@vocalstack/player 0.1.0-alpha.7 → 0.1.0-alpha.70

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 (40) hide show
  1. package/README.md +12 -0
  2. package/dist/core/archive.d.ts +19 -0
  3. package/dist/core/dailymotion.d.ts +38 -0
  4. package/dist/core/embeds.d.ts +30 -0
  5. package/dist/core/facebook.d.ts +26 -0
  6. package/dist/core/find.d.ts +9 -0
  7. package/dist/core/loomStream.d.ts +5 -0
  8. package/dist/core/share.d.ts +2 -0
  9. package/dist/core/sites.d.ts +13 -0
  10. package/dist/core/streamTime.d.ts +12 -0
  11. package/dist/core/vimeo.d.ts +38 -0
  12. package/dist/core/voiceFollow.d.ts +11 -1
  13. package/dist/core/voiceWait.d.ts +10 -0
  14. package/dist/data/connect.d.ts +8 -0
  15. package/dist/data/context.d.ts +8 -2
  16. package/dist/data/errors.d.ts +1 -0
  17. package/dist/data/title.d.ts +8 -0
  18. package/dist/ds/Controls.d.ts +2 -1
  19. package/dist/ds/Icons.d.ts +1 -0
  20. package/dist/ds/LanguagePicker.d.ts +2 -1
  21. package/dist/index.d.ts +5 -2
  22. package/dist/index.js +5326 -3212
  23. package/dist/index.js.map +1 -1
  24. package/dist/style.css +1 -1
  25. package/dist/ui/DailymotionFollow.d.ts +8 -0
  26. package/dist/ui/EmbedFollow.d.ts +8 -0
  27. package/dist/ui/FacebookFollow.d.ts +7 -0
  28. package/dist/ui/FileFollow.d.ts +10 -0
  29. package/dist/ui/IdleSettings.d.ts +34 -0
  30. package/dist/ui/Providers.d.ts +1 -0
  31. package/dist/ui/SiteIcon.d.ts +9 -0
  32. package/dist/ui/SourceGate.d.ts +27 -3
  33. package/dist/ui/VidyardFollow.d.ts +7 -0
  34. package/dist/ui/VimeoFollow.d.ts +9 -0
  35. package/dist/ui/VocalStackPlayer.d.ts +30 -1
  36. package/dist/ui/WistiaFollow.d.ts +7 -0
  37. package/dist/ui/core.d.ts +27 -20
  38. package/dist/ui/full.d.ts +5 -1
  39. package/dist/ui/shared.d.ts +2 -1
  40. package/package.json +3 -2
package/README.md CHANGED
@@ -35,6 +35,10 @@ export function Video() {
35
35
  | `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. |
36
36
  | `baseUrl` | `https://api.vocalstack.com` | |
37
37
  | `onSource`, `onProgress`, `onError` | | Called with the loaded transcription, the transcription progress (0-100, `null` when done), and errors. |
38
+ | `onPlayback` | | Called about ten times a second while anything changes, with `{ t, dur, playing, idx, seekN, lang }`: the time in seconds, the length, whether it plays, the index of the current line, a counter that grows on every seek, and the language shown. |
39
+ | `ref` | | A `PlayerHandle`: `seek(t)`, `play()`, `pause()`, `toggle()`, `toggleMute()`, `load(link, { poster })`, which opens a video link (or a share link) in the player as if the viewer had pasted it (`poster` is an optional picture shown behind it until it plays), and `clear()`, which empties the player again. |
40
+ | `compact` | `false` | Small controls at any width, and no title, summary or share card when paused. For a player inside a side column or card. |
41
+ | `poster` | | An image shown behind the player before a video is chosen or before the visitor connects. |
38
42
 
39
43
  ### Settings
40
44
 
@@ -61,6 +65,14 @@ export function Video() {
61
65
  <VocalStackPlayer src="https://www.youtube.com/watch?v=QWCLiPOgeuw" />
62
66
  ```
63
67
 
68
+ Follow and drive it from your page:
69
+
70
+ ```tsx
71
+ const player = useRef<PlayerHandle>(null);
72
+ <VocalStackPlayer ref={player} id="r4m4srrrhi24" onPlayback={(s) => setAt(s.t)} />
73
+ <button onClick={() => player.current?.seek(42)}>Jump to 0:42</button>
74
+ ```
75
+
64
76
  Theme it by overriding the CSS variables on `.vsp`, for example `--vsp-radius`, `--brand` and `--vs-font-sans`.
65
77
 
66
78
  ## License
@@ -0,0 +1,19 @@
1
+ export interface ArchiveFile {
2
+ name?: string;
3
+ format?: string;
4
+ source?: string;
5
+ height?: string | number;
6
+ size?: string | number;
7
+ length?: string | number;
8
+ }
9
+ export declare function archiveVideoFile(id: string, meta: {
10
+ files?: ArchiveFile[];
11
+ metadata?: {
12
+ mediatype?: string;
13
+ };
14
+ } | null | undefined, want?: string | null): string | null;
15
+ export declare function archiveTarget(raw: string | null | undefined): {
16
+ id: string;
17
+ file: string | null;
18
+ } | null;
19
+ export declare function archiveSetup(id: string, file: string | null): (v: HTMLVideoElement, fail: () => void) => () => void;
@@ -0,0 +1,38 @@
1
+ export declare const DAILYMOTION_PLAYER = "x8lr5";
2
+ export declare function dailymotionPlayerId(id: string | null | undefined): string;
3
+ export declare function dailymotionLib(player?: string | null): string;
4
+ export declare function dailymotionFrame(video: string, at: {
5
+ t: number;
6
+ play: boolean;
7
+ player?: string | null;
8
+ }): string;
9
+ export interface DmState {
10
+ videoTime?: number;
11
+ playerIsPlaying?: boolean;
12
+ adIsPlaying?: boolean;
13
+ videoId?: string | null;
14
+ videoDuration?: number;
15
+ playerIsReplayScreen?: boolean;
16
+ playerIsMuted?: boolean;
17
+ playerVolume?: number;
18
+ playerIsBuffering?: boolean;
19
+ }
20
+ export type DmStep = {
21
+ kind: 'none';
22
+ } | {
23
+ kind: 'reload';
24
+ } | {
25
+ kind: 'play';
26
+ } | {
27
+ kind: 'pause';
28
+ } | {
29
+ kind: 'seek';
30
+ to: number;
31
+ };
32
+ export declare function dmStep(s: DmState, want: {
33
+ video: string;
34
+ t: number;
35
+ playing: boolean;
36
+ settling?: boolean;
37
+ }, over?: number): DmStep;
38
+ export declare function dmLoud(s: DmState | null | undefined): boolean;
@@ -0,0 +1,30 @@
1
+ export interface EmbedAt {
2
+ t: number;
3
+ play: boolean;
4
+ host?: string;
5
+ player?: string | null;
6
+ }
7
+ export declare function loomId(raw: string): string | null;
8
+ export declare function vimeoIds(raw: string): {
9
+ id: string;
10
+ h: string | null;
11
+ } | null;
12
+ export declare function dailymotionId(raw: string): string | null;
13
+ export declare function twitchTarget(raw: string): {
14
+ video?: string;
15
+ channel?: string;
16
+ clip?: string;
17
+ } | null;
18
+ export declare function embedUrl(raw: string, at: EmbedAt): string | null;
19
+ export declare function hasEmbed(raw: string | null | undefined): boolean;
20
+ export declare function urlFromEmbed(site: string | null | undefined, id: string | null | undefined): string | null;
21
+ export declare function sourceVideoUrl(src: {
22
+ kind?: string;
23
+ url?: string | null;
24
+ site?: string | null;
25
+ embedId?: string | null;
26
+ } | null | undefined): string | null;
27
+ export declare function linkVideoFile(raw: string | null | undefined): string | null;
28
+ export declare function wistiaId(raw: string): string | null;
29
+ export declare function vidyardId(raw: string): string | null;
30
+ export declare function stillThumb(url: string | null | undefined): string | null;
@@ -0,0 +1,26 @@
1
+ import { type VmState, type VmStep } from './vimeo';
2
+ export interface FbState extends VmState {
3
+ seen: number | null;
4
+ }
5
+ export declare const FB_TICK = 0.5;
6
+ export declare function fbState(): FbState;
7
+ export declare function fbSample(s: FbState, pos: number, now: number): void;
8
+ export declare function fbNow(s: FbState, now: number): number | null;
9
+ export declare function fbStep(s: FbState, want: {
10
+ t: number;
11
+ playing: boolean;
12
+ settling?: boolean;
13
+ lead?: number;
14
+ }, now: number, over?: number): VmStep;
15
+ export declare function fbFit(box: {
16
+ w: number;
17
+ h: number;
18
+ }, frame: {
19
+ w: number;
20
+ h: number;
21
+ }): {
22
+ scale: number;
23
+ w: number;
24
+ h: number;
25
+ };
26
+ export declare function fbWidth(box: number, screen: number): number;
@@ -0,0 +1,9 @@
1
+ export interface FindRow {
2
+ id: string;
3
+ text: string;
4
+ translations?: Record<string, string>;
5
+ }
6
+ export declare function findMatches(rows: FindRow[], q: string, lang?: string | null): number[];
7
+ export declare function stepMatch(at: number, total: number, dir: 1 | -1): number;
8
+ export declare function matchAt(rows: FindRow[], matches: number[], id: string | null): number;
9
+ export declare function findCount(at: number, total: number): string;
@@ -0,0 +1,5 @@
1
+ import type { FollowSetup } from '../ui/FileFollow';
2
+ export declare function loomStreamUrl(id: string): Promise<string | null>;
3
+ export declare function isPlaylist(url: string): boolean;
4
+ export declare function signedLoader(master: string): (xhr: XMLHttpRequest, u: string) => void;
5
+ export declare function loomSetup(id: string): FollowSetup;
@@ -0,0 +1,2 @@
1
+ export declare function shareCodeOf(raw: string): string | null;
2
+ export declare function playIdOf(id: string | null | undefined, withToken: boolean): string;
@@ -0,0 +1,13 @@
1
+ export type SiteId = 'youtube' | 'loom' | 'vimeo' | 'twitch' | 'facebook' | 'instagram' | 'dailymotion' | 'tiktok' | 'x' | 'soundcloud' | 'kick' | 'mixcloud' | 'bandcamp' | 'streamable' | 'ted' | 'linkedin' | 'archive' | 'odysee' | 'niconico' | 'vk' | 'bitchute' | 'wistia' | 'vidyard' | 'kaltura' | 'jwplayer' | 'pinterest' | 'bluesky' | 'gdrive' | 'spreaker' | 'iheart' | 'audioboom' | 'cnn';
2
+ export interface Site {
3
+ id: SiteId;
4
+ name: string;
5
+ color: string;
6
+ hosts: RegExp;
7
+ glyph: string;
8
+ audioOnly?: boolean;
9
+ }
10
+ export declare const SITES: Site[];
11
+ export declare function siteById(id: string | null | undefined): Site | null;
12
+ export declare function hostOfUrl(url: string | null | undefined): string | null;
13
+ export declare function siteOf(url: string | null | undefined): Site | null;
@@ -0,0 +1,12 @@
1
+ export interface Span {
2
+ wallStart: number;
3
+ wallEnd?: number | null;
4
+ mediaStart: number;
5
+ }
6
+ export interface Gap {
7
+ at: number;
8
+ shift: number;
9
+ }
10
+ export declare function spanGaps(spans: readonly Span[]): Gap[];
11
+ export declare function toStream(t: number, base: number, gaps: readonly Gap[]): number;
12
+ export declare function fromStream(y: number, base: number, gaps: readonly Gap[]): number;
@@ -0,0 +1,38 @@
1
+ export declare const VIMEO_ORIGIN = "https://player.vimeo.com";
2
+ export declare function vimeoFrame(id: string, at: {
3
+ t: number;
4
+ h?: string | null;
5
+ }): string;
6
+ export interface VimeoMsg {
7
+ event?: string;
8
+ method?: string;
9
+ value?: unknown;
10
+ data?: Record<string, unknown>;
11
+ }
12
+ export declare function vimeoMsg(origin: string, data: unknown): VimeoMsg | null;
13
+ export interface VmState {
14
+ t: number | null;
15
+ at: number;
16
+ playing: boolean;
17
+ buffering: boolean;
18
+ duration: number | null;
19
+ ended?: boolean;
20
+ }
21
+ export type VmStep = {
22
+ kind: 'none';
23
+ } | {
24
+ kind: 'play';
25
+ } | {
26
+ kind: 'pause';
27
+ } | {
28
+ kind: 'seek';
29
+ to: number;
30
+ };
31
+ export declare function vimeoNow(s: VmState, now: number): number | null;
32
+ export declare function vmStep(s: VmState, want: {
33
+ t: number;
34
+ playing: boolean;
35
+ settling?: boolean;
36
+ lead?: number;
37
+ }, now: number, over?: number): VmStep;
38
+ export declare function vimeoLoud(data: Record<string, unknown> | null | undefined): boolean;
@@ -1,8 +1,15 @@
1
+ export interface FollowWord {
2
+ start: number;
3
+ end: number;
4
+ text?: string;
5
+ }
1
6
  export interface FollowLine {
2
7
  sid: number;
3
8
  start: number;
4
9
  end: number;
10
+ words?: readonly FollowWord[];
5
11
  }
12
+ export type FollowTimes = Readonly<Record<string, readonly (readonly [number, number])[]>>;
6
13
  export interface FollowClip {
7
14
  src: string;
8
15
  part: number;
@@ -25,8 +32,10 @@ export type FollowTarget = {
25
32
  };
26
33
  export declare const FOLLOW_DRIFT_S = 0.5;
27
34
  export declare const FOLLOW_AHEAD = 3;
35
+ export declare const FOLLOW_JUMP_S = 1.5;
28
36
  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;
37
+ export declare function clipTimeAt(line: FollowLine, t: number, totalS: number | null, times?: readonly (readonly [number, number])[]): number;
38
+ export declare function followTarget(lines: readonly FollowLine[], clips: ReadonlyMap<number, readonly FollowClip[]>, t: number, times?: FollowTimes): FollowTarget;
30
39
  export declare function mayRunOn(lines: readonly FollowLine[], t: number, playingSid: number | null): boolean;
31
40
  export declare function upcomingSrcs(lines: readonly FollowLine[], clips: ReadonlyMap<number, readonly FollowClip[]>, t: number, n?: number): string[];
32
41
  export interface FollowState {
@@ -42,4 +51,5 @@ export declare function useVoiceFollow(o: {
42
51
  t: number;
43
52
  playing: boolean;
44
53
  muted: boolean;
54
+ times?: FollowTimes;
45
55
  }): FollowState;
@@ -0,0 +1,10 @@
1
+ export type VoiceWait = 'asked' | 'line' | null;
2
+ export declare function voiceWait(o: {
3
+ on: boolean;
4
+ want: boolean;
5
+ relang: boolean;
6
+ playing: boolean;
7
+ preparing: boolean;
8
+ starting: number | null | undefined;
9
+ }): VoiceWait;
10
+ export declare const VOICE_WAIT_TITLE = "Preparing the voice\u2026";
@@ -4,6 +4,7 @@ export interface Started {
4
4
  recordingId: string;
5
5
  token: string;
6
6
  expiresAt: string | null;
7
+ shareCode?: string | null;
7
8
  }
8
9
  export type PopupStatus = 'signing-in' | 'consent' | 'looking' | 'confirm' | 'checking' | 'starting';
9
10
  export declare function openPopup(appUrl: string | undefined, ask: {
@@ -11,7 +12,14 @@ export declare function openPopup(appUrl: string | undefined, ask: {
11
12
  transcription?: string;
12
13
  ask?: boolean;
13
14
  connect?: boolean;
15
+ tx?: {
16
+ voices: 'cloned' | 'synthetic';
17
+ spoken: string | null;
18
+ speakers: 'auto' | 'on' | 'off';
19
+ };
14
20
  }, onStatus?: (s: PopupStatus) => void): Promise<Started | 'connected' | null>;
15
21
  export declare function startFromEmbed(appUrl: string | undefined, url: string, onStatus?: (s: PopupStatus) => void): Promise<Started | null>;
16
22
  export declare function wasConnected(appUrl: string | undefined): boolean;
17
23
  export declare function rememberConnected(appUrl: string | undefined): void;
24
+ export declare function rememberedCode(link: string): string | null;
25
+ export declare function rememberCode(link: string, code: string | null): void;
@@ -51,8 +51,14 @@ export interface ApiOptions {
51
51
  }
52
52
  export declare function useApi(o: ApiOptions): PlayerApi;
53
53
  export declare function withMedia(api: PlayerApi, media: string | null): PlayerApi;
54
- export declare function loadSource(api: PlayerApi, id: string): Promise<PlayerSource>;
55
- export declare function useSource(api: PlayerApi, id: string): {
54
+ export declare function isLiveRecording(r: Pick<Recording, 'kind' | 'state'> | null | undefined): boolean;
55
+ export declare function streamOffsetS(ingest: {
56
+ mediaAt?: string | null;
57
+ streamStartedAt?: string | null;
58
+ } | null | undefined): number;
59
+ export declare function liveJob(recording: Recording, url: string | null | undefined): TranscriptionJob | null;
60
+ export declare function loadSource(api: PlayerApi, id: string, recordingId?: string | null): Promise<PlayerSource>;
61
+ export declare function useSource(api: PlayerApi, id: string, recordingId?: string | null): {
56
62
  source: PlayerSource | null;
57
63
  gone: boolean;
58
64
  error: ErrorLike | null;
@@ -3,6 +3,7 @@ export interface ErrorLike {
3
3
  code?: string;
4
4
  status?: number;
5
5
  details?: any;
6
+ requestId?: string;
6
7
  }
7
8
  export declare const GENERIC: string;
8
9
  export declare const OFFLINE = "Can't reach VocalStack. Check your connection.";
@@ -0,0 +1,8 @@
1
+ export declare function useYtTitle(ytId: string | null): string | null;
2
+ export declare function displayName(parts: {
3
+ name?: string | null;
4
+ sourceName?: string | null;
5
+ ytTitle?: string | null;
6
+ url?: string | null;
7
+ id: string;
8
+ }): string;
@@ -67,7 +67,7 @@ export declare function IconButton({ children, onClick, label, size, variant, bo
67
67
  active?: boolean;
68
68
  title?: string;
69
69
  }): import("react").JSX.Element;
70
- export declare function LanguageChip({ flag, code, label, onClick, variant, block, bordered, size, style }: {
70
+ export declare function LanguageChip({ flag, code, label, onClick, variant, block, bordered, size, style, flagOnly }: {
71
71
  flag: ReactNode;
72
72
  code: string;
73
73
  label?: string;
@@ -77,6 +77,7 @@ export declare function LanguageChip({ flag, code, label, onClick, variant, bloc
77
77
  bordered?: boolean;
78
78
  size?: 'sm';
79
79
  style?: React.CSSProperties;
80
+ flagOnly?: boolean;
80
81
  }): import("react").JSX.Element;
81
82
  export declare function CopyButton({ value, label, onCopied }: {
82
83
  value: string;
@@ -14,6 +14,7 @@ export declare const D: {
14
14
  chevronRight: string;
15
15
  chevronLeft: string;
16
16
  chevronDown: string;
17
+ chevronUp: string;
17
18
  external: string;
18
19
  arrowLeft: string;
19
20
  arrowRight: string;
@@ -12,13 +12,14 @@ export interface LanguageListProps {
12
12
  languages: PickerLanguage[];
13
13
  searchPlaceholder?: string;
14
14
  none?: string;
15
+ noneNote?: string;
15
16
  pinned?: string[];
16
17
  recent?: string[];
17
18
  requireVoice?: boolean;
18
19
  keepOpen?: boolean;
19
20
  busy?: string | null;
20
21
  }
21
- export declare function useLanguageList({ open, onClose, value, onSelect, languages, searchPlaceholder, none, pinned, recent, requireVoice, keepOpen, busy }: LanguageListProps & {
22
+ export declare function useLanguageList({ open, onClose, value, onSelect, languages, searchPlaceholder, none, noneNote, pinned, recent, requireVoice, keepOpen, busy }: LanguageListProps & {
22
23
  open: boolean;
23
24
  onClose: () => void;
24
25
  }): {
package/dist/index.d.ts CHANGED
@@ -1,12 +1,15 @@
1
1
  import './styles.css';
2
- export { VocalStackPlayer, type VocalStackPlayerProps, type PlayerSettings, type PlayerControls } from './ui/VocalStackPlayer';
2
+ export { VocalStackPlayer, type VocalStackPlayerProps, type PlayerSettings, type PlayerControls, type PlayerHandle, type PlaybackState } from './ui/VocalStackPlayer';
3
3
  export type { EndCardOptions } from './ui/EndCard';
4
4
  export { PlayerApiProvider, usePlayerApi, useApi, type PlayerApi, type PlayerApiProviderProps, type ApiOptions, type PlayerSource, type TokenSource, type Listen } from './data/context';
5
5
  export type { ErrorLike } from './data/errors';
6
6
  export { setErrorReporter, type MediaCred } from './core/audio';
7
7
  export { useTranscript } from './data/transcript';
8
- export { useTxPlayer, useTxVoice, useDuck, useFlash, useYtLead, useFindPull, YtFollow, MuteButton, TxLines, TxFind, lineWords, spokenWordOf, pictureT, lineEnd, PAUSE_D, PLAY_D, NO_SEEK, PUB_SIDE, type TxPlayer, type YtLead, type VoiceSheetHooks, type VoiceSheetCtx, type NoCloneNote } from './ui/core';
8
+ export { useTxPlayer, useTxVoice, useDuck, useFlash, useYtLead, useFindPull, type FindState, YtFollow, MuteButton, TxLines, TxFind, lineWords, spokenWordOf, pictureT, lineEnd, PAUSE_D, PLAY_D, NO_SEEK, PUB_SIDE, type TxPlayer, type YtLead, type VoiceSheetHooks, type VoiceSheetCtx, type NoCloneNote } from './ui/core';
9
9
  export { Transport, ReplayScrub, ExportPanel, SummaryPanel, SpeakerCast, VoiceSheetBody, useSummaryIn, useViewportTranslation, useArchiveVoice, useVoiceCatalogue, type AvailableVoice, type CastMember, type SummaryState } from './ui/shared';
10
10
  export { FullVideo, MiniPlayer, PanelSeek, browserFull, realFull, setFullTarget, type PlayerPos, type PlayerTransport, type VoicesBtn } from './ui/full';
11
11
  export { useBackgroundBed, useSeparatedTrack, bedNote, trackPlan, REMOVE_BG_LABEL, REMOVE_BG_NOTE, type BedState, type TrackPlan, type Separated } from './core/background';
12
12
  export { snapPosition, placePosition, type PlayPos } from './core/playPosition';
13
+ export { SITES, siteOf, siteById, hostOfUrl, type Site, type SiteId } from './core/sites';
14
+ export { SiteIcon } from './ui/SiteIcon';
15
+ export { hasEmbed, linkVideoFile, sourceVideoUrl } from './core/embeds';