@bendyline/squisq-react 2.4.3 → 2.4.5
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.
|
@@ -1540,10 +1540,19 @@ function buildSegmentTitleMap(doc) {
|
|
|
1540
1540
|
|
|
1541
1541
|
// src/docPlayer/renderReadiness.ts
|
|
1542
1542
|
var DEFAULT_VIDEO_FRAME_TIMEOUT_MS = 2e3;
|
|
1543
|
+
var VIDEO_FRAME_READINESS_POLL_MS = 16;
|
|
1543
1544
|
var VIDEO_TIME_TOLERANCE_SECONDS = 0.01;
|
|
1544
1545
|
function formatMediaTime(time) {
|
|
1545
1546
|
return Number.isFinite(time) ? `${time.toFixed(3)}s` : String(time);
|
|
1546
1547
|
}
|
|
1548
|
+
function reachableMediaTime(video, targetTime) {
|
|
1549
|
+
const duration = video.duration;
|
|
1550
|
+
if (!Number.isFinite(duration)) return targetTime;
|
|
1551
|
+
return Math.max(0, Math.min(targetTime, duration));
|
|
1552
|
+
}
|
|
1553
|
+
function isAtReachableMediaTime(video, targetTime) {
|
|
1554
|
+
return Math.abs(video.currentTime - reachableMediaTime(video, targetTime)) <= VIDEO_TIME_TOLERANCE_SECONDS;
|
|
1555
|
+
}
|
|
1547
1556
|
function isVisiblyPresented(video) {
|
|
1548
1557
|
if (!video.isConnected) return false;
|
|
1549
1558
|
const view = video.ownerDocument.defaultView;
|
|
@@ -1558,13 +1567,14 @@ function isVisiblyPresented(video) {
|
|
|
1558
1567
|
}
|
|
1559
1568
|
function seekVideoToFrame(video, targetTime, timeoutMs = DEFAULT_VIDEO_FRAME_TIMEOUT_MS) {
|
|
1560
1569
|
video.pause();
|
|
1561
|
-
const alreadyReady = !video.seeking && video.readyState >= HTMLMediaElement.HAVE_CURRENT_DATA &&
|
|
1570
|
+
const alreadyReady = !video.seeking && video.readyState >= HTMLMediaElement.HAVE_CURRENT_DATA && isAtReachableMediaTime(video, targetTime);
|
|
1562
1571
|
if (alreadyReady) return Promise.resolve();
|
|
1563
1572
|
return new Promise((resolve, reject) => {
|
|
1564
1573
|
let settled = false;
|
|
1565
1574
|
let videoFrameRequest = null;
|
|
1566
1575
|
const cleanup = () => {
|
|
1567
1576
|
clearTimeout(timeout);
|
|
1577
|
+
clearInterval(readinessPoll);
|
|
1568
1578
|
video.removeEventListener("seeked", handleMediaReady);
|
|
1569
1579
|
video.removeEventListener("loadeddata", handleMediaReady);
|
|
1570
1580
|
video.removeEventListener("canplay", handleMediaReady);
|
|
@@ -1584,12 +1594,14 @@ function seekVideoToFrame(video, targetTime, timeoutMs = DEFAULT_VIDEO_FRAME_TIM
|
|
|
1584
1594
|
cleanup();
|
|
1585
1595
|
reject(
|
|
1586
1596
|
new Error(
|
|
1587
|
-
`Video frame did not become ready at ${formatMediaTime(targetTime)} within ${timeoutMs}ms (currentTime=${formatMediaTime(video.currentTime)}, readyState=${video.readyState}, seeking=${String(video.seeking)}, visible=${String(isVisiblyPresented(video))}).`
|
|
1597
|
+
`Video frame did not become ready at ${formatMediaTime(targetTime)} within ${timeoutMs}ms (currentTime=${formatMediaTime(video.currentTime)}, reachableTime=${formatMediaTime(reachableMediaTime(video, targetTime))}, duration=${formatMediaTime(video.duration)}, readyState=${video.readyState}, seeking=${String(video.seeking)}, visible=${String(isVisiblyPresented(video))}).`
|
|
1588
1598
|
)
|
|
1589
1599
|
);
|
|
1590
1600
|
};
|
|
1591
1601
|
const requestPresentedFrame = () => {
|
|
1592
|
-
if (settled || video.seeking || video.readyState < HTMLMediaElement.HAVE_CURRENT_DATA)
|
|
1602
|
+
if (settled || video.seeking || video.readyState < HTMLMediaElement.HAVE_CURRENT_DATA || !isAtReachableMediaTime(video, targetTime)) {
|
|
1603
|
+
return;
|
|
1604
|
+
}
|
|
1593
1605
|
if (typeof video.requestVideoFrameCallback !== "function" || !isVisiblyPresented(video)) {
|
|
1594
1606
|
finish();
|
|
1595
1607
|
return;
|
|
@@ -1604,11 +1616,12 @@ function seekVideoToFrame(video, targetTime, timeoutMs = DEFAULT_VIDEO_FRAME_TIM
|
|
|
1604
1616
|
requestPresentedFrame();
|
|
1605
1617
|
}
|
|
1606
1618
|
const timeout = setTimeout(fail, timeoutMs);
|
|
1619
|
+
const readinessPoll = setInterval(requestPresentedFrame, VIDEO_FRAME_READINESS_POLL_MS);
|
|
1607
1620
|
video.addEventListener("seeked", handleMediaReady);
|
|
1608
1621
|
video.addEventListener("loadeddata", handleMediaReady);
|
|
1609
1622
|
video.addEventListener("canplay", handleMediaReady);
|
|
1610
1623
|
try {
|
|
1611
|
-
video.currentTime = targetTime;
|
|
1624
|
+
video.currentTime = reachableMediaTime(video, targetTime);
|
|
1612
1625
|
queueMicrotask(requestPresentedFrame);
|
|
1613
1626
|
} catch (error) {
|
|
1614
1627
|
settled = true;
|
package/dist/index.js
CHANGED