@vanillaskyai/video 0.10.1 → 0.10.3

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 (38) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/README.md +12 -7
  3. package/dist/check-runtime.js +2 -2
  4. package/dist/{chunk-6KZGF63O.js → chunk-3U2F7C7C.js} +53 -34
  5. package/dist/{chunk-5C6HZNHY.js → chunk-LJR5VLEI.js} +3 -2
  6. package/dist/{chunk-77VY4O7A.js → chunk-SI6CFFAA.js} +57 -10
  7. package/dist/{chunk-KHLO5OHT.js → chunk-UCXQORDZ.js} +1 -1
  8. package/dist/{chunk-VQH3JTQC.js → chunk-VVNZCY2U.js} +1 -1
  9. package/dist/{chunk-TVIU23OM.js → chunk-YZZSWGC3.js} +8 -3
  10. package/dist/{cinema-media-APDJS7SC.js → cinema-media-4JUYKPQI.js} +4 -4
  11. package/dist/{comparison-ZVE2DE7U.js → comparison-3QLMUC5V.js} +4 -4
  12. package/dist/{editorial-timeline-YIXXVJUV.js → editorial-timeline-IVE2P25N.js} +4 -4
  13. package/dist/{key-figure-I2C37FWV.js → key-figure-APD56LCO.js} +4 -4
  14. package/dist/{mobile-message-JSGBU6EX.js → mobile-message-WLK3WY5B.js} +4 -4
  15. package/dist/{quote-XH54G3FS.js → quote-Z6YET5BO.js} +4 -4
  16. package/dist/react.js +52 -19
  17. package/dist/{scene-video-backdrop-PCTARAAJ.js → scene-video-backdrop-OWUXPXHZ.js} +2 -2
  18. package/dist/server.js +333 -276
  19. package/docs/agent-integration.md +5 -4
  20. package/docs/getting-started.md +7 -5
  21. package/docs/media-and-audio.md +23 -17
  22. package/docs/production.md +7 -4
  23. package/docs/prompt-and-input.md +24 -15
  24. package/docs/provider-integration.md +2 -2
  25. package/docs/reference/protocol.md +7 -1
  26. package/docs/reference/provider-adapters.md +5 -3
  27. package/docs/testing.md +7 -2
  28. package/package.json +1 -1
  29. package/registry/items/backgrounds.json +2 -2
  30. package/registry/items/cinemaMedia.json +1 -1
  31. package/registry/items/comparison.json +1 -1
  32. package/registry/items/editorialTimeline.json +1 -1
  33. package/registry/items/keyFigure.json +1 -1
  34. package/registry/items/mobileMessage.json +1 -1
  35. package/registry/items/quote.json +1 -1
  36. package/starters/video-chat/README.md +18 -17
  37. package/starters/video-chat/package.json +1 -1
  38. package/starters/video-chat/providers/video.ts +5 -4
package/dist/react.js CHANGED
@@ -40,9 +40,9 @@ import {
40
40
  VideoFrame,
41
41
  getDimensions,
42
42
  sceneReadinessKey
43
- } from "./chunk-6KZGF63O.js";
43
+ } from "./chunk-3U2F7C7C.js";
44
44
  import "./chunk-224QNWRA.js";
45
- import "./chunk-TVIU23OM.js";
45
+ import "./chunk-YZZSWGC3.js";
46
46
  import {
47
47
  getVideoDuration,
48
48
  resolveVideoTimeline
@@ -94,13 +94,13 @@ import { createElement } from "react";
94
94
 
95
95
  // src/visual-system/catalog/builtin-loaders.generated.ts
96
96
  var GENERATED_BUILTIN_TEMPLATE_LOADERS = {
97
- "cinemaMedia": () => import("./cinema-media-APDJS7SC.js").then((module) => ({ default: module.MediaSceneTemplate })),
97
+ "cinemaMedia": () => import("./cinema-media-4JUYKPQI.js").then((module) => ({ default: module.MediaSceneTemplate })),
98
98
  "chapterTitle": () => import("./chapter-title-YRLIQY3V.js").then((module) => ({ default: module.TitleSceneTemplate })),
99
- "editorialTimeline": () => import("./editorial-timeline-YIXXVJUV.js").then((module) => ({ default: module.TimelineSceneTemplate })),
100
- "mobileMessage": () => import("./mobile-message-JSGBU6EX.js").then((module) => ({ default: module.NotificationSceneTemplate })),
101
- "comparison": () => import("./comparison-ZVE2DE7U.js").then((module) => ({ default: module.ComparisonSceneTemplate })),
102
- "quote": () => import("./quote-XH54G3FS.js").then((module) => ({ default: module.QuoteSceneTemplate })),
103
- "keyFigure": () => import("./key-figure-I2C37FWV.js").then((module) => ({ default: module.KeyFigureSceneTemplate }))
99
+ "editorialTimeline": () => import("./editorial-timeline-IVE2P25N.js").then((module) => ({ default: module.TimelineSceneTemplate })),
100
+ "mobileMessage": () => import("./mobile-message-WLK3WY5B.js").then((module) => ({ default: module.NotificationSceneTemplate })),
101
+ "comparison": () => import("./comparison-3QLMUC5V.js").then((module) => ({ default: module.ComparisonSceneTemplate })),
102
+ "quote": () => import("./quote-Z6YET5BO.js").then((module) => ({ default: module.QuoteSceneTemplate })),
103
+ "keyFigure": () => import("./key-figure-APD56LCO.js").then((module) => ({ default: module.KeyFigureSceneTemplate }))
104
104
  };
105
105
 
106
106
  // src/visual-system/catalog/builtin-player.generated.ts
@@ -754,6 +754,14 @@ function VideoPlayerRuntime({
754
754
  }
755
755
  }, []);
756
756
  const playbackEndedRef = useRef(false);
757
+ let mediaPlaying = isPlaying;
758
+ if (sceneIndexRef.current >= 0) {
759
+ try {
760
+ mediaPlaying = isPlaying && narrationReady?.() !== false;
761
+ } catch {
762
+ mediaPlaying = false;
763
+ }
764
+ }
757
765
  stateRef.current = state;
758
766
  timeRef.current = currentTime;
759
767
  callbacksRef.current = { onComplete, onPlaybackEnd, onError, onSceneChange, narrationReady, narrationTime, onFramePresented, onMediaFramePresented, onStallChange, onStateChange };
@@ -1131,7 +1139,8 @@ function VideoPlayerRuntime({
1131
1139
  time: showStartPoster ? posterTime : currentTime,
1132
1140
  width: dimensions.width,
1133
1141
  height: dimensions.height,
1134
- playing: isPlaying,
1142
+ playing: mediaPlaying,
1143
+ preparingNarration: isPlaying && !mediaPlaying,
1135
1144
  mediaAudioMuted: !nativeMediaAudio || isMuted,
1136
1145
  mediaAudioVolume: nativeMediaVolume,
1137
1146
  style: {
@@ -1243,7 +1252,7 @@ var VideoError = class extends Error {
1243
1252
  function recoverSceneMedia(scene) {
1244
1253
  if (scene.templateId === "cinemaMedia") {
1245
1254
  const title = scene.variables.fallbackText;
1246
- if (typeof title !== "string" || !title.trim() || [...title].length > 65) return void 0;
1255
+ if (typeof title !== "string" || !title.trim() || [...title].length > 65) return { ...scene, variables: { mediaType: "video", mediaUrl: "" } };
1247
1256
  return { ...scene, templateId: "chapterTitle", variables: { title: title.trim() } };
1248
1257
  }
1249
1258
  if (!["comparison", "editorialTimeline", "quote", "keyFigure"].includes(scene.templateId)) return void 0;
@@ -1397,7 +1406,11 @@ function useNarration(options) {
1397
1406
  if (!optionsRef.current.voice.getCurrentTime) return void 0;
1398
1407
  const time = currentRef.current ? optionsRef.current.voice.getCurrentTime() : void 0;
1399
1408
  if (currentRef.current && readyRef.current && time === void 0) return void 0;
1400
- if (time !== void 0 && Number.isFinite(time)) clockRef.current = Math.min(group?.totalSeconds ?? Infinity, Math.max(group?.offsetSeconds ?? 0, time));
1409
+ if (time !== void 0 && Number.isFinite(time)) {
1410
+ const end = group?.totalSeconds ?? scene.timing.fixedDuration ?? Infinity;
1411
+ const limit = currentRef.current ? Math.max(0, end - 0.01) : end;
1412
+ clockRef.current = Math.min(limit, Math.max(group?.offsetSeconds ?? 0, time));
1413
+ }
1401
1414
  return clockRef.current;
1402
1415
  }, []);
1403
1416
  const isReady = useCallback(() => optionsRef.current.enabled === false || readyRef.current || clockRef.current !== void 0 && clockRef.current >= (groupRef.current?.offsetSeconds ?? 0) + 0.04, []);
@@ -1550,6 +1563,8 @@ function createVideoChatVoice(options = {}) {
1550
1563
  const lines = /* @__PURE__ */ new Map();
1551
1564
  const pendingLoads = /* @__PURE__ */ new Set();
1552
1565
  let sounding;
1566
+ let generatedElement;
1567
+ let stopGenerated;
1553
1568
  let browserFinish;
1554
1569
  let held = false;
1555
1570
  let silent = false;
@@ -1674,7 +1689,12 @@ function createVideoChatVoice(options = {}) {
1674
1689
  },
1675
1690
  resume() {
1676
1691
  held = false;
1677
- if (sounding) void sounding.play().catch(() => playbackFailure?.());
1692
+ if (sounding) {
1693
+ const fail = playbackFailure;
1694
+ void sounding.play().catch(() => {
1695
+ if (!held) fail?.();
1696
+ });
1697
+ }
1678
1698
  if (!silent) globalThis.speechSynthesis?.resume();
1679
1699
  },
1680
1700
  setMuted(muted) {
@@ -1753,9 +1773,11 @@ function createVideoChatVoice(options = {}) {
1753
1773
  }
1754
1774
  let playbackFailed = false;
1755
1775
  try {
1756
- const element = new Audio(line.src);
1776
+ stopGenerated?.();
1777
+ const element = generatedElement ??= new Audio();
1778
+ element.src = line.src;
1757
1779
  element.muted = silent;
1758
- if (offsetSeconds !== void 0) element.currentTime = offsetSeconds;
1780
+ element.currentTime = offsetSeconds ?? 0;
1759
1781
  sounding = element;
1760
1782
  await new Promise((resolve) => {
1761
1783
  let finished = false;
@@ -1771,6 +1793,7 @@ function createVideoChatVoice(options = {}) {
1771
1793
  element.onplaying = null;
1772
1794
  element.onended = null;
1773
1795
  element.onerror = null;
1796
+ if (stopGenerated === stop) stopGenerated = void 0;
1774
1797
  if (sounding === element) {
1775
1798
  sounding = void 0;
1776
1799
  playbackFailure = void 0;
@@ -1778,13 +1801,17 @@ function createVideoChatVoice(options = {}) {
1778
1801
  resolve();
1779
1802
  };
1780
1803
  const stop = () => {
1804
+ if (finished) return;
1781
1805
  element.pause();
1782
1806
  finish();
1783
1807
  };
1784
1808
  const fail = () => {
1785
- playbackFailed = true;
1786
- stop();
1809
+ if (!finished) {
1810
+ playbackFailed = true;
1811
+ stop();
1812
+ }
1787
1813
  };
1814
+ stopGenerated = stop;
1788
1815
  const clearWatchdog = watchSpeech(Math.max(line.seconds, estimatedBrowserSeconds(text)), fail);
1789
1816
  speechStops.add(stop);
1790
1817
  playbackFailure = fail;
@@ -1799,7 +1826,9 @@ function createVideoChatVoice(options = {}) {
1799
1826
  element.onerror = fail;
1800
1827
  signal.addEventListener("abort", stop, { once: true });
1801
1828
  try {
1802
- if (!held) void element.play().catch(fail);
1829
+ if (!held) void element.play().catch(() => {
1830
+ if (!held) fail();
1831
+ });
1803
1832
  } catch {
1804
1833
  fail();
1805
1834
  }
@@ -1825,6 +1854,11 @@ function createVideoChatVoice(options = {}) {
1825
1854
  speechStops.clear();
1826
1855
  sounding?.pause();
1827
1856
  sounding = void 0;
1857
+ generatedElement?.pause();
1858
+ generatedElement?.removeAttribute?.("src");
1859
+ generatedElement?.load?.();
1860
+ generatedElement = void 0;
1861
+ stopGenerated = void 0;
1828
1862
  stopBrowser();
1829
1863
  for (const line of lines.values()) {
1830
1864
  if (line.source === "generated") URL.revokeObjectURL(line.src);
@@ -3346,8 +3380,7 @@ function VideoChat({ options = {}, className, welcomeTitle, showRecoveryNotice =
3346
3380
  const sessionOrientation = options.orientation ?? viewportOrientation;
3347
3381
  const { chat, restoreSession } = useVideoChatSession({
3348
3382
  ...options,
3349
- orientation: sessionOrientation,
3350
- style: { generatedLook: "Natural light, restrained camera movement, documentary realism, consistent natural color. No embedded text.", ...options.style }
3383
+ orientation: sessionOrientation
3351
3384
  });
3352
3385
  const instanceId = useId();
3353
3386
  const historyId = `${instanceId}-history`;
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  SceneVideoBackdrop
3
- } from "./chunk-77VY4O7A.js";
4
- import "./chunk-TVIU23OM.js";
3
+ } from "./chunk-SI6CFFAA.js";
4
+ import "./chunk-YZZSWGC3.js";
5
5
  export {
6
6
  SceneVideoBackdrop
7
7
  };