@bendyline/squisq-react 2.4.6 → 2.4.7

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.
@@ -9,7 +9,7 @@ import {
9
9
  TreeLayer,
10
10
  VideoLayer,
11
11
  getTransitionClass
12
- } from "./chunk-TI5X7SBC.js";
12
+ } from "./chunk-MKWVJYUS.js";
13
13
  import {
14
14
  useAutoSurface
15
15
  } from "./chunk-TT6ENR6T.js";
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  BlockRenderer,
3
3
  LinearDocView
4
- } from "./chunk-ICM7AWQT.js";
4
+ } from "./chunk-3HYSWEKG.js";
5
5
  import {
6
6
  useAudioSync,
7
7
  useDocPlayback,
@@ -165,7 +165,7 @@ function MediaClipElement({
165
165
  return;
166
166
  }
167
167
  const target = Math.max(0, clip.sourceIn + (currentTime - clip.absoluteStart));
168
- if (renderMode || !isPlaying || Math.abs(el.currentTime - target) > DRIFT) {
168
+ if (el.dataset.captureSequential !== "true" && (renderMode || !isPlaying || Math.abs(el.currentTime - target) > DRIFT)) {
169
169
  try {
170
170
  el.currentTime = target;
171
171
  } catch {
@@ -175,7 +175,7 @@ function MediaClipElement({
175
175
  const p = el.play();
176
176
  if (p) p.catch(() => {
177
177
  });
178
- } else {
178
+ } else if (el.dataset.captureSequential !== "true") {
179
179
  el.pause();
180
180
  }
181
181
  }, [active, currentTime, isPlaying, renderMode, clip.sourceIn, clip.absoluteStart, src]);
@@ -1542,6 +1542,8 @@ function buildSegmentTitleMap(doc) {
1542
1542
  var DEFAULT_VIDEO_FRAME_TIMEOUT_MS = 2e3;
1543
1543
  var VIDEO_FRAME_READINESS_POLL_MS = 16;
1544
1544
  var VIDEO_TIME_TOLERANCE_SECONDS = 0.01;
1545
+ var MAX_SEQUENTIAL_CAPTURE_STEP_SECONDS = 0.5;
1546
+ var SEQUENTIAL_CAPTURE_PLAYBACK_RATE = 1;
1545
1547
  function formatMediaTime(time) {
1546
1548
  return Number.isFinite(time) ? `${time.toFixed(3)}s` : String(time);
1547
1549
  }
@@ -1565,10 +1567,8 @@ function isVisiblyPresented(video) {
1565
1567
  }
1566
1568
  return true;
1567
1569
  }
1568
- function seekVideoToFrame(video, targetTime, timeoutMs = DEFAULT_VIDEO_FRAME_TIMEOUT_MS) {
1570
+ function seekVideoByAssignment(video, targetTime, timeoutMs = DEFAULT_VIDEO_FRAME_TIMEOUT_MS) {
1569
1571
  video.pause();
1570
- const alreadyReady = !video.seeking && video.readyState >= HTMLMediaElement.HAVE_CURRENT_DATA && isAtReachableMediaTime(video, targetTime);
1571
- if (alreadyReady) return Promise.resolve();
1572
1572
  return new Promise((resolve, reject) => {
1573
1573
  let settled = false;
1574
1574
  let videoFrameRequest = null;
@@ -1630,6 +1630,125 @@ function seekVideoToFrame(video, targetTime, timeoutMs = DEFAULT_VIDEO_FRAME_TIM
1630
1630
  }
1631
1631
  });
1632
1632
  }
1633
+ function advanceSequentialCaptureVideo(video, targetTime, timeoutMs) {
1634
+ return new Promise((resolve, reject) => {
1635
+ let settled = false;
1636
+ let timeout = null;
1637
+ const ownerDocument = video.ownerDocument;
1638
+ const isInactive = () => ownerDocument.visibilityState !== "visible";
1639
+ const clearWatchdog = () => {
1640
+ if (timeout === null) return;
1641
+ clearTimeout(timeout);
1642
+ timeout = null;
1643
+ };
1644
+ const cleanup = () => {
1645
+ clearWatchdog();
1646
+ clearInterval(readinessPoll);
1647
+ video.removeEventListener("timeupdate", check);
1648
+ video.removeEventListener("loadeddata", check);
1649
+ video.removeEventListener("canplay", check);
1650
+ video.removeEventListener("error", fail);
1651
+ ownerDocument.removeEventListener("visibilitychange", handleVisibilityChange);
1652
+ };
1653
+ const finish = () => {
1654
+ if (!settled) {
1655
+ settled = true;
1656
+ cleanup();
1657
+ resolve();
1658
+ }
1659
+ };
1660
+ const fallbackToSeek = () => {
1661
+ if (settled) return;
1662
+ settled = true;
1663
+ video.pause();
1664
+ cleanup();
1665
+ void seekVideoByAssignment(video, targetTime, timeoutMs).then(resolve, reject);
1666
+ };
1667
+ const fail = () => {
1668
+ if (settled) return;
1669
+ settled = true;
1670
+ video.pause();
1671
+ cleanup();
1672
+ reject(
1673
+ new Error(
1674
+ `Video frame did not advance to ${formatMediaTime(targetTime)} within ${timeoutMs}ms (currentTime=${formatMediaTime(video.currentTime)}, readyState=${video.readyState}).`
1675
+ )
1676
+ );
1677
+ };
1678
+ function check() {
1679
+ if (video.readyState >= HTMLMediaElement.HAVE_CURRENT_DATA && video.currentTime >= reachableMediaTime(video, targetTime)) {
1680
+ video.pause();
1681
+ finish();
1682
+ }
1683
+ }
1684
+ const handlePlaybackFailure = () => {
1685
+ if (settled || isInactive()) return;
1686
+ fallbackToSeek();
1687
+ };
1688
+ const startPlayback = () => {
1689
+ if (settled || isInactive()) return;
1690
+ try {
1691
+ video.playbackRate = SEQUENTIAL_CAPTURE_PLAYBACK_RATE;
1692
+ if (video.paused) {
1693
+ void video.play().catch(handlePlaybackFailure);
1694
+ }
1695
+ } catch {
1696
+ handlePlaybackFailure();
1697
+ }
1698
+ };
1699
+ const armWatchdog = () => {
1700
+ clearWatchdog();
1701
+ if (settled || isInactive()) return;
1702
+ timeout = setTimeout(fail, timeoutMs);
1703
+ };
1704
+ const pauseWhileInactive = () => {
1705
+ video.pause();
1706
+ clearWatchdog();
1707
+ };
1708
+ const resumeWhenActive = () => {
1709
+ if (settled || isInactive()) return;
1710
+ check();
1711
+ if (settled) return;
1712
+ startPlayback();
1713
+ armWatchdog();
1714
+ };
1715
+ function handleVisibilityChange() {
1716
+ if (ownerDocument.visibilityState !== "visible") {
1717
+ pauseWhileInactive();
1718
+ return;
1719
+ }
1720
+ resumeWhenActive();
1721
+ }
1722
+ const readinessPoll = setInterval(check, VIDEO_FRAME_READINESS_POLL_MS);
1723
+ video.addEventListener("timeupdate", check);
1724
+ video.addEventListener("loadeddata", check);
1725
+ video.addEventListener("canplay", check);
1726
+ video.addEventListener("error", fail, { once: true });
1727
+ ownerDocument.addEventListener("visibilitychange", handleVisibilityChange);
1728
+ resumeWhenActive();
1729
+ });
1730
+ }
1731
+ function seekVideoToFrame(video, targetTime, timeoutMs = DEFAULT_VIDEO_FRAME_TIMEOUT_MS) {
1732
+ if (video.readyState >= HTMLMediaElement.HAVE_METADATA && video.videoWidth <= 0 && video.videoHeight <= 0) {
1733
+ video.pause();
1734
+ return Promise.resolve();
1735
+ }
1736
+ const reachableTargetTime = reachableMediaTime(video, targetTime);
1737
+ const step = reachableTargetTime - video.currentTime;
1738
+ if (video.dataset.captureSequential === "true") {
1739
+ if (video.readyState >= HTMLMediaElement.HAVE_CURRENT_DATA && step <= VIDEO_TIME_TOLERANCE_SECONDS) {
1740
+ if (step < -VIDEO_TIME_TOLERANCE_SECONDS) video.pause();
1741
+ return Promise.resolve();
1742
+ }
1743
+ if (step > 0 && step <= MAX_SEQUENTIAL_CAPTURE_STEP_SECONDS && video.readyState >= HTMLMediaElement.HAVE_CURRENT_DATA) {
1744
+ return advanceSequentialCaptureVideo(video, targetTime, timeoutMs);
1745
+ }
1746
+ }
1747
+ video.pause();
1748
+ const alreadyReady = !video.seeking && video.readyState >= HTMLMediaElement.HAVE_CURRENT_DATA && isAtReachableMediaTime(video, targetTime);
1749
+ if (alreadyReady) return Promise.resolve();
1750
+ return seekVideoByAssignment(video, targetTime, timeoutMs);
1751
+ }
1633
1752
 
1634
1753
  // src/DocPlayer.tsx
1635
1754
  import { jsx as jsx7, jsxs as jsxs4 } from "react/jsx-runtime";
@@ -1296,7 +1296,7 @@ function VideoLayer({
1296
1296
  const video = videoRef.current;
1297
1297
  if (!video || !hasStartedRef.current) return;
1298
1298
  const targetTime = gated ? content.clipStart : Math.min(content.clipEnd, content.clipStart + Math.max(0, blockTime - startAt));
1299
- if (Math.abs(video.currentTime - targetTime) > VIDEO_SYNC_DRIFT_SECONDS) {
1299
+ if (video.dataset.captureSequential !== "true" && Math.abs(video.currentTime - targetTime) > VIDEO_SYNC_DRIFT_SECONDS) {
1300
1300
  video.currentTime = targetTime;
1301
1301
  }
1302
1302
  if (gated) {
@@ -1313,7 +1313,7 @@ function VideoLayer({
1313
1313
  playPromise.catch(() => {
1314
1314
  });
1315
1315
  }
1316
- } else {
1316
+ } else if (video.dataset.captureSequential !== "true") {
1317
1317
  video.pause();
1318
1318
  }
1319
1319
  }, [isPlaying, gated, blockTime, startAt, src, content.clipStart, content.clipEnd]);
package/dist/index.js CHANGED
@@ -12,7 +12,7 @@ import {
12
12
  formatTime,
13
13
  resolveDocPlayerAppearance,
14
14
  useMediaClipDurations
15
- } from "./chunk-7CDO336T.js";
15
+ } from "./chunk-KF4DTT46.js";
16
16
  import {
17
17
  BlockRenderer,
18
18
  CanvasSection,
@@ -20,7 +20,7 @@ import {
20
20
  PageSectionView,
21
21
  PageViewContext,
22
22
  usePageView
23
- } from "./chunk-ICM7AWQT.js";
23
+ } from "./chunk-3HYSWEKG.js";
24
24
  import {
25
25
  ImageLayer,
26
26
  MapLayer,
@@ -33,7 +33,7 @@ import {
33
33
  VideoLayer,
34
34
  getAnimationStyle,
35
35
  getTransitionClass
36
- } from "./chunk-TI5X7SBC.js";
36
+ } from "./chunk-MKWVJYUS.js";
37
37
  import {
38
38
  useModalDialog
39
39
  } from "./chunk-65POMKHR.js";
@@ -8,7 +8,7 @@ import {
8
8
  TextLayer,
9
9
  TreeLayer,
10
10
  VideoLayer
11
- } from "../chunk-TI5X7SBC.js";
11
+ } from "../chunk-MKWVJYUS.js";
12
12
  import "../chunk-WLUZTUNZ.js";
13
13
  import "../chunk-LR3AIGDD.js";
14
14
  export {
@@ -4,8 +4,8 @@ import {
4
4
  PageSectionView,
5
5
  PageViewContext,
6
6
  usePageView
7
- } from "../chunk-ICM7AWQT.js";
8
- import "../chunk-TI5X7SBC.js";
7
+ } from "../chunk-3HYSWEKG.js";
8
+ import "../chunk-MKWVJYUS.js";
9
9
  import "../chunk-TT6ENR6T.js";
10
10
  import "../chunk-VMPQEUJH.js";
11
11
  import "../chunk-WLUZTUNZ.js";
@@ -10,11 +10,11 @@ import {
10
10
  MediaClipLayer,
11
11
  SocialCaptionOverlay,
12
12
  formatTime
13
- } from "../chunk-7CDO336T.js";
13
+ } from "../chunk-KF4DTT46.js";
14
14
  import {
15
15
  BlockRenderer
16
- } from "../chunk-ICM7AWQT.js";
17
- import "../chunk-TI5X7SBC.js";
16
+ } from "../chunk-3HYSWEKG.js";
17
+ import "../chunk-MKWVJYUS.js";
18
18
  import "../chunk-BOZJ655L.js";
19
19
  import "../chunk-TT6ENR6T.js";
20
20
  import {