Skip to content

Commit

Permalink
Merge pull request #19 from AssemblyAI/E07417BDFEA3614F5967B1520F8B2F61
Browse files Browse the repository at this point in the history
Release 3.1.0
  • Loading branch information
Swimburger authored Nov 16, 2023
2 parents 85a924c + b335fe6 commit 0aadce6
Show file tree
Hide file tree
Showing 9 changed files with 229 additions and 145 deletions.
18 changes: 15 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
[![AssemblyAI Twitter](https://img.shields.io/twitter/follow/AssemblyAI?label=%40AssemblyAI&style=social)](https://twitter.com/AssemblyAI)
[![AssemblyAI YouTube](https://img.shields.io/youtube/channel/subscribers/UCtatfZMf-8EkIwASXM4ts0A)](https://www.youtube.com/@AssemblyAI)
[![Discord](https://img.shields.io/discord/875120158014853141?logo=discord&label=Discord&link=https%3A%2F%2Fdiscord.com%2Fchannels%2F875120158014853141&style=social)
](https://discord.gg/5aQNZyq3)
](https://assemblyai.com/discord)

# AssemblyAI Node.js SDK

Expand Down Expand Up @@ -79,7 +79,7 @@ const transcript = await client.transcripts.create({
poll: true,
// How frequently the transcript is polled in ms. Defaults to 3000.
pollingInterval: 1000,
// How long to wait in ms until the "Polling timeout" error is thrown. Defaults to 180000.
// How long to wait in ms until the "Polling timeout" error is thrown. Defaults to infinite (-1).
pollingTimeout: 5000,
})
```
Expand All @@ -92,9 +92,21 @@ This will return the transcript object in its current state. If the transcript i
const transcript = await client.transcripts.get(transcript.id)
```

If you disabled polling during transcript creation, you can still poll until the transcript `status` is `completed` or `error` using `waitUntilReady`:

```javascript
const transcript = await client.transcripts.waitUntilReady(transcript.id,
{
// How frequently the transcript is polled in ms. Defaults to 3000.
pollingInterval: 1000,
// How long to wait in ms until the "Polling timeout" error is thrown. Defaults to infinite (-1).
pollingTimeout: 5000,
})
```

## List transcripts

This will return a page of transcripts that you have created.
This will return a page of transcripts you created.

```javascript
const page = await client.transcripts.list()
Expand Down
2 changes: 1 addition & 1 deletion src/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
export type * from "./types";
export * from "./types";
export * from "./services";
37 changes: 25 additions & 12 deletions src/services/transcripts/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import {
TranscriptListParameters,
WordSearchResponse,
BaseServiceParams,
PollingOptions,
} from "../..";
import { FileService } from "../files";

Expand Down Expand Up @@ -52,31 +53,31 @@ export class TranscriptService
});

if (options?.poll ?? true) {
return await this.poll(data.id, options);
return await this.waitUntilReady(data.id, options);
}

return data;
}

private async poll(
async waitUntilReady(
transcriptId: string,
options?: CreateTranscriptOptions
options?: PollingOptions
): Promise<Transcript> {
const pollingInterval = options?.pollingInterval ?? 3_000;
const pollingTimeout = options?.pollingTimeout ?? -1;
const startTime = Date.now();
// eslint-disable-next-line no-constant-condition
while (true) {
const transcript = await this.get(transcriptId);
if (transcript.status === "completed" || transcript.status === "error") {
return transcript;
} else if (
Date.now() - startTime <
(options?.pollingTimeout ?? 180_000)
pollingTimeout > 0 &&
Date.now() - startTime > pollingTimeout
) {
await new Promise((resolve) =>
setTimeout(resolve, options?.pollingInterval ?? 3_000)
);
} else {
throw new Error("Polling timeout");
} else {
await new Promise((resolve) => setTimeout(resolve, pollingInterval));
}
}
}
Expand Down Expand Up @@ -136,8 +137,9 @@ export class TranscriptService
* @return A promise that resolves to the sentences.
*/
wordSearch(id: string, words: string[]): Promise<WordSearchResponse> {
const params = new URLSearchParams({ words: words.join(",") });
return this.fetchJson<WordSearchResponse>(
`/v2/transcript/${id}/word-search?words=${JSON.stringify(words)}`
`/v2/transcript/${id}/word-search?${params.toString()}`
);
}

Expand Down Expand Up @@ -165,10 +167,21 @@ export class TranscriptService
* Retrieve subtitles of a transcript.
* @param id The identifier of the transcript.
* @param format The format of the subtitles.
* @param chars_per_caption The maximum number of characters per caption.
* @return A promise that resolves to the subtitles text.
*/
async subtitles(id: string, format: SubtitleFormat = "srt"): Promise<string> {
const response = await this.fetch(`/v2/transcript/${id}/${format}`);
async subtitles(
id: string,
format: SubtitleFormat = "srt",
chars_per_caption?: number
): Promise<string> {
let url = `/v2/transcript/${id}/${format}`;
if (chars_per_caption) {
const params = new URLSearchParams();
params.set("chars_per_caption", chars_per_caption.toString());
url += `?${params.toString()}`;
}
const response = await this.fetch(url);
return await response.text();
}

Expand Down
37 changes: 20 additions & 17 deletions src/types/asyncapi.generated.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,19 +14,19 @@ type OneOf<T extends any[]> = T extends [infer Only]
: never;

export type AudioData = {
/** @description Raw audio data, base64 encoded. This can be the raw data recorded directly from a microphone or read from an audio file. */
/** @description Base64 encoded raw audio data */
audio_data: string;
};

export type FinalTranscript = RealtimeBaseTranscript & {
/**
* @description Describes the type of message.
* @description Describes the type of message
* @constant
*/
message_type: "FinalTranscript";
/** @description Whether the text has been punctuated and cased. */
/** @description Whether the text is punctuated and cased */
punctuated: boolean;
/** @description Whether the text has been formatted (e.g. Dollar -> $) */
/** @description Whether the text is formatted, for example Dollar -> $ */
text_formatted: boolean;
};

Expand All @@ -39,32 +39,35 @@ export type MessageType =

export type PartialTranscript = RealtimeBaseTranscript & {
/**
* @description Describes the type of message.
* @description Describes the type of message
* @constant
*/
message_type: "PartialTranscript";
};

export type RealtimeBaseMessage = {
/** @description Describes the type of the message. */
/** @description Describes the type of the message */
message_type: MessageType;
};

export type RealtimeBaseTranscript = {
/** @description End time of audio sample relative to session start, in milliseconds. */
/** @description End time of audio sample relative to session start, in milliseconds */
audio_end: number;
/** @description Start time of audio sample relative to session start, in milliseconds. */
/** @description Start time of audio sample relative to session start, in milliseconds */
audio_start: number;
/**
* Format: double
* @description The confidence score of the entire transcription, between 0 and 1.
* @description The confidence score of the entire transcription, between 0 and 1
*/
confidence: number;
/** @description The timestamp for the partial transcript. */
/** @description The timestamp for the partial transcript */
created: Date;
/** @description The partial transcript for your audio. */
/** @description The partial transcript for your audio */
text: string;
/** @description An array of objects, with the information for each word in the transcription text. Includes the start/end time (in milliseconds) of the word, the confidence score of the word, and the text (i.e. the word itself). */
/**
* @description An array of objects, with the information for each word in the transcription text.
* Includes the start and end time of the word in milliseconds, the confidence score of the word, and the text, which is the word itself.
*/
words: Word[];
};

Expand All @@ -85,27 +88,27 @@ export type RealtimeTranscript = PartialTranscript | FinalTranscript;
export type RealtimeTranscriptType = "PartialTranscript" | "FinalTranscript";

export type SessionBegins = RealtimeBaseMessage & {
/** @description Timestamp when this session will expire. */
/** @description Timestamp when this session will expire */
expires_at: Date;
/**
* @description Describes the type of the message.
* @description Describes the type of the message
* @constant
*/
message_type: "SessionBegins";
/** @description Unique identifier for the established session. */
/** @description Unique identifier for the established session */
session_id: string;
};

export type SessionTerminated = RealtimeBaseMessage & {
/**
* @description Describes the type of the message.
* @description Describes the type of the message
* @constant
*/
message_type: "SessionTerminated";
};

export type TerminateSession = RealtimeBaseMessage & {
/** @description A boolean value to communicate that you wish to end your real-time session forever. */
/** @description Set to true to end your real-time session forever */
terminate_session: boolean;
};

Expand Down
12 changes: 6 additions & 6 deletions src/types/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
export type * from "./files";
export type * from "./transcripts";
export type * from "./realtime";
export type * from "./services";
export type * from "./asyncapi.generated";
export type * from "./openapi.generated";
export * from "./files";
export * from "./transcripts";
export * from "./realtime";
export * from "./services";
export * from "./asyncapi.generated";
export * from "./openapi.generated";
Loading

0 comments on commit 0aadce6

Please sign in to comment.