@vocalstack/player 0.0.0-stage → 0.1.0-alpha.0

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.
Files changed (41) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +36 -2
  3. package/dist/core/audio.d.ts +39 -0
  4. package/dist/core/background.d.ts +54 -0
  5. package/dist/core/clipPrefetch.d.ts +38 -0
  6. package/dist/core/clipQueue.d.ts +130 -0
  7. package/dist/core/format.d.ts +17 -0
  8. package/dist/core/mediaKeys.d.ts +14 -0
  9. package/dist/core/noAudio.d.ts +18 -0
  10. package/dist/core/playPosition.d.ts +18 -0
  11. package/dist/core/qr.d.ts +2 -0
  12. package/dist/core/readalong.d.ts +17 -0
  13. package/dist/core/transcript.d.ts +126 -0
  14. package/dist/core/voiceFollow.d.ts +44 -0
  15. package/dist/core/voiceRetry.d.ts +2 -0
  16. package/dist/core/voiceplayer.d.ts +31 -0
  17. package/dist/core/youtube.d.ts +9 -0
  18. package/dist/data/connect.d.ts +14 -0
  19. package/dist/data/context.d.ts +60 -0
  20. package/dist/data/errors.d.ts +9 -0
  21. package/dist/data/i18n.d.ts +425 -0
  22. package/dist/data/prefs.d.ts +14 -0
  23. package/dist/data/transcript.d.ts +27 -0
  24. package/dist/data/tx.d.ts +37 -0
  25. package/dist/data/voicePreview.d.ts +15 -0
  26. package/dist/ds/Controls.d.ts +163 -0
  27. package/dist/ds/Icons.d.ts +141 -0
  28. package/dist/ds/LanguagePicker.d.ts +34 -0
  29. package/dist/index.d.ts +6 -0
  30. package/dist/index.js +5377 -0
  31. package/dist/index.js.map +1 -0
  32. package/dist/style.css +1 -0
  33. package/dist/ui/EndCard.d.ts +11 -0
  34. package/dist/ui/SideColumn.d.ts +49 -0
  35. package/dist/ui/VocalStackPlayer.d.ts +33 -0
  36. package/dist/ui/core.d.ts +227 -0
  37. package/dist/ui/full.d.ts +108 -0
  38. package/dist/ui/shared.d.ts +276 -0
  39. package/dist/ui/useDesk.d.ts +1 -0
  40. package/dist/ui/wait.d.ts +24 -0
  41. package/package.json +49 -4
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 VocalStack
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,3 +1,37 @@
1
- # Temporary Holding Version
1
+ # @vocalstack/player
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ A React video and transcript player for [VocalStack](https://vocalstack.com) transcriptions. It shows subtitles, a synced transcript, and spoken translations read in the speakers' own (cloned) or stock voices. It can also remove the background sound. It talks only to the public VocalStack API.
4
+
5
+ ```bash
6
+ npm install @vocalstack/player
7
+ ```
8
+
9
+ ```tsx
10
+ import { VocalStackPlayer } from '@vocalstack/player';
11
+ import '@vocalstack/player/style.css';
12
+
13
+ export function Video() {
14
+ return <VocalStackPlayer id="r4m4srrrhi24" mode="video" />;
15
+ }
16
+ ```
17
+
18
+ `id` is the share code from a VocalStack share link (`vocalstack.com/v/<code>`). Shared transcriptions need no key.
19
+
20
+ ## Props
21
+
22
+ | Prop | Default | |
23
+ |---|---|---|
24
+ | `id` | required | A share code. Or, with `token`, a transcription id. |
25
+ | `token` | none | A browser token (or a function returning one) for a private transcription. Never pass an API key to a browser. |
26
+ | `mode` | `'video'` | `'video'` for the full player, `'transcript'` for the reading view with a player. |
27
+ | `layout` | `'embed'` | `'embed'` sizes to its container (16:9 for video); `'page'` fills the page. |
28
+ | `initial` | none | `{ lang, cc, translateAudio, clonedVoices, removeBackground, labels, words, startAt }` |
29
+ | `endCard` | on | At the end of a video, offers to transcribe another link in the visitor's own VocalStack account. Pass `false` to turn it off. |
30
+ | `baseUrl` | `https://api.vocalstack.com` | |
31
+ | `onSource`, `onProgress`, `onError` | none | Callbacks for the loaded transcription, the transcription progress (0-100, `null` when done), and errors. |
32
+
33
+ Theme it by overriding the CSS variables on `.vsp`, for example `--vsp-radius`, `--brand` and `--vs-font-sans`.
34
+
35
+ ## License
36
+
37
+ MIT
@@ -0,0 +1,39 @@
1
+ export declare function setErrorReporter(fn: ((e: Error) => void) | null): void;
2
+ export declare function reportError(e: Error): void;
3
+ export declare function liveAudioSupported(): boolean;
4
+ export declare class LivePlayer {
5
+ private ctx;
6
+ private decoder;
7
+ private demux;
8
+ private nextTime;
9
+ private gain;
10
+ private headerSeen;
11
+ private ts;
12
+ volume: number;
13
+ start(): Promise<void>;
14
+ setVolume(v: number): void;
15
+ feed(bytes: ArrayBuffer): void;
16
+ private play;
17
+ stop(): Promise<void>;
18
+ }
19
+ export declare function deliveryFormat(): 'ogg' | 'caf';
20
+ export interface MediaCred {
21
+ accessToken?: string | null;
22
+ listenerToken?: string | null;
23
+ shareCode?: string | null;
24
+ media?: string | null;
25
+ }
26
+ export declare function credParams(cred?: MediaCred): string;
27
+ export declare function audioClipUrl(apiOrigin: string, recordingId: string, startS: number, endS: number, cred?: MediaCred, clean?: boolean): string;
28
+ export declare function explainAudioError(url: string): Promise<{
29
+ message: string;
30
+ permanent: boolean;
31
+ } | null>;
32
+ export declare function audioSealed(url: string): Promise<boolean>;
33
+ export declare function deliveryAudioUrl(apiOrigin: string, recordingId: string, cred?: MediaCred): string;
34
+ export declare function backgroundAudioUrl(apiOrigin: string, recordingId: string, cred?: MediaCred, kind?: 'background' | 'speech'): string;
35
+ export declare function audioDownloadUrl(apiOrigin: string, recordingId: string, kind: 'source' | 'delivery' | 'video', cred?: MediaCred): string;
36
+ export declare function voiceTrackUrl(apiOrigin: string, recordingId: string, lang: string, voiceKey: string, cred?: MediaCred): string;
37
+ export declare function voiceTrackDownloadUrl(apiOrigin: string, recordingId: string, lang: string, voiceKey: string, cred?: MediaCred): string;
38
+ export declare function mediaErrorText(e: MediaError | null, report?: boolean): string;
39
+ export declare function reportMediaError(e: MediaError | null): void;
@@ -0,0 +1,54 @@
1
+ export type BedState = 'off' | 'making' | 'ready' | 'unavailable';
2
+ export declare const BED_DRIFT_S = 0.3;
3
+ export interface BedMedia {
4
+ currentTime: number;
5
+ paused: boolean;
6
+ muted: boolean;
7
+ play: () => Promise<void> | void;
8
+ pause: () => void;
9
+ }
10
+ export declare function followBed(a: BedMedia, want: {
11
+ t: number;
12
+ playing: boolean;
13
+ muted: boolean;
14
+ }): void;
15
+ export declare const REMOVE_BG_LABEL = "Remove background sound";
16
+ export declare const REMOVE_BG_NOTE = "Takes out everything that isn't speech: music, ambience and noise.";
17
+ export declare function bedNote(on: boolean, state: BedState, what?: 'transcription' | 'video', untilS?: number): string;
18
+ export interface TrackPlan {
19
+ bed: boolean;
20
+ speech: boolean;
21
+ }
22
+ export declare function trackPlan(removeBg: boolean, voiceOn: boolean): TrackPlan;
23
+ export declare function removeBgOf(stored: boolean | null, oldKeep: boolean | null): boolean;
24
+ export declare function removeBgFromQuery(q: URLSearchParams): boolean;
25
+ export declare function withRemoveBg(u: URL, removeBg: boolean): void;
26
+ export declare function bedRetryS(status: number, body: unknown): number | null;
27
+ export interface SepPart {
28
+ startS: number;
29
+ endS: number;
30
+ url: string;
31
+ }
32
+ export declare const SEAM_S = 0.05;
33
+ export declare function partsOf(body: unknown): {
34
+ untilS: number;
35
+ parts: SepPart[];
36
+ };
37
+ export declare function partAt(parts: SepPart[], t: number): number;
38
+ export declare function slotsFor(parts: SepPart[], i: number, held: [number, number], cur: 0 | 1): {
39
+ play: 0 | 1;
40
+ load: Array<[0 | 1, number]>;
41
+ };
42
+ export interface Separated {
43
+ state: BedState;
44
+ on: boolean;
45
+ untilS: number;
46
+ }
47
+ type Want = {
48
+ t: number;
49
+ playing: boolean;
50
+ muted: boolean;
51
+ };
52
+ export declare function useSeparatedTrack(url: string | null, want: Want): Separated;
53
+ export declare function useBackgroundBed(url: string | null, want: Want): BedState;
54
+ export {};
@@ -0,0 +1,38 @@
1
+ export type Fetcher = (src: string, signal: AbortSignal) => Promise<{
2
+ ok: boolean;
3
+ status: number;
4
+ blob: () => Promise<Blob>;
5
+ }>;
6
+ export interface PrefetchOptions {
7
+ fetcher?: Fetcher;
8
+ concurrency?: number;
9
+ keep?: number;
10
+ retryMs?: number;
11
+ now?: () => number;
12
+ toUrl?: (b: Blob) => string;
13
+ revoke?: (url: string) => void;
14
+ }
15
+ export declare class ClipPrefetch {
16
+ private entries;
17
+ private wanted;
18
+ private used;
19
+ private readonly fetcher;
20
+ private readonly concurrency;
21
+ private readonly keep;
22
+ private readonly retryMs;
23
+ private readonly now;
24
+ private readonly toUrl;
25
+ private readonly revoke;
26
+ onReady: (src: string) => void;
27
+ constructor(o?: PrefetchOptions);
28
+ want(srcs: string[]): void;
29
+ urlFor(src: string): string;
30
+ ready(src: string): boolean;
31
+ loading(): number;
32
+ forget(src: string): void;
33
+ clear(): void;
34
+ private evict;
35
+ private usedRank;
36
+ private pump;
37
+ private load;
38
+ }
@@ -0,0 +1,130 @@
1
+ import { ClipPrefetch } from './clipPrefetch';
2
+ export declare const mediaKind: {
3
+ video: boolean;
4
+ };
5
+ export declare function newMediaElement(url?: string): HTMLMediaElement;
6
+ export interface VoiceClip {
7
+ sentenceId: number;
8
+ lang: string;
9
+ src: string;
10
+ durationS: number;
11
+ generation?: number;
12
+ part: number;
13
+ parts: number;
14
+ voice?: string | null;
15
+ cloned?: boolean;
16
+ }
17
+ export declare class VoiceNotStarted extends Error {
18
+ constructor();
19
+ }
20
+ export declare class ClipQueue {
21
+ private el;
22
+ private clips;
23
+ private order;
24
+ current: number | null;
25
+ private currentPart;
26
+ private partBase;
27
+ private within;
28
+ playing: boolean;
29
+ muted: boolean;
30
+ rate: number;
31
+ volume: number;
32
+ finite: boolean;
33
+ onSentence: (id: number | null) => void;
34
+ onWaiting: (id: number | null) => void;
35
+ onStarting: (since: number | null) => void;
36
+ speakable: (sentenceId: number) => boolean;
37
+ coming: (sentenceId: number) => boolean;
38
+ gapBefore: (prev: number | null, next: number) => number;
39
+ flow: boolean;
40
+ silentSpan: (sentenceId: number) => {
41
+ fromS: number;
42
+ ms: number;
43
+ } | null;
44
+ private lastDone;
45
+ private rested;
46
+ private rest;
47
+ private sequence;
48
+ private seqAt;
49
+ setSequence(ids: number[]): void;
50
+ private rank;
51
+ private expected;
52
+ static WAIT_MS: number;
53
+ static START_WAIT_MS: number;
54
+ static COMING_MS: number;
55
+ static SKEW_LINES: number;
56
+ private spoken;
57
+ private lastRead;
58
+ private started;
59
+ private awaiting;
60
+ private waitTimer;
61
+ onError: (e: unknown) => void;
62
+ private floor;
63
+ private loading;
64
+ readAhead: number;
65
+ readAheadS: number;
66
+ readonly prefetch: ClipPrefetch;
67
+ private warmed;
68
+ private static readonly RETRIES;
69
+ private static readonly RETRY_MS;
70
+ private static readonly STARTING_MS;
71
+ private startingSince;
72
+ private retries;
73
+ private retryTimer;
74
+ add(clip: VoiceClip): void;
75
+ private piecesOf;
76
+ private due;
77
+ private follow;
78
+ private restAfter;
79
+ joinSilently(id: number): void;
80
+ private silentLine;
81
+ private runRest;
82
+ private holdRest;
83
+ private clearRest;
84
+ resting(): {
85
+ sentenceId: number;
86
+ s: number;
87
+ silent: boolean;
88
+ } | null;
89
+ private finishLine;
90
+ private earliestHeld;
91
+ private floorOrBefore;
92
+ private waitFor;
93
+ private stopWaiting;
94
+ has(sentenceId: number): boolean;
95
+ get size(): number;
96
+ latest(): VoiceClip | null;
97
+ clipAt(sentenceId: number): VoiceClip | null;
98
+ private from;
99
+ private edge;
100
+ play(sentenceId: number | null): void;
101
+ pause(): void;
102
+ resume(sentenceId: number | null): boolean;
103
+ private swap;
104
+ readingAt(): number | null;
105
+ arm(sentenceId: number | null): void;
106
+ seekWithin(t: number): void;
107
+ seek(sentenceId: number | null): void;
108
+ setMuted(m: boolean): void;
109
+ setVolume(v: number): void;
110
+ setRate(r: number): void;
111
+ private start;
112
+ private startPartAt;
113
+ startWithin(sentenceId: number, frac: number): void;
114
+ private startPart;
115
+ upcoming(from: number, withFrom?: boolean): VoiceClip[];
116
+ private warm;
117
+ private srcOf;
118
+ private failed;
119
+ private classify;
120
+ private drop;
121
+ position(): {
122
+ sentenceId: number;
123
+ t: number;
124
+ dur: number;
125
+ } | null;
126
+ private element;
127
+ resync(): void;
128
+ clear(): void;
129
+ stop(): void;
130
+ }
@@ -0,0 +1,17 @@
1
+ export declare function clock(s: number): string;
2
+ export declare function durationLabel(s?: number | null): string;
3
+ export declare function monDay(iso?: string | null): {
4
+ mon: string;
5
+ day: string;
6
+ };
7
+ export declare function timeOfDay(iso?: string | null): string;
8
+ export declare function recordingWhen(iso?: string | null): string;
9
+ export declare function dayGroup(iso?: string | null): string;
10
+ export declare function whenLabel(iso?: string | null): string;
11
+ export declare function ago(iso?: string | null): string;
12
+ export declare function dwell(s: number): string;
13
+ export declare function highlightParts(text: string, query: string): {
14
+ t: string;
15
+ hit: boolean;
16
+ }[];
17
+ export declare function pluralize(n: number, one: string, many?: string): string;
@@ -0,0 +1,14 @@
1
+ export type MediaKey = 'play' | 'pause' | 'stop' | 'nexttrack' | 'previoustrack';
2
+ export interface MediaKeyTarget {
3
+ playing: boolean;
4
+ toggle: () => void;
5
+ next?: () => void;
6
+ prev?: () => void;
7
+ }
8
+ export declare const MEDIA_KEYS: MediaKey[];
9
+ export declare function onMediaKey(key: MediaKey, t: MediaKeyTarget): void;
10
+ export interface MediaSessionLike {
11
+ setActionHandler: (action: MediaKey, handler: (() => void) | null) => void;
12
+ }
13
+ export declare function bindMediaKeys(ms: MediaSessionLike, get: () => MediaKeyTarget | null): () => void;
14
+ export declare function useMediaKeys(target: MediaKeyTarget | null, title?: string | null): void;
@@ -0,0 +1,18 @@
1
+ export interface AudioFacts {
2
+ state?: string | null;
3
+ mediaDurationS?: number | null;
4
+ ingest?: {
5
+ state?: string | null;
6
+ error?: string | null;
7
+ startedAt?: string | null;
8
+ } | null;
9
+ }
10
+ export type NoAudio = {
11
+ none: false;
12
+ } | {
13
+ none: true;
14
+ message: string;
15
+ };
16
+ export declare function recordingAudio(rec: AudioFacts | null | undefined, lines: number): NoAudio;
17
+ export declare function noAudioMessage(reason?: string | null): string;
18
+ export declare function isNotCaptured(message?: string | null): boolean;
@@ -0,0 +1,18 @@
1
+ export interface PlaySlot {
2
+ sentenceId?: number | null;
3
+ start: number;
4
+ }
5
+ export interface PlayPos {
6
+ t: number;
7
+ playing: boolean;
8
+ sentenceId: number | null;
9
+ offset: number;
10
+ ended: boolean;
11
+ }
12
+ export interface PlayPlace {
13
+ t: number;
14
+ playing: boolean;
15
+ index: number;
16
+ }
17
+ export declare function snapPosition(rows: readonly PlaySlot[], t: number, playing: boolean, dur: number): PlayPos;
18
+ export declare function placePosition(pos: PlayPos, rows: readonly PlaySlot[], dur: number): PlayPlace;
@@ -0,0 +1,2 @@
1
+ export declare function qrMatrix(text: string): boolean[][];
2
+ export declare function qrSvgUrl(text: string): string;
@@ -0,0 +1,17 @@
1
+ export declare const SUB_LEAD_S = 0.3;
2
+ export declare const SUB_LINGER_S = 1.5;
3
+ export interface Timed {
4
+ start: number;
5
+ end?: number;
6
+ words: {
7
+ start: number;
8
+ end: number;
9
+ }[];
10
+ }
11
+ export declare function lineSpeechEnd(r: Timed, next: Timed | undefined, fallback: number): number;
12
+ export declare function subtitleShown(rows: Timed[], i: number, t: number): boolean;
13
+ export declare function spreadWords(tokens: string[], from: number, to: number): {
14
+ text: string;
15
+ start: number;
16
+ end: number;
17
+ }[];
@@ -0,0 +1,126 @@
1
+ import type { Correction, TranscriptSnapshot } from '@vocalstack/js-sdk';
2
+ export declare function fixedSlots(corrections: Correction[]): Set<string>;
3
+ export interface Word {
4
+ text: string;
5
+ prob?: number | null;
6
+ start: number;
7
+ end: number;
8
+ alts?: {
9
+ text: string;
10
+ prob: number;
11
+ }[];
12
+ script?: boolean;
13
+ recognized?: string;
14
+ seq: number;
15
+ idx: number;
16
+ }
17
+ export interface Row {
18
+ id: string;
19
+ sentenceId?: number;
20
+ seqs: number[];
21
+ speaker: number;
22
+ start: number;
23
+ end?: number;
24
+ wallStart: number;
25
+ text: string;
26
+ words: Word[];
27
+ status: 'open' | 'closed';
28
+ settled: boolean;
29
+ corrected: boolean;
30
+ catchup: boolean;
31
+ suppressed: boolean;
32
+ unclear?: boolean;
33
+ confidence?: number;
34
+ latencyS?: number;
35
+ language?: string;
36
+ translations: Record<string, string>;
37
+ provisional: boolean;
38
+ translationLatencyS?: Record<string, number>;
39
+ }
40
+ export interface Segment {
41
+ seq: number;
42
+ speaker: number;
43
+ start: number;
44
+ end: number;
45
+ text: string;
46
+ words: Word[];
47
+ catchup: boolean;
48
+ corrected: boolean;
49
+ settled: boolean;
50
+ suppressed: boolean;
51
+ unclear?: boolean;
52
+ confidence?: number;
53
+ latencyS?: number;
54
+ language?: string;
55
+ translations: Record<string, string>;
56
+ scriptPos?: number;
57
+ scriptFrom?: number;
58
+ }
59
+ export interface Model {
60
+ segments: Map<number, Segment>;
61
+ sentences: Map<number, Omit<Row, 'words' | 'text' | 'seqs'> & {
62
+ text: string;
63
+ seqs: number[];
64
+ }>;
65
+ speakers: Record<number, string>;
66
+ speakerSpeechS: Record<number, number>;
67
+ speakerSex: Record<number, 'male' | 'female'>;
68
+ speakerIds: Record<number, {
69
+ name: string;
70
+ voiceId?: string;
71
+ color?: string;
72
+ confidence?: number;
73
+ tone?: boolean;
74
+ }>;
75
+ labels?: 'auto' | 'on' | 'off';
76
+ lastSeq: number;
77
+ state: string;
78
+ spans: {
79
+ wallStart: number;
80
+ wallEnd?: number | null;
81
+ mediaStart: number;
82
+ mediaEnd?: number | null;
83
+ }[];
84
+ held?: {
85
+ fromMediaS: number;
86
+ language?: string;
87
+ } | null;
88
+ numbers?: Map<number, number>;
89
+ }
90
+ export declare function empty(): Model;
91
+ export declare function mediaToWall(m: Model, media: number): number;
92
+ export declare function fromSnapshot(snap: TranscriptSnapshot, base?: Model): Model;
93
+ export declare function scriptPosAt(m: Model, at?: number): number | undefined;
94
+ export declare function scriptSpan(m: Model, seqs: number[]): [number, number] | null;
95
+ export declare function applyFrame(m: Model, f: any): Model;
96
+ export declare function rows(m: Model): Row[];
97
+ export declare function heldLine(m: Model): string | null;
98
+ export declare const CONF_MID = 0.85;
99
+ export declare const CONF_LOW = 0.75;
100
+ export declare function confClass(p?: number | null): '' | 'mid' | 'low';
101
+ export declare function lowWords(r: Row, threshold?: number): Word[];
102
+ export declare const LANES: readonly ["a", "b", "c", "d", "e", "f", "g", "h"];
103
+ export type Lane = (typeof LANES)[number];
104
+ export declare function lane(speaker: number): Lane;
105
+ export declare function speakerNumbers(m: Model): Map<number, number>;
106
+ export declare function speakerNumber(m: Model, speaker: number): number;
107
+ export declare function speakerName(m: Model, speaker: number): string | undefined;
108
+ export declare function speakerLabel(m: Model, speaker: number): string;
109
+ export declare function speakerInitial(m: Model, speaker: number): string;
110
+ export declare function speakerColor(voiceColor?: string | null): {
111
+ fg: string;
112
+ soft: string;
113
+ } | undefined;
114
+ export declare function speakerLook(m: Model, speaker: number): {
115
+ fg?: string;
116
+ soft?: string;
117
+ lane: Lane;
118
+ hasVoice: boolean;
119
+ };
120
+ export declare function latestLatency(m: Model): number | undefined;
121
+ export declare function peakLatency(m: Model): number;
122
+ export declare function showLabels(m: Model, rows: {
123
+ speaker: number;
124
+ }[], fallback?: {
125
+ speakerLabels?: 'auto' | 'on' | 'off' | null;
126
+ } | null, own?: boolean): boolean;
@@ -0,0 +1,44 @@
1
+ export interface FollowLine {
2
+ sid: number;
3
+ start: number;
4
+ end: number;
5
+ }
6
+ export interface FollowClip {
7
+ src: string;
8
+ part: number;
9
+ parts: number;
10
+ durationS?: number | null;
11
+ }
12
+ export type FollowTarget = {
13
+ kind: 'play';
14
+ sid: number;
15
+ src: string;
16
+ offset: number;
17
+ } | {
18
+ kind: 'missing';
19
+ sid: number;
20
+ } | {
21
+ kind: 'done';
22
+ sid: number;
23
+ } | {
24
+ kind: 'none';
25
+ };
26
+ export declare const FOLLOW_DRIFT_S = 0.5;
27
+ export declare const FOLLOW_AHEAD = 3;
28
+ export declare function lineAt(lines: readonly FollowLine[], t: number): number;
29
+ export declare function followTarget(lines: readonly FollowLine[], clips: ReadonlyMap<number, readonly FollowClip[]>, t: number): FollowTarget;
30
+ export declare function upcomingSrcs(lines: readonly FollowLine[], clips: ReadonlyMap<number, readonly FollowClip[]>, t: number, n?: number): string[];
31
+ export interface FollowState {
32
+ missing: number | null;
33
+ sid: number | null;
34
+ }
35
+ export declare function useVoiceFollow(o: {
36
+ on: boolean;
37
+ lines: readonly FollowLine[];
38
+ clips: readonly (FollowClip & {
39
+ sentenceId: number;
40
+ })[];
41
+ t: number;
42
+ playing: boolean;
43
+ muted: boolean;
44
+ }): FollowState;
@@ -0,0 +1,2 @@
1
+ export declare const STARTING_DEFAULT_MS = 3000;
2
+ export declare function startingRetryMs(status: number, retryAfter: string | null, body: unknown): number | null;
@@ -0,0 +1,31 @@
1
+ import { type MediaCred } from './audio';
2
+ import type { VoiceClip } from './clipQueue';
3
+ export { ClipQueue, VoiceNotStarted, mediaKind, newMediaElement, type VoiceClip } from './clipQueue';
4
+ export declare function clipOf(f: any, apiOrigin: string, listenerToken?: string | null): VoiceClip | null;
5
+ export interface VoiceTrackRow {
6
+ lang: string;
7
+ voiceKey: string;
8
+ state: string;
9
+ durationS?: number | null;
10
+ error?: string | null;
11
+ clips: number[];
12
+ voice?: string | null;
13
+ wordTimes?: Record<string, [number, number][]>;
14
+ clipRev?: Record<string, string>;
15
+ clipDur?: Record<string, number>;
16
+ clipParts?: Record<string, number>;
17
+ }
18
+ export declare function rowForVoice(rows: VoiceTrackRow[], voiceId: string | null): VoiceTrackRow | null;
19
+ export declare function archiveClips(row: VoiceTrackRow | null | undefined, recordingId: string, apiOrigin: string, cred?: MediaCred, sentenceIds?: number[]): VoiceClip[];
20
+ export interface ReadToken {
21
+ t: string;
22
+ sp: string;
23
+ }
24
+ export declare function readTokens(text: string): ReadToken[];
25
+ export interface ReadPos {
26
+ t: number;
27
+ dur: number;
28
+ words?: [number, number][] | null;
29
+ }
30
+ export declare function readCursor(tokens: ReadToken[], pos: ReadPos): number | null;
31
+ export declare function tokenAt(tokens: ReadToken[], pos: number, dur: number): number;
@@ -0,0 +1,9 @@
1
+ export declare const ytIdOf: (u: string | null | undefined) => string | null;
2
+ export declare const YOUTUBE_LINK: RegExp;
3
+ export declare const isLiveRefusal: (url: string | null | undefined, error: string | null | undefined) => boolean;
4
+ export declare const previewEmbedUrl: (id: string) => string;
5
+ export declare const ytThumbUrl: (id: string) => string;
6
+ export declare const YT_D = "M2.25 12c0-2.6.2-4.3.5-5.2a2.3 2.3 0 0 1 1.6-1.6C5.8 4.8 12 4.8 12 4.8s6.2 0 7.65.4a2.3 2.3 0 0 1 1.6 1.6c.3.9.5 2.6.5 5.2s-.2 4.3-.5 5.2a2.3 2.3 0 0 1-1.6 1.6c-1.45.4-7.65.4-7.65.4s-6.2 0-7.65-.4a2.3 2.3 0 0 1-1.6-1.6c-.3-.9-.5-2.6-.5-5.2ZM10 9.25v5.5L14.75 12 10 9.25Z";
7
+ export declare function youtubeTitle(id: string, signal?: AbortSignal): Promise<string | null>;
8
+ export declare function youtubeChannel(id: string, signal?: AbortSignal): Promise<string | null>;
9
+ export declare const liveEmbedUrl: (id: string) => string;
@@ -0,0 +1,14 @@
1
+ export declare const DEFAULT_APP = "https://app.vocalstack.com";
2
+ export interface Started {
3
+ transcriptionId: string;
4
+ recordingId: string;
5
+ token: string;
6
+ expiresAt: string | null;
7
+ }
8
+ export type PopupStatus = 'signing-in' | 'consent' | 'checking' | 'starting';
9
+ export declare function openPopup(appUrl: string | undefined, ask: {
10
+ url?: string;
11
+ transcription?: string;
12
+ }, onStatus?: (s: PopupStatus) => void): Promise<Started | null>;
13
+ export declare function startFromEmbed(appUrl: string | undefined, url: string, onStatus?: (s: PopupStatus) => void): Promise<Started | null>;
14
+ export declare function refreshToken(appUrl: string | undefined, transcriptionId: string): Promise<Started | null>;