@speech-sdk/core 0.6.2 → 0.8.0-alpha
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +202 -21
- package/README.md +267 -264
- package/dist/__tests__/e2e/_save-audio.d.ts +5 -24
- package/dist/__tests__/e2e/_save-audio.d.ts.map +1 -1
- package/dist/__tests__/e2e/_save-audio.js +19 -42
- package/dist/__tests__/e2e/_save-audio.js.map +1 -1
- package/dist/audio-duration.d.ts +0 -5
- package/dist/audio-duration.d.ts.map +1 -1
- package/dist/audio-duration.js +3 -10
- package/dist/audio-duration.js.map +1 -1
- package/dist/audio-utils.d.ts +1 -9
- package/dist/audio-utils.d.ts.map +1 -1
- package/dist/audio-utils.js +10 -13
- package/dist/audio-utils.js.map +1 -1
- package/dist/captions.d.ts +29 -0
- package/dist/captions.d.ts.map +1 -0
- package/dist/captions.js +193 -0
- package/dist/captions.js.map +1 -0
- package/dist/conversation/attribute-timestamps.d.ts +26 -0
- package/dist/conversation/attribute-timestamps.d.ts.map +1 -0
- package/dist/conversation/attribute-timestamps.js +276 -0
- package/dist/conversation/attribute-timestamps.js.map +1 -0
- package/dist/conversation/dispatch.d.ts +5 -5
- package/dist/conversation/dispatch.d.ts.map +1 -1
- package/dist/conversation/dispatch.js +18 -8
- package/dist/conversation/dispatch.js.map +1 -1
- package/dist/conversation/errors.d.ts +3 -0
- package/dist/conversation/errors.d.ts.map +1 -1
- package/dist/conversation/errors.js +6 -0
- package/dist/conversation/errors.js.map +1 -1
- package/dist/conversation/pcm-concat.d.ts +0 -23
- package/dist/conversation/pcm-concat.d.ts.map +1 -1
- package/dist/conversation/pcm-concat.js +5 -43
- package/dist/conversation/pcm-concat.js.map +1 -1
- package/dist/conversation/proportional-fill.d.ts +10 -0
- package/dist/conversation/proportional-fill.d.ts.map +1 -0
- package/dist/conversation/proportional-fill.js +64 -0
- package/dist/conversation/proportional-fill.js.map +1 -0
- package/dist/conversation/silence-detection.d.ts +14 -0
- package/dist/conversation/silence-detection.d.ts.map +1 -0
- package/dist/conversation/silence-detection.js +52 -0
- package/dist/conversation/silence-detection.js.map +1 -0
- package/dist/conversation/stitch.d.ts +3 -1
- package/dist/conversation/stitch.d.ts.map +1 -1
- package/dist/conversation/stitch.js +54 -13
- package/dist/conversation/stitch.js.map +1 -1
- package/dist/conversation/types.d.ts +1 -19
- package/dist/conversation/types.d.ts.map +1 -1
- package/dist/conversation/validate.d.ts +1 -16
- package/dist/conversation/validate.d.ts.map +1 -1
- package/dist/conversation/validate.js +29 -29
- package/dist/conversation/validate.js.map +1 -1
- package/dist/default-stt-fallback.d.ts +3 -0
- package/dist/default-stt-fallback.d.ts.map +1 -0
- package/dist/default-stt-fallback.js +11 -0
- package/dist/default-stt-fallback.js.map +1 -0
- package/dist/derive-timestamps.d.ts +10 -0
- package/dist/derive-timestamps.d.ts.map +1 -0
- package/dist/derive-timestamps.js +24 -0
- package/dist/derive-timestamps.js.map +1 -0
- package/dist/errors.d.ts +20 -2
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js +28 -2
- package/dist/errors.js.map +1 -1
- package/dist/generate-conversation.d.ts +5 -4
- package/dist/generate-conversation.d.ts.map +1 -1
- package/dist/generate-conversation.js +191 -38
- package/dist/generate-conversation.js.map +1 -1
- package/dist/generate-speech.d.ts +2 -10
- package/dist/generate-speech.d.ts.map +1 -1
- package/dist/generate-speech.js +111 -33
- package/dist/generate-speech.js.map +1 -1
- package/dist/index.d.ts +5 -8
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +6 -4
- package/dist/index.js.map +1 -1
- package/dist/logger.d.ts +2 -0
- package/dist/logger.d.ts.map +1 -0
- package/dist/logger.js +29 -0
- package/dist/logger.js.map +1 -0
- package/dist/metadata.d.ts +0 -22
- package/dist/metadata.d.ts.map +1 -1
- package/dist/provider-utils.d.ts +3 -1
- package/dist/provider-utils.d.ts.map +1 -1
- package/dist/provider-utils.js +36 -39
- package/dist/provider-utils.js.map +1 -1
- package/dist/providers/cartesia/alignment.d.ts +8 -0
- package/dist/providers/cartesia/alignment.d.ts.map +1 -0
- package/dist/providers/cartesia/alignment.js +18 -0
- package/dist/providers/cartesia/alignment.js.map +1 -0
- package/dist/providers/cartesia/index.d.ts +11 -13
- package/dist/providers/cartesia/index.d.ts.map +1 -1
- package/dist/providers/cartesia/index.js +184 -61
- package/dist/providers/cartesia/index.js.map +1 -1
- package/dist/providers/deepgram/index.d.ts +7 -8
- package/dist/providers/deepgram/index.d.ts.map +1 -1
- package/dist/providers/deepgram/index.js +17 -18
- package/dist/providers/deepgram/index.js.map +1 -1
- package/dist/providers/elevenlabs/alignment.d.ts +10 -0
- package/dist/providers/elevenlabs/alignment.d.ts.map +1 -0
- package/dist/providers/elevenlabs/alignment.js +47 -0
- package/dist/providers/elevenlabs/alignment.js.map +1 -0
- package/dist/providers/elevenlabs/index.d.ts +10 -26
- package/dist/providers/elevenlabs/index.d.ts.map +1 -1
- package/dist/providers/elevenlabs/index.js +216 -154
- package/dist/providers/elevenlabs/index.js.map +1 -1
- package/dist/providers/fal/index.d.ts +7 -43
- package/dist/providers/fal/index.d.ts.map +1 -1
- package/dist/providers/fal/index.js +37 -86
- package/dist/providers/fal/index.js.map +1 -1
- package/dist/providers/fish-audio/index.d.ts +7 -8
- package/dist/providers/fish-audio/index.d.ts.map +1 -1
- package/dist/providers/fish-audio/index.js +23 -19
- package/dist/providers/fish-audio/index.js.map +1 -1
- package/dist/providers/gateway/index.d.ts +68 -0
- package/dist/providers/gateway/index.d.ts.map +1 -0
- package/dist/providers/gateway/index.js +236 -0
- package/dist/providers/gateway/index.js.map +1 -0
- package/dist/providers/google/index.d.ts +7 -20
- package/dist/providers/google/index.d.ts.map +1 -1
- package/dist/providers/google/index.js +161 -151
- package/dist/providers/google/index.js.map +1 -1
- package/dist/providers/hume/alignment.d.ts +33 -0
- package/dist/providers/hume/alignment.d.ts.map +1 -0
- package/dist/providers/hume/alignment.js +37 -0
- package/dist/providers/hume/alignment.js.map +1 -0
- package/dist/providers/hume/index.d.ts +11 -13
- package/dist/providers/hume/index.d.ts.map +1 -1
- package/dist/providers/hume/index.js +105 -41
- package/dist/providers/hume/index.js.map +1 -1
- package/dist/providers/inworld/alignment.d.ts +11 -0
- package/dist/providers/inworld/alignment.d.ts.map +1 -0
- package/dist/providers/inworld/alignment.js +24 -0
- package/dist/providers/inworld/alignment.js.map +1 -0
- package/dist/providers/inworld/index.d.ts +10 -14
- package/dist/providers/inworld/index.d.ts.map +1 -1
- package/dist/providers/inworld/index.js +55 -38
- package/dist/providers/inworld/index.js.map +1 -1
- package/dist/providers/mistral/index.d.ts +7 -8
- package/dist/providers/mistral/index.d.ts.map +1 -1
- package/dist/providers/mistral/index.js +39 -38
- package/dist/providers/mistral/index.js.map +1 -1
- package/dist/providers/murf/alignment.d.ts +13 -0
- package/dist/providers/murf/alignment.d.ts.map +1 -0
- package/dist/providers/murf/alignment.js +22 -0
- package/dist/providers/murf/alignment.js.map +1 -0
- package/dist/providers/murf/index.d.ts +11 -13
- package/dist/providers/murf/index.d.ts.map +1 -1
- package/dist/providers/murf/index.js +73 -56
- package/dist/providers/murf/index.js.map +1 -1
- package/dist/providers/openai/index.d.ts +36 -20
- package/dist/providers/openai/index.d.ts.map +1 -1
- package/dist/providers/openai/index.js +270 -102
- package/dist/providers/openai/index.js.map +1 -1
- package/dist/providers/resemble/alignment.d.ts +11 -0
- package/dist/providers/resemble/alignment.d.ts.map +1 -0
- package/dist/providers/resemble/alignment.js +54 -0
- package/dist/providers/resemble/alignment.js.map +1 -0
- package/dist/providers/resemble/index.d.ts +10 -8
- package/dist/providers/resemble/index.d.ts.map +1 -1
- package/dist/providers/resemble/index.js +58 -40
- package/dist/providers/resemble/index.js.map +1 -1
- package/dist/providers/xai/index.d.ts +7 -9
- package/dist/providers/xai/index.d.ts.map +1 -1
- package/dist/providers/xai/index.js +37 -40
- package/dist/providers/xai/index.js.map +1 -1
- package/dist/providers.d.ts +29 -0
- package/dist/providers.d.ts.map +1 -0
- package/dist/providers.js +15 -0
- package/dist/providers.js.map +1 -0
- package/dist/resolve-provider.d.ts.map +1 -1
- package/dist/resolve-provider.js +7 -59
- package/dist/resolve-provider.js.map +1 -1
- package/dist/speech-provider.d.ts +19 -15
- package/dist/speech-provider.d.ts.map +1 -1
- package/dist/speech-provider.js +9 -14
- package/dist/speech-provider.js.map +1 -1
- package/dist/speech-result.d.ts +5 -0
- package/dist/speech-result.d.ts.map +1 -1
- package/dist/speech-result.js.map +1 -1
- package/dist/speech-to-text-provider.d.ts +28 -0
- package/dist/speech-to-text-provider.d.ts.map +1 -0
- package/dist/speech-to-text-provider.js +2 -0
- package/dist/speech-to-text-provider.js.map +1 -0
- package/dist/stream-speech.d.ts.map +1 -1
- package/dist/stream-speech.js +2 -3
- package/dist/stream-speech.js.map +1 -1
- package/dist/timestamps.d.ts +9 -0
- package/dist/timestamps.d.ts.map +1 -0
- package/dist/timestamps.js +2 -0
- package/dist/timestamps.js.map +1 -0
- package/dist/turns.d.ts +9 -0
- package/dist/turns.d.ts.map +1 -0
- package/dist/turns.js +21 -0
- package/dist/turns.js.map +1 -0
- package/dist/types.d.ts +25 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/volume-adjust.d.ts +0 -6
- package/dist/volume-adjust.d.ts.map +1 -1
- package/dist/volume-adjust.js +0 -6
- package/dist/volume-adjust.js.map +1 -1
- package/package.json +12 -63
|
@@ -1,35 +1,16 @@
|
|
|
1
1
|
import { generateConversation as _generateConversation } from "../../generate-conversation.js";
|
|
2
2
|
import { generateSpeech as _generateSpeech } from "../../generate-speech.js";
|
|
3
|
-
|
|
4
|
-
* Write a test-generated audio file to `SPEECH_SDK_E2E_OUTPUT_DIR` if the env
|
|
5
|
-
* var is set. No-op otherwise, so normal CI runs don't produce artifacts.
|
|
6
|
-
* Usually you don't need to call this directly — use the `generateSpeech`,
|
|
7
|
-
* `generateConversation`, and `collectStreamAndSave` helpers exported from
|
|
8
|
-
* this module, which autosave using the current test name.
|
|
9
|
-
*
|
|
10
|
-
* Output layout: `$SPEECH_SDK_E2E_OUTPUT_DIR/<provider-file>/<test-slug>.<ext>`.
|
|
11
|
-
* If the same test saves multiple times, subsequent files are suffixed `-2`,
|
|
12
|
-
* `-3`, etc.
|
|
13
|
-
*/
|
|
3
|
+
import type { WordTimestamp } from "../../timestamps.js";
|
|
14
4
|
export declare function maybeSaveAudio(name: string, audio: {
|
|
15
5
|
uint8Array: Uint8Array;
|
|
16
6
|
mediaType: string;
|
|
17
7
|
}): Promise<void>;
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
8
|
+
export declare function maybeSaveResult(name: string, audio: {
|
|
9
|
+
uint8Array: Uint8Array;
|
|
10
|
+
mediaType: string;
|
|
11
|
+
}, timestamps?: readonly WordTimestamp[]): Promise<void>;
|
|
22
12
|
export declare const generateSpeech: typeof _generateSpeech;
|
|
23
|
-
/**
|
|
24
|
-
* Drop-in replacement for `generateConversation` that autosaves to
|
|
25
|
-
* `SPEECH_SDK_E2E_OUTPUT_DIR` using the current vitest test name.
|
|
26
|
-
*/
|
|
27
13
|
export declare const generateConversation: typeof _generateConversation;
|
|
28
|
-
/**
|
|
29
|
-
* Collects a streamed `streamSpeech` result into bytes AND autosaves them to
|
|
30
|
-
* `SPEECH_SDK_E2E_OUTPUT_DIR` using the current vitest test name. Use in place
|
|
31
|
-
* of `collectStream(result.audio)` in e2e tests.
|
|
32
|
-
*/
|
|
33
14
|
export declare function collectStreamAndSave(result: {
|
|
34
15
|
audio: ReadableStream<Uint8Array>;
|
|
35
16
|
mediaType: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"_save-audio.d.ts","sourceRoot":"","sources":["../../../src/__tests__/e2e/_save-audio.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"_save-audio.d.ts","sourceRoot":"","sources":["../../../src/__tests__/e2e/_save-audio.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,oBAAoB,IAAI,qBAAqB,EAAE,MAAM,gCAAgC,CAAC;AAC/F,OAAO,EAAE,cAAc,IAAI,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAC7E,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AA6EzD,wBAAsB,cAAc,CAClC,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE;IAAE,UAAU,EAAE,UAAU,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,GACnD,OAAO,CAAC,IAAI,CAAC,CAEf;AAED,wBAAsB,eAAe,CACnC,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE;IAAE,UAAU,EAAE,UAAU,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,EACpD,UAAU,CAAC,EAAE,SAAS,aAAa,EAAE,GACpC,OAAO,CAAC,IAAI,CAAC,CA8Bf;AAOD,eAAO,MAAM,cAAc,EAAE,OAAO,eAMR,CAAC;AAE7B,eAAO,MAAM,oBAAoB,EAAE,OAAO,qBAMR,CAAC;AAEnC,wBAAsB,oBAAoB,CAAC,MAAM,EAAE;IACjD,KAAK,EAAE,cAAc,CAAC,UAAU,CAAC,CAAC;IAClC,SAAS,EAAE,MAAM,CAAC;CACnB,GAAG,OAAO,CAAC,UAAU,CAAC,CAOtB"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { mkdir, writeFile } from "node:fs/promises";
|
|
2
2
|
import { basename, join } from "node:path";
|
|
3
3
|
import { expect } from "vitest";
|
|
4
|
+
import { timestampsToCaptions } from "../../captions.js";
|
|
4
5
|
import { generateConversation as _generateConversation } from "../../generate-conversation.js";
|
|
5
6
|
import { generateSpeech as _generateSpeech } from "../../generate-speech.js";
|
|
6
7
|
import { collectStream } from "./_collect-stream.js";
|
|
@@ -48,12 +49,6 @@ function currentTestContext() {
|
|
|
48
49
|
testPath: state.testPath,
|
|
49
50
|
};
|
|
50
51
|
}
|
|
51
|
-
/**
|
|
52
|
-
* Derives the subdirectory for a given test file. e2e tests are named like
|
|
53
|
-
* `openai.e2e.test.ts` / `conversation-google.e2e.test.ts`; we strip the
|
|
54
|
-
* `.e2e.test.ts` suffix and use that as the per-provider bucket so a full run
|
|
55
|
-
* doesn't dump 100+ files into a single flat directory.
|
|
56
|
-
*/
|
|
57
52
|
function providerBucket(testPath) {
|
|
58
53
|
if (!testPath) {
|
|
59
54
|
return "unknown";
|
|
@@ -61,29 +56,21 @@ function providerBucket(testPath) {
|
|
|
61
56
|
const base = basename(testPath).replace(E2E_TEST_SUFFIX, "");
|
|
62
57
|
return slugify(base) || "unknown";
|
|
63
58
|
}
|
|
64
|
-
// Counter keyed by `${bucket}/${slug}` so multiple generate/stream calls
|
|
65
|
-
// within a single test don't overwrite each other. Vitest isolates modules
|
|
66
|
-
// per file, so this resets per test file — collisions are only meaningful
|
|
67
|
-
// within the same `it`.
|
|
68
59
|
const callCounts = new Map();
|
|
69
|
-
function
|
|
60
|
+
function nextStem(bucket, slug) {
|
|
70
61
|
const key = `${bucket}/${slug}`;
|
|
71
62
|
const n = (callCounts.get(key) ?? 0) + 1;
|
|
72
63
|
callCounts.set(key, n);
|
|
73
|
-
return n === 1 ?
|
|
64
|
+
return n === 1 ? slug : `${slug}-${n}`;
|
|
65
|
+
}
|
|
66
|
+
async function writeAndLog(file, data) {
|
|
67
|
+
await writeFile(file, data);
|
|
68
|
+
console.log(`[e2e-save] wrote ${file}`);
|
|
74
69
|
}
|
|
75
|
-
/**
|
|
76
|
-
* Write a test-generated audio file to `SPEECH_SDK_E2E_OUTPUT_DIR` if the env
|
|
77
|
-
* var is set. No-op otherwise, so normal CI runs don't produce artifacts.
|
|
78
|
-
* Usually you don't need to call this directly — use the `generateSpeech`,
|
|
79
|
-
* `generateConversation`, and `collectStreamAndSave` helpers exported from
|
|
80
|
-
* this module, which autosave using the current test name.
|
|
81
|
-
*
|
|
82
|
-
* Output layout: `$SPEECH_SDK_E2E_OUTPUT_DIR/<provider-file>/<test-slug>.<ext>`.
|
|
83
|
-
* If the same test saves multiple times, subsequent files are suffixed `-2`,
|
|
84
|
-
* `-3`, etc.
|
|
85
|
-
*/
|
|
86
70
|
export async function maybeSaveAudio(name, audio) {
|
|
71
|
+
await maybeSaveResult(name, audio);
|
|
72
|
+
}
|
|
73
|
+
export async function maybeSaveResult(name, audio, timestamps) {
|
|
87
74
|
const dir = resolveOutputDir();
|
|
88
75
|
if (!dir) {
|
|
89
76
|
return;
|
|
@@ -92,38 +79,28 @@ export async function maybeSaveAudio(name, audio) {
|
|
|
92
79
|
const bucket = providerBucket(testPath);
|
|
93
80
|
const bucketDir = join(dir, bucket);
|
|
94
81
|
await mkdir(bucketDir, { recursive: true });
|
|
95
|
-
const
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
82
|
+
const stem = nextStem(bucket, slugify(name));
|
|
83
|
+
await writeAndLog(join(bucketDir, `${stem}.${extFor(audio.mediaType)}`), audio.uint8Array);
|
|
84
|
+
if (timestamps && timestamps.length > 0) {
|
|
85
|
+
await writeAndLog(join(bucketDir, `${stem}.timestamps.json`), `${JSON.stringify(timestamps, null, 2)}\n`);
|
|
86
|
+
await writeAndLog(join(bucketDir, `${stem}.srt`), timestampsToCaptions(timestamps));
|
|
87
|
+
await writeAndLog(join(bucketDir, `${stem}.vtt`), timestampsToCaptions(timestamps, { format: "vtt" }));
|
|
88
|
+
}
|
|
99
89
|
}
|
|
100
90
|
function currentTestSlug() {
|
|
101
91
|
const { currentTestName } = currentTestContext();
|
|
102
92
|
return slugify(currentTestName ?? "unnamed") || "unnamed";
|
|
103
93
|
}
|
|
104
|
-
/**
|
|
105
|
-
* Drop-in replacement for `generateSpeech` that autosaves to
|
|
106
|
-
* `SPEECH_SDK_E2E_OUTPUT_DIR` using the current vitest test name.
|
|
107
|
-
*/
|
|
108
94
|
export const generateSpeech = (async (options) => {
|
|
109
95
|
const result = await _generateSpeech(options);
|
|
110
|
-
await
|
|
96
|
+
await maybeSaveResult(currentTestSlug(), result.audio, result.timestamps);
|
|
111
97
|
return result;
|
|
112
98
|
});
|
|
113
|
-
/**
|
|
114
|
-
* Drop-in replacement for `generateConversation` that autosaves to
|
|
115
|
-
* `SPEECH_SDK_E2E_OUTPUT_DIR` using the current vitest test name.
|
|
116
|
-
*/
|
|
117
99
|
export const generateConversation = (async (options) => {
|
|
118
100
|
const result = await _generateConversation(options);
|
|
119
|
-
await
|
|
101
|
+
await maybeSaveResult(currentTestSlug(), result.audio, result.timestamps);
|
|
120
102
|
return result;
|
|
121
103
|
});
|
|
122
|
-
/**
|
|
123
|
-
* Collects a streamed `streamSpeech` result into bytes AND autosaves them to
|
|
124
|
-
* `SPEECH_SDK_E2E_OUTPUT_DIR` using the current vitest test name. Use in place
|
|
125
|
-
* of `collectStream(result.audio)` in e2e tests.
|
|
126
|
-
*/
|
|
127
104
|
export async function collectStreamAndSave(result) {
|
|
128
105
|
const bytes = await collectStream(result.audio);
|
|
129
106
|
await maybeSaveAudio(currentTestSlug(), {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"_save-audio.js","sourceRoot":"","sources":["../../../src/__tests__/e2e/_save-audio.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AACpD,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAC3C,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAChC,OAAO,EAAE,oBAAoB,IAAI,qBAAqB,EAAE,MAAM,gCAAgC,CAAC;AAC/F,OAAO,EAAE,cAAc,IAAI,eAAe,EAAE,MAAM,0BAA0B,CAAC;
|
|
1
|
+
{"version":3,"file":"_save-audio.js","sourceRoot":"","sources":["../../../src/__tests__/e2e/_save-audio.ts"],"names":[],"mappings":"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"}
|
package/dist/audio-duration.d.ts
CHANGED
|
@@ -1,7 +1,2 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Compute audio duration in milliseconds from raw audio bytes.
|
|
3
|
-
* Uses mediabunny to parse the audio container (MP3, WAV, Ogg, FLAC, etc.)
|
|
4
|
-
* and extract duration. Returns undefined if parsing fails.
|
|
5
|
-
*/
|
|
6
1
|
export declare function computeAudioDuration(data: Uint8Array | string, mediaType: string): Promise<number | undefined>;
|
|
7
2
|
//# sourceMappingURL=audio-duration.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"audio-duration.d.ts","sourceRoot":"","sources":["../src/audio-duration.ts"],"names":[],"mappings":"AAEA
|
|
1
|
+
{"version":3,"file":"audio-duration.d.ts","sourceRoot":"","sources":["../src/audio-duration.ts"],"names":[],"mappings":"AAEA,wBAAsB,oBAAoB,CACxC,IAAI,EAAE,UAAU,GAAG,MAAM,EACzB,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAoB7B"}
|
package/dist/audio-duration.js
CHANGED
|
@@ -1,15 +1,8 @@
|
|
|
1
1
|
import { ALL_FORMATS, BlobSource, Input } from "mediabunny";
|
|
2
|
-
/**
|
|
3
|
-
* Compute audio duration in milliseconds from raw audio bytes.
|
|
4
|
-
* Uses mediabunny to parse the audio container (MP3, WAV, Ogg, FLAC, etc.)
|
|
5
|
-
* and extract duration. Returns undefined if parsing fails.
|
|
6
|
-
*/
|
|
7
2
|
export async function computeAudioDuration(data, mediaType) {
|
|
8
3
|
try {
|
|
9
4
|
const bytes = data instanceof Uint8Array ? data : base64ToUint8Array(data);
|
|
10
|
-
// Copy to a fresh ArrayBuffer
|
|
11
|
-
// bytes — not the entire underlying buffer (which may be larger when
|
|
12
|
-
// bytes is a subarray) and satisfies Blob's BlobPart type.
|
|
5
|
+
// Copy to a fresh ArrayBuffer — bytes may be a subarray of a larger buffer.
|
|
13
6
|
const ab = new ArrayBuffer(bytes.byteLength);
|
|
14
7
|
new Uint8Array(ab).set(bytes);
|
|
15
8
|
const blob = new Blob([ab], { type: mediaType });
|
|
@@ -19,13 +12,13 @@ export async function computeAudioDuration(data, mediaType) {
|
|
|
19
12
|
});
|
|
20
13
|
const track = await input.getPrimaryAudioTrack();
|
|
21
14
|
if (!track) {
|
|
22
|
-
return
|
|
15
|
+
return;
|
|
23
16
|
}
|
|
24
17
|
const durationSeconds = await track.computeDuration();
|
|
25
18
|
return Math.round(durationSeconds * 1000);
|
|
26
19
|
}
|
|
27
20
|
catch {
|
|
28
|
-
return
|
|
21
|
+
return;
|
|
29
22
|
}
|
|
30
23
|
}
|
|
31
24
|
function base64ToUint8Array(b64) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"audio-duration.js","sourceRoot":"","sources":["../src/audio-duration.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAE5D
|
|
1
|
+
{"version":3,"file":"audio-duration.js","sourceRoot":"","sources":["../src/audio-duration.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAE5D,MAAM,CAAC,KAAK,UAAU,oBAAoB,CACxC,IAAyB,EACzB,SAAiB;IAEjB,IAAI,CAAC;QACH,MAAM,KAAK,GAAG,IAAI,YAAY,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,kBAAkB,CAAC,IAAI,CAAC,CAAC;QAC3E,4EAA4E;QAC5E,MAAM,EAAE,GAAG,IAAI,WAAW,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;QAC7C,IAAI,UAAU,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QAC9B,MAAM,IAAI,GAAG,IAAI,IAAI,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC,CAAC;QACjD,MAAM,KAAK,GAAG,IAAI,KAAK,CAAC;YACtB,MAAM,EAAE,IAAI,UAAU,CAAC,IAAI,CAAC;YAC5B,OAAO,EAAE,WAAW;SACrB,CAAC,CAAC;QACH,MAAM,KAAK,GAAG,MAAM,KAAK,CAAC,oBAAoB,EAAE,CAAC;QACjD,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,OAAO;QACT,CAAC;QACD,MAAM,eAAe,GAAG,MAAM,KAAK,CAAC,eAAe,EAAE,CAAC;QACtD,OAAO,IAAI,CAAC,KAAK,CAAC,eAAe,GAAG,IAAI,CAAC,CAAC;IAC5C,CAAC;IAAC,MAAM,CAAC;QACP,OAAO;IACT,CAAC;AACH,CAAC;AAED,SAAS,kBAAkB,CAAC,GAAW;IACrC,MAAM,YAAY,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC;IAC/B,MAAM,KAAK,GAAG,IAAI,UAAU,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC;IAClD,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,YAAY,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QAC7C,KAAK,CAAC,CAAC,CAAC,GAAG,YAAY,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;IACxC,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC"}
|
package/dist/audio-utils.d.ts
CHANGED
|
@@ -1,12 +1,4 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Parse a numeric parameter from a mediaType string (e.g. "audio/pcm;rate=24000").
|
|
3
|
-
* Returns undefined if missing or non-positive.
|
|
4
|
-
*/
|
|
5
1
|
export declare function parseMediaTypeParam(mediaType: string, name: string): number | undefined;
|
|
6
|
-
/**
|
|
7
|
-
* Wrap raw 16-bit little-endian mono PCM bytes in a WAV container.
|
|
8
|
-
* Cross-platform (browser, Node, edge) via mediabunny's container ops —
|
|
9
|
-
* does not require the WebCodecs encoder.
|
|
10
|
-
*/
|
|
11
2
|
export declare function wrapPcm16Mono(pcm: Uint8Array, sampleRate: number): Promise<Uint8Array>;
|
|
3
|
+
export declare function base64ToUint8Array(b64: string): Uint8Array;
|
|
12
4
|
//# sourceMappingURL=audio-utils.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"audio-utils.d.ts","sourceRoot":"","sources":["../src/audio-utils.ts"],"names":[],"mappings":"AAUA
|
|
1
|
+
{"version":3,"file":"audio-utils.d.ts","sourceRoot":"","sources":["../src/audio-utils.ts"],"names":[],"mappings":"AAUA,wBAAgB,mBAAmB,CACjC,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,MAAM,GACX,MAAM,GAAG,SAAS,CAapB;AAED,wBAAsB,aAAa,CACjC,GAAG,EAAE,UAAU,EACf,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,UAAU,CAAC,CA0BrB;AAED,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,GAAG,UAAU,CAO1D"}
|
package/dist/audio-utils.js
CHANGED
|
@@ -1,29 +1,19 @@
|
|
|
1
1
|
import { BufferTarget, EncodedAudioPacketSource, EncodedPacket, Output, WavOutputFormat, } from "mediabunny";
|
|
2
2
|
const PARAM_REGEX_CACHE = new Map();
|
|
3
|
-
/**
|
|
4
|
-
* Parse a numeric parameter from a mediaType string (e.g. "audio/pcm;rate=24000").
|
|
5
|
-
* Returns undefined if missing or non-positive.
|
|
6
|
-
*/
|
|
7
3
|
export function parseMediaTypeParam(mediaType, name) {
|
|
8
4
|
let re = PARAM_REGEX_CACHE.get(name);
|
|
9
5
|
if (!re) {
|
|
10
|
-
// End boundary
|
|
11
|
-
// end-of-string. Rejects values like "rate=24000x".
|
|
6
|
+
// End boundary rejects values like "rate=24000x".
|
|
12
7
|
re = new RegExp(`(?:^|;)\\s*${name}=(\\d+)(?=$|;|\\s)`, "i");
|
|
13
8
|
PARAM_REGEX_CACHE.set(name, re);
|
|
14
9
|
}
|
|
15
10
|
const match = mediaType.match(re);
|
|
16
11
|
if (!match) {
|
|
17
|
-
return
|
|
12
|
+
return;
|
|
18
13
|
}
|
|
19
14
|
const value = Number(match[1]);
|
|
20
15
|
return Number.isFinite(value) && value > 0 ? value : undefined;
|
|
21
16
|
}
|
|
22
|
-
/**
|
|
23
|
-
* Wrap raw 16-bit little-endian mono PCM bytes in a WAV container.
|
|
24
|
-
* Cross-platform (browser, Node, edge) via mediabunny's container ops —
|
|
25
|
-
* does not require the WebCodecs encoder.
|
|
26
|
-
*/
|
|
27
17
|
export async function wrapPcm16Mono(pcm, sampleRate) {
|
|
28
18
|
const output = new Output({
|
|
29
19
|
format: new WavOutputFormat(),
|
|
@@ -32,7 +22,6 @@ export async function wrapPcm16Mono(pcm, sampleRate) {
|
|
|
32
22
|
const source = new EncodedAudioPacketSource("pcm-s16");
|
|
33
23
|
output.addAudioTrack(source);
|
|
34
24
|
await output.start();
|
|
35
|
-
// 2 bytes per sample, mono.
|
|
36
25
|
const numSamples = pcm.length / 2;
|
|
37
26
|
const durationSeconds = numSamples / sampleRate;
|
|
38
27
|
const packet = new EncodedPacket(pcm, "key", 0, durationSeconds, 0);
|
|
@@ -50,4 +39,12 @@ export async function wrapPcm16Mono(pcm, sampleRate) {
|
|
|
50
39
|
}
|
|
51
40
|
return new Uint8Array(buffer);
|
|
52
41
|
}
|
|
42
|
+
export function base64ToUint8Array(b64) {
|
|
43
|
+
const binary = atob(b64);
|
|
44
|
+
const bytes = new Uint8Array(binary.length);
|
|
45
|
+
for (let i = 0; i < binary.length; i++) {
|
|
46
|
+
bytes[i] = binary.charCodeAt(i);
|
|
47
|
+
}
|
|
48
|
+
return bytes;
|
|
49
|
+
}
|
|
53
50
|
//# sourceMappingURL=audio-utils.js.map
|
package/dist/audio-utils.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"audio-utils.js","sourceRoot":"","sources":["../src/audio-utils.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,YAAY,EACZ,wBAAwB,EACxB,aAAa,EACb,MAAM,EACN,eAAe,GAChB,MAAM,YAAY,CAAC;AAEpB,MAAM,iBAAiB,GAAG,IAAI,GAAG,EAAkB,CAAC;AAEpD
|
|
1
|
+
{"version":3,"file":"audio-utils.js","sourceRoot":"","sources":["../src/audio-utils.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,YAAY,EACZ,wBAAwB,EACxB,aAAa,EACb,MAAM,EACN,eAAe,GAChB,MAAM,YAAY,CAAC;AAEpB,MAAM,iBAAiB,GAAG,IAAI,GAAG,EAAkB,CAAC;AAEpD,MAAM,UAAU,mBAAmB,CACjC,SAAiB,EACjB,IAAY;IAEZ,IAAI,EAAE,GAAG,iBAAiB,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IACrC,IAAI,CAAC,EAAE,EAAE,CAAC;QACR,kDAAkD;QAClD,EAAE,GAAG,IAAI,MAAM,CAAC,cAAc,IAAI,oBAAoB,EAAE,GAAG,CAAC,CAAC;QAC7D,iBAAiB,CAAC,GAAG,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;IAClC,CAAC;IACD,MAAM,KAAK,GAAG,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;IAClC,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,OAAO;IACT,CAAC;IACD,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;IAC/B,OAAO,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC;AACjE,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,GAAe,EACf,UAAkB;IAElB,MAAM,MAAM,GAAG,IAAI,MAAM,CAAC;QACxB,MAAM,EAAE,IAAI,eAAe,EAAE;QAC7B,MAAM,EAAE,IAAI,YAAY,EAAE;KAC3B,CAAC,CAAC;IACH,MAAM,MAAM,GAAG,IAAI,wBAAwB,CAAC,SAAS,CAAC,CAAC;IACvD,MAAM,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC;IAC7B,MAAM,MAAM,CAAC,KAAK,EAAE,CAAC;IAErB,MAAM,UAAU,GAAG,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC;IAClC,MAAM,eAAe,GAAG,UAAU,GAAG,UAAU,CAAC;IAChD,MAAM,MAAM,GAAG,IAAI,aAAa,CAAC,GAAG,EAAE,KAAK,EAAE,CAAC,EAAE,eAAe,EAAE,CAAC,CAAC,CAAC;IACpE,MAAM,MAAM,CAAC,GAAG,CAAC,MAAM,EAAE;QACvB,aAAa,EAAE;YACb,KAAK,EAAE,SAAS;YAChB,gBAAgB,EAAE,CAAC;YACnB,UAAU;SACX;KACF,CAAC,CAAC;IAEH,MAAM,MAAM,CAAC,QAAQ,EAAE,CAAC;IACxB,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC;IACpC,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,MAAM,IAAI,KAAK,CAAC,iDAAiD,CAAC,CAAC;IACrE,CAAC;IACD,OAAO,IAAI,UAAU,CAAC,MAAM,CAAC,CAAC;AAChC,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,GAAW;IAC5C,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC;IACzB,MAAM,KAAK,GAAG,IAAI,UAAU,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IAC5C,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACvC,KAAK,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;IAClC,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { WordTimestamp } from "./timestamps.js";
|
|
2
|
+
export declare function normalizeTypography(text: string): string;
|
|
3
|
+
export declare function escapeVttText(text: string): string;
|
|
4
|
+
export declare function formatSrtTime(seconds: number): string;
|
|
5
|
+
export declare function formatVttTime(seconds: number): string;
|
|
6
|
+
export declare function groupIntoSentences(words: readonly WordTimestamp[]): WordTimestamp[][];
|
|
7
|
+
interface CueSplitOptions {
|
|
8
|
+
readonly longPhraseCommaBreakChars: number;
|
|
9
|
+
readonly maxCharsPerCue: number;
|
|
10
|
+
readonly maxCueDurationMs: number;
|
|
11
|
+
}
|
|
12
|
+
export declare function splitSentenceIntoCues(sentence: readonly WordTimestamp[], options: CueSplitOptions): WordTimestamp[][];
|
|
13
|
+
interface WrapOptions {
|
|
14
|
+
readonly maxLineLength: number;
|
|
15
|
+
readonly maxLines: number;
|
|
16
|
+
}
|
|
17
|
+
export declare function wrapCueText(words: readonly string[], options: WrapOptions): string;
|
|
18
|
+
export type CaptionFormat = "srt" | "vtt";
|
|
19
|
+
export interface CaptionsOptions {
|
|
20
|
+
readonly format?: CaptionFormat;
|
|
21
|
+
readonly longPhraseCommaBreakChars?: number;
|
|
22
|
+
readonly maxCharsPerCue?: number;
|
|
23
|
+
readonly maxCueDurationMs?: number;
|
|
24
|
+
readonly maxLineLength?: number;
|
|
25
|
+
readonly maxLinesPerCue?: number;
|
|
26
|
+
}
|
|
27
|
+
export declare function timestampsToCaptions(timestamps: readonly WordTimestamp[], options?: CaptionsOptions): string;
|
|
28
|
+
export {};
|
|
29
|
+
//# sourceMappingURL=captions.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"captions.d.ts","sourceRoot":"","sources":["../src/captions.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAsBrD,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAMxD;AAQD,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAMlD;AAeD,wBAAgB,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAErD;AAED,wBAAgB,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAErD;AAOD,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,SAAS,aAAa,EAAE,GAC9B,aAAa,EAAE,EAAE,CAcnB;AAMD,UAAU,eAAe;IACvB,QAAQ,CAAC,yBAAyB,EAAE,MAAM,CAAC;IAC3C,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAC;CACnC;AA0BD,wBAAgB,qBAAqB,CACnC,QAAQ,EAAE,SAAS,aAAa,EAAE,EAClC,OAAO,EAAE,eAAe,GACvB,aAAa,EAAE,EAAE,CAgCnB;AAED,UAAU,WAAW;IACnB,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;CAC3B;AAGD,wBAAgB,WAAW,CACzB,KAAK,EAAE,SAAS,MAAM,EAAE,EACxB,OAAO,EAAE,WAAW,GACnB,MAAM,CAmBR;AAED,MAAM,MAAM,aAAa,GAAG,KAAK,GAAG,KAAK,CAAC;AAE1C,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,MAAM,CAAC,EAAE,aAAa,CAAC;IAChC,QAAQ,CAAC,yBAAyB,CAAC,EAAE,MAAM,CAAC;IAC5C,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAC;IACjC,QAAQ,CAAC,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAEnC,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAC;CAClC;AAWD,wBAAgB,oBAAoB,CAClC,UAAU,EAAE,SAAS,aAAa,EAAE,EACpC,OAAO,GAAE,eAAoB,GAC5B,MAAM,CA8DR"}
|
package/dist/captions.js
ADDED
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
const SECONDS_PER_HOUR = 3600;
|
|
2
|
+
const SECONDS_PER_MINUTE = 60;
|
|
3
|
+
const MS_PER_SECOND = 1000;
|
|
4
|
+
const TYPOGRAPHY_MAP = [
|
|
5
|
+
[/\u2019/g, "'"],
|
|
6
|
+
[/\u2018/g, "'"],
|
|
7
|
+
[/\u201C/g, '"'],
|
|
8
|
+
[/\u201D/g, '"'],
|
|
9
|
+
[/\u2013/g, "-"],
|
|
10
|
+
[/\u2014/g, "-"],
|
|
11
|
+
[/\u2026/g, "..."],
|
|
12
|
+
];
|
|
13
|
+
// Strip C0 controls (excluding whitespace) + DEL — some parsers truncate on NUL.
|
|
14
|
+
// biome-ignore lint/suspicious/noControlCharactersInRegex: intentional — this regex exists to strip control characters
|
|
15
|
+
const CONTROL_CHARS = /[\u0000-\u0008\u000E-\u001F\u007F]/g;
|
|
16
|
+
const WHITESPACE_RUN = /\s+/g;
|
|
17
|
+
export function normalizeTypography(text) {
|
|
18
|
+
let out = text.replace(CONTROL_CHARS, "");
|
|
19
|
+
for (const [pattern, replacement] of TYPOGRAPHY_MAP) {
|
|
20
|
+
out = out.replace(pattern, replacement);
|
|
21
|
+
}
|
|
22
|
+
return out.replace(WHITESPACE_RUN, " ");
|
|
23
|
+
}
|
|
24
|
+
const VTT_ESCAPE_MAP = [
|
|
25
|
+
[/&/g, "&"],
|
|
26
|
+
[/</g, "<"],
|
|
27
|
+
[/>/g, ">"],
|
|
28
|
+
];
|
|
29
|
+
export function escapeVttText(text) {
|
|
30
|
+
let out = text;
|
|
31
|
+
for (const [pattern, replacement] of VTT_ESCAPE_MAP) {
|
|
32
|
+
out = out.replace(pattern, replacement);
|
|
33
|
+
}
|
|
34
|
+
return out;
|
|
35
|
+
}
|
|
36
|
+
function formatTimestamp(seconds, separator) {
|
|
37
|
+
const clamped = Math.max(0, seconds);
|
|
38
|
+
const totalMs = Math.round(clamped * MS_PER_SECOND);
|
|
39
|
+
const ms = totalMs % MS_PER_SECOND;
|
|
40
|
+
const totalSeconds = Math.floor(totalMs / MS_PER_SECOND);
|
|
41
|
+
const hours = Math.floor(totalSeconds / SECONDS_PER_HOUR);
|
|
42
|
+
const minutes = Math.floor((totalSeconds % SECONDS_PER_HOUR) / SECONDS_PER_MINUTE);
|
|
43
|
+
const secs = totalSeconds % SECONDS_PER_MINUTE;
|
|
44
|
+
return `${String(hours).padStart(2, "0")}:${String(minutes).padStart(2, "0")}:${String(secs).padStart(2, "0")}${separator}${String(ms).padStart(3, "0")}`;
|
|
45
|
+
}
|
|
46
|
+
export function formatSrtTime(seconds) {
|
|
47
|
+
return formatTimestamp(seconds, ",");
|
|
48
|
+
}
|
|
49
|
+
export function formatVttTime(seconds) {
|
|
50
|
+
return formatTimestamp(seconds, ".");
|
|
51
|
+
}
|
|
52
|
+
// Sentence terminators: ASCII + CJK + Devanagari + Arabic, optional trailing quote.
|
|
53
|
+
const SENTENCE_TERMINATOR = /[.!?\u3002\uFF01\uFF1F\u0964\u0965\u061F\u06D4]["'\u2018\u2019\u201C\u201D\u300D\u300F]?$/;
|
|
54
|
+
// Limitations: "Dr."/"e.g." are treated as sentence ends; Thai etc. fall through to char/duration breaks.
|
|
55
|
+
export function groupIntoSentences(words) {
|
|
56
|
+
const sentences = [];
|
|
57
|
+
let current = [];
|
|
58
|
+
for (const word of words) {
|
|
59
|
+
current.push(word);
|
|
60
|
+
if (SENTENCE_TERMINATOR.test(word.text.trim())) {
|
|
61
|
+
sentences.push(current);
|
|
62
|
+
current = [];
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
if (current.length > 0) {
|
|
66
|
+
sentences.push(current);
|
|
67
|
+
}
|
|
68
|
+
return sentences;
|
|
69
|
+
}
|
|
70
|
+
// Comma-equivalent soft breaks: ASCII + CJK + Arabic.
|
|
71
|
+
const COMMA_TERMINATOR = /[,\u3001\uFF0C\u060C]["'\u2018\u2019\u201C\u201D\u300D\u300F]?$/;
|
|
72
|
+
function cueCharLength(cue) {
|
|
73
|
+
let chars = 0;
|
|
74
|
+
for (const word of cue) {
|
|
75
|
+
chars += word.text.length;
|
|
76
|
+
}
|
|
77
|
+
if (cue.length > 1) {
|
|
78
|
+
chars += cue.length - 1;
|
|
79
|
+
}
|
|
80
|
+
return chars;
|
|
81
|
+
}
|
|
82
|
+
function cueDurationMs(cue) {
|
|
83
|
+
if (cue.length === 0) {
|
|
84
|
+
return 0;
|
|
85
|
+
}
|
|
86
|
+
const first = cue[0];
|
|
87
|
+
const last = cue.at(-1);
|
|
88
|
+
if (!last) {
|
|
89
|
+
return 0;
|
|
90
|
+
}
|
|
91
|
+
return (last.end - first.start) * 1000;
|
|
92
|
+
}
|
|
93
|
+
// Break priority: char budget → duration → comma above longPhraseCommaBreakChars.
|
|
94
|
+
export function splitSentenceIntoCues(sentence, options) {
|
|
95
|
+
const cues = [];
|
|
96
|
+
let current = [];
|
|
97
|
+
for (const word of sentence) {
|
|
98
|
+
const tentative = [...current, word];
|
|
99
|
+
const exceedsChars = cueCharLength(tentative) > options.maxCharsPerCue;
|
|
100
|
+
const exceedsDuration = cueDurationMs(tentative) > options.maxCueDurationMs;
|
|
101
|
+
if ((exceedsChars || exceedsDuration) && current.length > 0) {
|
|
102
|
+
cues.push(current);
|
|
103
|
+
current = [word];
|
|
104
|
+
continue;
|
|
105
|
+
}
|
|
106
|
+
current.push(word);
|
|
107
|
+
const endsWithComma = COMMA_TERMINATOR.test(word.text.trim());
|
|
108
|
+
if (endsWithComma &&
|
|
109
|
+
cueCharLength(current) + 1 >= options.longPhraseCommaBreakChars) {
|
|
110
|
+
cues.push(current);
|
|
111
|
+
current = [];
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
if (current.length > 0) {
|
|
115
|
+
cues.push(current);
|
|
116
|
+
}
|
|
117
|
+
return cues;
|
|
118
|
+
}
|
|
119
|
+
// Words longer than maxLineLength go on their own line; overflow appends to the last line.
|
|
120
|
+
export function wrapCueText(words, options) {
|
|
121
|
+
if (words.length === 0) {
|
|
122
|
+
return "";
|
|
123
|
+
}
|
|
124
|
+
const lines = [""];
|
|
125
|
+
for (const word of words) {
|
|
126
|
+
const last = lines.at(-1) ?? "";
|
|
127
|
+
const candidate = last.length === 0 ? word : `${last} ${word}`;
|
|
128
|
+
if (candidate.length <= options.maxLineLength ||
|
|
129
|
+
last.length === 0 ||
|
|
130
|
+
lines.length >= options.maxLines) {
|
|
131
|
+
lines[lines.length - 1] = candidate;
|
|
132
|
+
}
|
|
133
|
+
else {
|
|
134
|
+
lines.push(word);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
return lines.join("\n");
|
|
138
|
+
}
|
|
139
|
+
const DEFAULT_MAX_LINE_LENGTH = 42;
|
|
140
|
+
const DEFAULT_MAX_LINES_PER_CUE = 2;
|
|
141
|
+
const DEFAULT_MAX_CUE_DURATION_MS = 7000;
|
|
142
|
+
const DEFAULT_LONG_PHRASE_COMMA_BREAK_CHARS = 60;
|
|
143
|
+
function identity(text) {
|
|
144
|
+
return text;
|
|
145
|
+
}
|
|
146
|
+
export function timestampsToCaptions(timestamps, options = {}) {
|
|
147
|
+
const format = options.format ?? "srt";
|
|
148
|
+
if (timestamps.length === 0) {
|
|
149
|
+
// WebVTT requires the WEBVTT header per W3C §3.1, even with zero cues.
|
|
150
|
+
return format === "vtt" ? "WEBVTT\n\n" : "";
|
|
151
|
+
}
|
|
152
|
+
const maxLineLength = options.maxLineLength ?? DEFAULT_MAX_LINE_LENGTH;
|
|
153
|
+
const maxLinesPerCue = options.maxLinesPerCue ?? DEFAULT_MAX_LINES_PER_CUE;
|
|
154
|
+
const maxCharsPerCue = options.maxCharsPerCue ?? maxLineLength * maxLinesPerCue;
|
|
155
|
+
const maxCueDurationMs = options.maxCueDurationMs ?? DEFAULT_MAX_CUE_DURATION_MS;
|
|
156
|
+
const longPhraseCommaBreakChars = options.longPhraseCommaBreakChars ?? DEFAULT_LONG_PHRASE_COMMA_BREAK_CHARS;
|
|
157
|
+
const sentences = groupIntoSentences(timestamps);
|
|
158
|
+
const cues = [];
|
|
159
|
+
for (const sentence of sentences) {
|
|
160
|
+
cues.push(...splitSentenceIntoCues(sentence, {
|
|
161
|
+
maxCharsPerCue,
|
|
162
|
+
maxCueDurationMs,
|
|
163
|
+
longPhraseCommaBreakChars,
|
|
164
|
+
}));
|
|
165
|
+
}
|
|
166
|
+
const formatTime = format === "vtt" ? formatVttTime : formatSrtTime;
|
|
167
|
+
const escapeText = format === "vtt" ? escapeVttText : identity;
|
|
168
|
+
const blocks = [];
|
|
169
|
+
if (format === "vtt") {
|
|
170
|
+
blocks.push("WEBVTT\n");
|
|
171
|
+
}
|
|
172
|
+
let index = 1;
|
|
173
|
+
for (const cue of cues) {
|
|
174
|
+
if (cue.length === 0) {
|
|
175
|
+
continue;
|
|
176
|
+
}
|
|
177
|
+
const normalizedWords = cue.map((wt) => escapeText(normalizeTypography(wt.text)));
|
|
178
|
+
const body = wrapCueText(normalizedWords, {
|
|
179
|
+
maxLineLength,
|
|
180
|
+
maxLines: maxLinesPerCue,
|
|
181
|
+
});
|
|
182
|
+
const first = cue[0];
|
|
183
|
+
const last = cue.at(-1);
|
|
184
|
+
if (!last) {
|
|
185
|
+
continue;
|
|
186
|
+
}
|
|
187
|
+
blocks.push(`${index}\n${formatTime(first.start)} --> ${formatTime(last.end)}\n${body}\n`);
|
|
188
|
+
index++;
|
|
189
|
+
}
|
|
190
|
+
// Trailing blank line required by WebVTT and expected by strict SRT parsers.
|
|
191
|
+
return `${blocks.join("\n")}\n`;
|
|
192
|
+
}
|
|
193
|
+
//# sourceMappingURL=captions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"captions.js","sourceRoot":"","sources":["../src/captions.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { ConversationWordTimestamp, WordTimestamp } from "../timestamps.js";
|
|
2
|
+
import type { SilenceGap } from "./silence-detection.js";
|
|
3
|
+
export interface Tier2Result {
|
|
4
|
+
readonly budgetExceeded: boolean;
|
|
5
|
+
readonly mismatches: number;
|
|
6
|
+
readonly timestamps: readonly ConversationWordTimestamp[];
|
|
7
|
+
}
|
|
8
|
+
export declare function tier2TextMatch(args: {
|
|
9
|
+
timestamps: readonly WordTimestamp[];
|
|
10
|
+
turnTexts: readonly string[];
|
|
11
|
+
}): Tier2Result;
|
|
12
|
+
export declare function tier1SilenceAnchored(args: {
|
|
13
|
+
timestamps: readonly WordTimestamp[];
|
|
14
|
+
gaps: readonly SilenceGap[];
|
|
15
|
+
turnTexts: readonly string[];
|
|
16
|
+
}): readonly ConversationWordTimestamp[] | undefined;
|
|
17
|
+
export interface AttributeTimestampsResult {
|
|
18
|
+
readonly timestamps?: readonly ConversationWordTimestamp[];
|
|
19
|
+
readonly warnings: readonly string[];
|
|
20
|
+
}
|
|
21
|
+
export declare function attributeTimestamps(args: {
|
|
22
|
+
timestamps: readonly WordTimestamp[];
|
|
23
|
+
turnTexts: readonly string[];
|
|
24
|
+
silenceGaps: readonly SilenceGap[];
|
|
25
|
+
}): AttributeTimestampsResult;
|
|
26
|
+
//# sourceMappingURL=attribute-timestamps.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"attribute-timestamps.d.ts","sourceRoot":"","sources":["../../src/conversation/attribute-timestamps.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,yBAAyB,EACzB,aAAa,EACd,MAAM,kBAAkB,CAAC;AAE1B,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AA6DzD,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,cAAc,EAAE,OAAO,CAAC;IACjC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,UAAU,EAAE,SAAS,yBAAyB,EAAE,CAAC;CAC3D;AAGD,wBAAgB,cAAc,CAAC,IAAI,EAAE;IACnC,UAAU,EAAE,SAAS,aAAa,EAAE,CAAC;IACrC,SAAS,EAAE,SAAS,MAAM,EAAE,CAAC;CAC9B,GAAG,WAAW,CA4Id;AAYD,wBAAgB,oBAAoB,CAAC,IAAI,EAAE;IACzC,UAAU,EAAE,SAAS,aAAa,EAAE,CAAC;IACrC,IAAI,EAAE,SAAS,UAAU,EAAE,CAAC;IAC5B,SAAS,EAAE,SAAS,MAAM,EAAE,CAAC;CAC9B,GAAG,SAAS,yBAAyB,EAAE,GAAG,SAAS,CAqEnD;AAED,MAAM,WAAW,yBAAyB;IACxC,QAAQ,CAAC,UAAU,CAAC,EAAE,SAAS,yBAAyB,EAAE,CAAC;IAC3D,QAAQ,CAAC,QAAQ,EAAE,SAAS,MAAM,EAAE,CAAC;CACtC;AAED,wBAAgB,mBAAmB,CAAC,IAAI,EAAE;IACxC,UAAU,EAAE,SAAS,aAAa,EAAE,CAAC;IACrC,SAAS,EAAE,SAAS,MAAM,EAAE,CAAC;IAC7B,WAAW,EAAE,SAAS,UAAU,EAAE,CAAC;CACpC,GAAG,yBAAyB,CAwC5B"}
|