Skip to content

Commit

Permalink
Merge pull request #61 from AssemblyAI/E07417BDFEA3614F5967B1520F8B2F61
Browse files Browse the repository at this point in the history
Sync from internal repo (YYYY/MM/DD)
  • Loading branch information
Swimburger committed Jun 24, 2024
2 parents 19a807c + 4fb2e07 commit 12d6da9
Show file tree
Hide file tree
Showing 7 changed files with 224 additions and 154 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# Changelog

## [4.5.1]

- Add more TSDoc comments for `RealtimeService` documentation

## [4.5.0]

- You can now retrieve previous LeMUR responses using `client.lemur.getResponse<LemurTask>("YOUR_REQUEST_ID")`.
Expand Down
3 changes: 3 additions & 0 deletions samples/.prettierrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"semi": false
}
54 changes: 27 additions & 27 deletions samples/streaming-stt-from-mic/index.js
Original file line number Diff line number Diff line change
@@ -1,47 +1,47 @@
import "dotenv/config";
import { AssemblyAI } from "assemblyai";
import { SoxRecording } from "./sox.js";
const SAMPLE_RATE = 16000;
import "dotenv/config"
import { AssemblyAI } from "assemblyai"
import { SoxRecording } from "./sox.js"
const SAMPLE_RATE = 16000
const client = new AssemblyAI({
apiKey: process.env.ASSEMBLYAI_API_KEY,
});
})
const transcriber = client.realtime.transcriber({
sampleRate: SAMPLE_RATE,
});
})
transcriber.on("open", ({ sessionId }) => {
console.log(`Session opened with ID: ${sessionId}`);
});
console.log(`Session opened with ID: ${sessionId}`)
})
transcriber.on("error", (error) => {
console.error("Error:", error);
});
console.error("Error:", error)
})
transcriber.on("close", (code, reason) =>
console.log("Session closed:", code, reason),
);
)
transcriber.on("transcript", (transcript) => {
if (!transcript.text) {
return;
return
}
if (transcript.message_type === "PartialTranscript") {
console.log("Partial:", transcript.text);
console.log("Partial:", transcript.text)
} else {
console.log("Final:", transcript.text);
console.log("Final:", transcript.text)
}
});
console.log("Connecting to real-time transcript service");
await transcriber.connect();
console.log("Starting recording");
})
console.log("Connecting to real-time transcript service")
await transcriber.connect()
console.log("Starting recording")
const recording = new SoxRecording({
channels: 1,
sampleRate: SAMPLE_RATE,
audioType: "wav", // Linear PCM
});
recording.stream().pipeTo(transcriber.stream());
})
recording.stream().pipeTo(transcriber.stream())
// Stop recording and close connection using Ctrl-C.
process.on("SIGINT", async function () {
console.log();
console.log("Stopping recording");
recording.stop();
console.log("Closing real-time transcript connection");
await transcriber.close();
process.exit();
});
console.log()
console.log("Stopping recording")
recording.stop()
console.log("Closing real-time transcript connection")
await transcriber.close()
process.exit()
})
54 changes: 27 additions & 27 deletions samples/streaming-stt-from-mic/index.ts
Original file line number Diff line number Diff line change
@@ -1,61 +1,61 @@
import "dotenv/config";
import { AssemblyAI, RealtimeTranscript } from "assemblyai";
import { SoxRecording } from "./sox.js";
import "dotenv/config"
import { AssemblyAI, RealtimeTranscript } from "assemblyai"
import { SoxRecording } from "./sox.js"

const SAMPLE_RATE = 16_000;
const SAMPLE_RATE = 16_000

const client = new AssemblyAI({
apiKey: process.env.ASSEMBLYAI_API_KEY!,
});
})

const transcriber = client.realtime.transcriber({
sampleRate: SAMPLE_RATE,
});
})

transcriber.on("open", ({ sessionId }) => {
console.log(`Session opened with ID: ${sessionId}`);
});
console.log(`Session opened with ID: ${sessionId}`)
})

transcriber.on("error", (error: Error) => {
console.error("Error:", error);
});
console.error("Error:", error)
})

transcriber.on("close", (code: number, reason: string) =>
console.log("Session closed:", code, reason),
);
)

transcriber.on("transcript", (transcript: RealtimeTranscript) => {
if (!transcript.text) {
return;
return
}

if (transcript.message_type === "PartialTranscript") {
console.log("Partial:", transcript.text);
console.log("Partial:", transcript.text)
} else {
console.log("Final:", transcript.text);
console.log("Final:", transcript.text)
}
});
})

console.log("Connecting to real-time transcript service");
await transcriber.connect();
console.log("Connecting to real-time transcript service")
await transcriber.connect()

console.log("Starting recording");
console.log("Starting recording")
const recording = new SoxRecording({
channels: 1,
sampleRate: SAMPLE_RATE,
audioType: "wav", // Linear PCM
});
})

recording.stream().pipeTo(transcriber.stream());
recording.stream().pipeTo(transcriber.stream())

// Stop recording and close connection using Ctrl-C.
process.on("SIGINT", async function () {
console.log();
console.log("Stopping recording");
recording.stop();
console.log()
console.log("Stopping recording")
recording.stop()

console.log("Closing real-time transcript connection");
await transcriber.close();
console.log("Closing real-time transcript connection")
await transcriber.close()

process.exit();
});
process.exit()
})
89 changes: 44 additions & 45 deletions samples/streaming-stt-from-mic/sox.js
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
// This code is a simplified and typed version adapted from the 'node-record-lpcm16' project by Gilles De Mey.
// Original source code: https://github.com/gillesdemey/node-record-lpcm16
import { ok as assert } from "assert";
import { spawn } from "child_process";
import { Readable } from "stream";
import { ok as assert } from "assert"
import { spawn } from "child_process"
import { Readable } from "stream"
const debug =
!!process.env.DEBUG && process.env.DEBUG.indexOf("record") !== -1
? console.debug
: () => {};
: () => {}
export class SoxRecording {
options;
process;
soxStream;
options
process
soxStream
constructor(options = {}) {
const defaults = {
sampleRate: 16000,
Expand All @@ -21,14 +21,14 @@ export class SoxRecording {
recorder: "sox",
endOnSilence: false,
audioType: "wav",
};
this.options = Object.assign(defaults, options);
debug("Started recording");
debug(this.options);
return this.start();
}
this.options = Object.assign(defaults, options)
debug("Started recording")
debug(this.options)
return this.start()
}
start() {
const cmd = "sox";
const cmd = "sox"
const args = [
"--default-device",
"--no-show-progress",
Expand All @@ -43,58 +43,57 @@ export class SoxRecording {
"--type",
this.options.audioType,
"-", // pipe
];
debug(` ${cmd} ${args.join(" ")}`);
]
debug(` ${cmd} ${args.join(" ")}`)
const cp = spawn(cmd, args, {
encoding: "binary",
stdio: "pipe",
});
const rec = cp.stdout;
const err = cp.stderr;
this.process = cp; // expose child process
this.soxStream = cp.stdout; // expose output stream
})
const rec = cp.stdout
const err = cp.stderr
this.process = cp // expose child process
this.soxStream = cp.stdout // expose output stream
cp.on("close", (code) => {
if (code === 0) return;
if (code === 0) return
rec?.emit(
"error",
`${cmd} has exited with error code ${code}.
Enable debugging with the environment variable debug=record.`,
);
});
)
})
err?.on("data", (chunk) => {
debug(`STDERR: ${chunk}`);
});
debug(`STDERR: ${chunk}`)
})
rec?.on("data", (chunk) => {
debug(`Recording ${chunk.length} bytes`);
});
debug(`Recording ${chunk.length} bytes`)
})
rec?.on("end", () => {
debug("Recording ended");
});
return this;
debug("Recording ended")
})
return this
}
stop() {
assert(this.process, "Recording not yet started");
this.process.kill();
assert(this.process, "Recording not yet started")
this.process.kill()
}
pause() {
assert(this.process, "Recording not yet started");
this.process.kill("SIGSTOP");
this.soxStream?.pause();
debug("Paused recording");
assert(this.process, "Recording not yet started")
this.process.kill("SIGSTOP")
this.soxStream?.pause()
debug("Paused recording")
}
resume() {
assert(this.process, "Recording not yet started");
this.process.kill("SIGCONT");
this.soxStream?.resume();
debug("Resumed recording");
assert(this.process, "Recording not yet started")
this.process.kill("SIGCONT")
this.soxStream?.resume()
debug("Resumed recording")
}
isPaused() {
assert(this.process, "Recording not yet started");
return this.soxStream?.isPaused();
assert(this.process, "Recording not yet started")
return this.soxStream?.isPaused()
}
stream() {
assert(this?.soxStream, "Recording not yet started");
return Readable.toWeb(this?.soxStream);
assert(this?.soxStream, "Recording not yet started")
return Readable.toWeb(this?.soxStream)
}
}
Loading

0 comments on commit 12d6da9

Please sign in to comment.