@xhub-reels/sdk 0.1.11 → 0.1.13
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.
- package/dist/index.cjs +74 -18
- package/dist/index.js +74 -18
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -1364,9 +1364,18 @@ function mapHlsError(data) {
|
|
|
1364
1364
|
}
|
|
1365
1365
|
function useHls(options) {
|
|
1366
1366
|
const { src, videoRef, isActive, isPrefetch, bufferTier = "active", hlsConfig, onError } = options;
|
|
1367
|
-
const
|
|
1368
|
-
const
|
|
1369
|
-
|
|
1367
|
+
const [isHlsJs, setIsHlsJs] = react.useState(false);
|
|
1368
|
+
const [isNativeHls, setIsNativeHls] = react.useState(false);
|
|
1369
|
+
react.useEffect(() => {
|
|
1370
|
+
const hlsSupported = Hls__default.default.isSupported();
|
|
1371
|
+
const native = supportsNativeHls();
|
|
1372
|
+
setIsHlsJs(hlsSupported && !native);
|
|
1373
|
+
setIsNativeHls(native);
|
|
1374
|
+
}, []);
|
|
1375
|
+
const isHlsJsRef = react.useRef(false);
|
|
1376
|
+
const isNativeRef = react.useRef(false);
|
|
1377
|
+
isHlsJsRef.current = isHlsJs;
|
|
1378
|
+
isNativeRef.current = isNativeHls;
|
|
1370
1379
|
const [isReady, setIsReady] = react.useState(false);
|
|
1371
1380
|
const hlsRef = react.useRef(null);
|
|
1372
1381
|
const onErrorRef = react.useRef(onError);
|
|
@@ -1391,6 +1400,8 @@ function useHls(options) {
|
|
|
1391
1400
|
currentSrcRef.current = void 0;
|
|
1392
1401
|
return;
|
|
1393
1402
|
}
|
|
1403
|
+
const isNative = isNativeRef.current;
|
|
1404
|
+
const isHlsSupported = isHlsJsRef.current;
|
|
1394
1405
|
if (!isActive && !isPrefetch) {
|
|
1395
1406
|
if (isNative) {
|
|
1396
1407
|
if (video.src) {
|
|
@@ -1417,6 +1428,9 @@ function useHls(options) {
|
|
|
1417
1428
|
video.addEventListener("canplay", handleCanPlayReuse, { once: true });
|
|
1418
1429
|
video.addEventListener("loadeddata", handleCanPlayReuse, { once: true });
|
|
1419
1430
|
video.addEventListener("playing", handleCanPlayReuse, { once: true });
|
|
1431
|
+
if (isActive && video.readyState < HTMLMediaElement.HAVE_FUTURE_DATA) {
|
|
1432
|
+
video.load();
|
|
1433
|
+
}
|
|
1420
1434
|
return () => {
|
|
1421
1435
|
video.removeEventListener("canplay", handleCanPlayReuse);
|
|
1422
1436
|
video.removeEventListener("loadeddata", handleCanPlayReuse);
|
|
@@ -1441,7 +1455,6 @@ function useHls(options) {
|
|
|
1441
1455
|
};
|
|
1442
1456
|
}
|
|
1443
1457
|
if (!isHlsSupported) {
|
|
1444
|
-
onErrorRef.current?.("UNKNOWN", "HLS playback not supported in this browser");
|
|
1445
1458
|
return;
|
|
1446
1459
|
}
|
|
1447
1460
|
if (hlsRef.current && currentSrcRef.current === src) {
|
|
@@ -1505,7 +1518,7 @@ function useHls(options) {
|
|
|
1505
1518
|
currentSrcRef.current = void 0;
|
|
1506
1519
|
}
|
|
1507
1520
|
};
|
|
1508
|
-
}, [src, isActive, isPrefetch]);
|
|
1521
|
+
}, [src, isActive, isPrefetch, isHlsJs, isNativeHls]);
|
|
1509
1522
|
react.useEffect(() => {
|
|
1510
1523
|
const hls = hlsRef.current;
|
|
1511
1524
|
if (!hls) {
|
|
@@ -1524,7 +1537,7 @@ function useHls(options) {
|
|
|
1524
1537
|
}, [bufferTier]);
|
|
1525
1538
|
return {
|
|
1526
1539
|
isHlsJs,
|
|
1527
|
-
isNativeHls
|
|
1540
|
+
isNativeHls,
|
|
1528
1541
|
isReady,
|
|
1529
1542
|
destroy
|
|
1530
1543
|
};
|
|
@@ -1769,24 +1782,47 @@ function VideoSlotInner({
|
|
|
1769
1782
|
const prevMuted = video.muted;
|
|
1770
1783
|
video.muted = true;
|
|
1771
1784
|
let cancelled = false;
|
|
1785
|
+
let rafId = null;
|
|
1786
|
+
let vfcHandle = null;
|
|
1787
|
+
const pauseAfterDecode = () => {
|
|
1788
|
+
if (cancelled) return;
|
|
1789
|
+
video.pause();
|
|
1790
|
+
video.currentTime = 0;
|
|
1791
|
+
video.muted = prevMuted;
|
|
1792
|
+
setHasPlayedAhead(true);
|
|
1793
|
+
};
|
|
1772
1794
|
const doPlayAhead = async () => {
|
|
1773
1795
|
try {
|
|
1774
1796
|
await video.play();
|
|
1775
1797
|
if (cancelled) return;
|
|
1776
|
-
|
|
1777
|
-
|
|
1778
|
-
|
|
1779
|
-
|
|
1780
|
-
|
|
1781
|
-
|
|
1782
|
-
|
|
1783
|
-
|
|
1798
|
+
if ("requestVideoFrameCallback" in video) {
|
|
1799
|
+
vfcHandle = video.requestVideoFrameCallback(() => {
|
|
1800
|
+
vfcHandle = null;
|
|
1801
|
+
pauseAfterDecode();
|
|
1802
|
+
});
|
|
1803
|
+
} else {
|
|
1804
|
+
rafId = requestAnimationFrame(() => {
|
|
1805
|
+
rafId = requestAnimationFrame(() => {
|
|
1806
|
+
rafId = null;
|
|
1807
|
+
pauseAfterDecode();
|
|
1808
|
+
});
|
|
1809
|
+
});
|
|
1810
|
+
}
|
|
1784
1811
|
} catch {
|
|
1812
|
+
video.muted = prevMuted;
|
|
1785
1813
|
}
|
|
1786
1814
|
};
|
|
1787
1815
|
doPlayAhead();
|
|
1788
1816
|
return () => {
|
|
1789
1817
|
cancelled = true;
|
|
1818
|
+
if (rafId !== null) {
|
|
1819
|
+
cancelAnimationFrame(rafId);
|
|
1820
|
+
rafId = null;
|
|
1821
|
+
}
|
|
1822
|
+
if (vfcHandle !== null && "cancelVideoFrameCallback" in video) {
|
|
1823
|
+
video.cancelVideoFrameCallback(vfcHandle);
|
|
1824
|
+
vfcHandle = null;
|
|
1825
|
+
}
|
|
1790
1826
|
};
|
|
1791
1827
|
}, [canPlayAhead, isActive, isReady, hasPlayedAhead]);
|
|
1792
1828
|
react.useEffect(() => {
|
|
@@ -1797,6 +1833,7 @@ function VideoSlotInner({
|
|
|
1797
1833
|
const video = videoRef.current;
|
|
1798
1834
|
if (!video) return;
|
|
1799
1835
|
let onReady = null;
|
|
1836
|
+
let fallbackTimerId = null;
|
|
1800
1837
|
if (isActive) {
|
|
1801
1838
|
wasActiveRef.current = true;
|
|
1802
1839
|
const startPlay = () => {
|
|
@@ -1806,6 +1843,10 @@ function VideoSlotInner({
|
|
|
1806
1843
|
video.removeEventListener("playing", onReady);
|
|
1807
1844
|
onReady = null;
|
|
1808
1845
|
}
|
|
1846
|
+
if (fallbackTimerId !== null) {
|
|
1847
|
+
clearTimeout(fallbackTimerId);
|
|
1848
|
+
fallbackTimerId = null;
|
|
1849
|
+
}
|
|
1809
1850
|
video.muted = true;
|
|
1810
1851
|
video.play().then(() => {
|
|
1811
1852
|
video.muted = isMuted;
|
|
@@ -1820,9 +1861,15 @@ function VideoSlotInner({
|
|
|
1820
1861
|
video.addEventListener("canplay", onReady, { once: true });
|
|
1821
1862
|
video.addEventListener("loadeddata", onReady, { once: true });
|
|
1822
1863
|
video.addEventListener("playing", onReady, { once: true });
|
|
1823
|
-
if (
|
|
1864
|
+
if (isNativeHls && video.src && video.readyState < HTMLMediaElement.HAVE_FUTURE_DATA) {
|
|
1824
1865
|
video.load();
|
|
1825
1866
|
}
|
|
1867
|
+
fallbackTimerId = window.setTimeout(() => {
|
|
1868
|
+
fallbackTimerId = null;
|
|
1869
|
+
if (onReady) {
|
|
1870
|
+
startPlay();
|
|
1871
|
+
}
|
|
1872
|
+
}, 3e3);
|
|
1826
1873
|
}
|
|
1827
1874
|
} else if (wasActiveRef.current) {
|
|
1828
1875
|
video.pause();
|
|
@@ -1838,13 +1885,21 @@ function VideoSlotInner({
|
|
|
1838
1885
|
video.removeEventListener("loadeddata", onReady);
|
|
1839
1886
|
video.removeEventListener("playing", onReady);
|
|
1840
1887
|
}
|
|
1888
|
+
if (fallbackTimerId !== null) {
|
|
1889
|
+
clearTimeout(fallbackTimerId);
|
|
1890
|
+
fallbackTimerId = null;
|
|
1891
|
+
}
|
|
1841
1892
|
};
|
|
1842
1893
|
}, [isActive, isMuted, hasPlayedAhead, isNativeHls]);
|
|
1843
1894
|
react.useEffect(() => {
|
|
1844
1895
|
const video = videoRef.current;
|
|
1845
1896
|
if (!video) return;
|
|
1846
|
-
|
|
1847
|
-
|
|
1897
|
+
if (isActive) {
|
|
1898
|
+
video.muted = isMuted;
|
|
1899
|
+
} else {
|
|
1900
|
+
video.muted = true;
|
|
1901
|
+
}
|
|
1902
|
+
}, [isMuted, isActive]);
|
|
1848
1903
|
const [isActuallyPlaying, setIsActuallyPlaying] = react.useState(false);
|
|
1849
1904
|
react.useEffect(() => {
|
|
1850
1905
|
const video = videoRef.current;
|
|
@@ -1922,8 +1977,9 @@ function VideoSlotInner({
|
|
|
1922
1977
|
ref: videoRef,
|
|
1923
1978
|
src: mp4Src,
|
|
1924
1979
|
loop: true,
|
|
1925
|
-
muted:
|
|
1980
|
+
muted: true,
|
|
1926
1981
|
playsInline: true,
|
|
1982
|
+
autoPlay: isActive,
|
|
1927
1983
|
preload: shouldLoadSrc ? "auto" : "none",
|
|
1928
1984
|
style: {
|
|
1929
1985
|
width: "100%",
|
package/dist/index.js
CHANGED
|
@@ -1358,9 +1358,18 @@ function mapHlsError(data) {
|
|
|
1358
1358
|
}
|
|
1359
1359
|
function useHls(options) {
|
|
1360
1360
|
const { src, videoRef, isActive, isPrefetch, bufferTier = "active", hlsConfig, onError } = options;
|
|
1361
|
-
const
|
|
1362
|
-
const
|
|
1363
|
-
|
|
1361
|
+
const [isHlsJs, setIsHlsJs] = useState(false);
|
|
1362
|
+
const [isNativeHls, setIsNativeHls] = useState(false);
|
|
1363
|
+
useEffect(() => {
|
|
1364
|
+
const hlsSupported = Hls.isSupported();
|
|
1365
|
+
const native = supportsNativeHls();
|
|
1366
|
+
setIsHlsJs(hlsSupported && !native);
|
|
1367
|
+
setIsNativeHls(native);
|
|
1368
|
+
}, []);
|
|
1369
|
+
const isHlsJsRef = useRef(false);
|
|
1370
|
+
const isNativeRef = useRef(false);
|
|
1371
|
+
isHlsJsRef.current = isHlsJs;
|
|
1372
|
+
isNativeRef.current = isNativeHls;
|
|
1364
1373
|
const [isReady, setIsReady] = useState(false);
|
|
1365
1374
|
const hlsRef = useRef(null);
|
|
1366
1375
|
const onErrorRef = useRef(onError);
|
|
@@ -1385,6 +1394,8 @@ function useHls(options) {
|
|
|
1385
1394
|
currentSrcRef.current = void 0;
|
|
1386
1395
|
return;
|
|
1387
1396
|
}
|
|
1397
|
+
const isNative = isNativeRef.current;
|
|
1398
|
+
const isHlsSupported = isHlsJsRef.current;
|
|
1388
1399
|
if (!isActive && !isPrefetch) {
|
|
1389
1400
|
if (isNative) {
|
|
1390
1401
|
if (video.src) {
|
|
@@ -1411,6 +1422,9 @@ function useHls(options) {
|
|
|
1411
1422
|
video.addEventListener("canplay", handleCanPlayReuse, { once: true });
|
|
1412
1423
|
video.addEventListener("loadeddata", handleCanPlayReuse, { once: true });
|
|
1413
1424
|
video.addEventListener("playing", handleCanPlayReuse, { once: true });
|
|
1425
|
+
if (isActive && video.readyState < HTMLMediaElement.HAVE_FUTURE_DATA) {
|
|
1426
|
+
video.load();
|
|
1427
|
+
}
|
|
1414
1428
|
return () => {
|
|
1415
1429
|
video.removeEventListener("canplay", handleCanPlayReuse);
|
|
1416
1430
|
video.removeEventListener("loadeddata", handleCanPlayReuse);
|
|
@@ -1435,7 +1449,6 @@ function useHls(options) {
|
|
|
1435
1449
|
};
|
|
1436
1450
|
}
|
|
1437
1451
|
if (!isHlsSupported) {
|
|
1438
|
-
onErrorRef.current?.("UNKNOWN", "HLS playback not supported in this browser");
|
|
1439
1452
|
return;
|
|
1440
1453
|
}
|
|
1441
1454
|
if (hlsRef.current && currentSrcRef.current === src) {
|
|
@@ -1499,7 +1512,7 @@ function useHls(options) {
|
|
|
1499
1512
|
currentSrcRef.current = void 0;
|
|
1500
1513
|
}
|
|
1501
1514
|
};
|
|
1502
|
-
}, [src, isActive, isPrefetch]);
|
|
1515
|
+
}, [src, isActive, isPrefetch, isHlsJs, isNativeHls]);
|
|
1503
1516
|
useEffect(() => {
|
|
1504
1517
|
const hls = hlsRef.current;
|
|
1505
1518
|
if (!hls) {
|
|
@@ -1518,7 +1531,7 @@ function useHls(options) {
|
|
|
1518
1531
|
}, [bufferTier]);
|
|
1519
1532
|
return {
|
|
1520
1533
|
isHlsJs,
|
|
1521
|
-
isNativeHls
|
|
1534
|
+
isNativeHls,
|
|
1522
1535
|
isReady,
|
|
1523
1536
|
destroy
|
|
1524
1537
|
};
|
|
@@ -1763,24 +1776,47 @@ function VideoSlotInner({
|
|
|
1763
1776
|
const prevMuted = video.muted;
|
|
1764
1777
|
video.muted = true;
|
|
1765
1778
|
let cancelled = false;
|
|
1779
|
+
let rafId = null;
|
|
1780
|
+
let vfcHandle = null;
|
|
1781
|
+
const pauseAfterDecode = () => {
|
|
1782
|
+
if (cancelled) return;
|
|
1783
|
+
video.pause();
|
|
1784
|
+
video.currentTime = 0;
|
|
1785
|
+
video.muted = prevMuted;
|
|
1786
|
+
setHasPlayedAhead(true);
|
|
1787
|
+
};
|
|
1766
1788
|
const doPlayAhead = async () => {
|
|
1767
1789
|
try {
|
|
1768
1790
|
await video.play();
|
|
1769
1791
|
if (cancelled) return;
|
|
1770
|
-
|
|
1771
|
-
|
|
1772
|
-
|
|
1773
|
-
|
|
1774
|
-
|
|
1775
|
-
|
|
1776
|
-
|
|
1777
|
-
|
|
1792
|
+
if ("requestVideoFrameCallback" in video) {
|
|
1793
|
+
vfcHandle = video.requestVideoFrameCallback(() => {
|
|
1794
|
+
vfcHandle = null;
|
|
1795
|
+
pauseAfterDecode();
|
|
1796
|
+
});
|
|
1797
|
+
} else {
|
|
1798
|
+
rafId = requestAnimationFrame(() => {
|
|
1799
|
+
rafId = requestAnimationFrame(() => {
|
|
1800
|
+
rafId = null;
|
|
1801
|
+
pauseAfterDecode();
|
|
1802
|
+
});
|
|
1803
|
+
});
|
|
1804
|
+
}
|
|
1778
1805
|
} catch {
|
|
1806
|
+
video.muted = prevMuted;
|
|
1779
1807
|
}
|
|
1780
1808
|
};
|
|
1781
1809
|
doPlayAhead();
|
|
1782
1810
|
return () => {
|
|
1783
1811
|
cancelled = true;
|
|
1812
|
+
if (rafId !== null) {
|
|
1813
|
+
cancelAnimationFrame(rafId);
|
|
1814
|
+
rafId = null;
|
|
1815
|
+
}
|
|
1816
|
+
if (vfcHandle !== null && "cancelVideoFrameCallback" in video) {
|
|
1817
|
+
video.cancelVideoFrameCallback(vfcHandle);
|
|
1818
|
+
vfcHandle = null;
|
|
1819
|
+
}
|
|
1784
1820
|
};
|
|
1785
1821
|
}, [canPlayAhead, isActive, isReady, hasPlayedAhead]);
|
|
1786
1822
|
useEffect(() => {
|
|
@@ -1791,6 +1827,7 @@ function VideoSlotInner({
|
|
|
1791
1827
|
const video = videoRef.current;
|
|
1792
1828
|
if (!video) return;
|
|
1793
1829
|
let onReady = null;
|
|
1830
|
+
let fallbackTimerId = null;
|
|
1794
1831
|
if (isActive) {
|
|
1795
1832
|
wasActiveRef.current = true;
|
|
1796
1833
|
const startPlay = () => {
|
|
@@ -1800,6 +1837,10 @@ function VideoSlotInner({
|
|
|
1800
1837
|
video.removeEventListener("playing", onReady);
|
|
1801
1838
|
onReady = null;
|
|
1802
1839
|
}
|
|
1840
|
+
if (fallbackTimerId !== null) {
|
|
1841
|
+
clearTimeout(fallbackTimerId);
|
|
1842
|
+
fallbackTimerId = null;
|
|
1843
|
+
}
|
|
1803
1844
|
video.muted = true;
|
|
1804
1845
|
video.play().then(() => {
|
|
1805
1846
|
video.muted = isMuted;
|
|
@@ -1814,9 +1855,15 @@ function VideoSlotInner({
|
|
|
1814
1855
|
video.addEventListener("canplay", onReady, { once: true });
|
|
1815
1856
|
video.addEventListener("loadeddata", onReady, { once: true });
|
|
1816
1857
|
video.addEventListener("playing", onReady, { once: true });
|
|
1817
|
-
if (
|
|
1858
|
+
if (isNativeHls && video.src && video.readyState < HTMLMediaElement.HAVE_FUTURE_DATA) {
|
|
1818
1859
|
video.load();
|
|
1819
1860
|
}
|
|
1861
|
+
fallbackTimerId = window.setTimeout(() => {
|
|
1862
|
+
fallbackTimerId = null;
|
|
1863
|
+
if (onReady) {
|
|
1864
|
+
startPlay();
|
|
1865
|
+
}
|
|
1866
|
+
}, 3e3);
|
|
1820
1867
|
}
|
|
1821
1868
|
} else if (wasActiveRef.current) {
|
|
1822
1869
|
video.pause();
|
|
@@ -1832,13 +1879,21 @@ function VideoSlotInner({
|
|
|
1832
1879
|
video.removeEventListener("loadeddata", onReady);
|
|
1833
1880
|
video.removeEventListener("playing", onReady);
|
|
1834
1881
|
}
|
|
1882
|
+
if (fallbackTimerId !== null) {
|
|
1883
|
+
clearTimeout(fallbackTimerId);
|
|
1884
|
+
fallbackTimerId = null;
|
|
1885
|
+
}
|
|
1835
1886
|
};
|
|
1836
1887
|
}, [isActive, isMuted, hasPlayedAhead, isNativeHls]);
|
|
1837
1888
|
useEffect(() => {
|
|
1838
1889
|
const video = videoRef.current;
|
|
1839
1890
|
if (!video) return;
|
|
1840
|
-
|
|
1841
|
-
|
|
1891
|
+
if (isActive) {
|
|
1892
|
+
video.muted = isMuted;
|
|
1893
|
+
} else {
|
|
1894
|
+
video.muted = true;
|
|
1895
|
+
}
|
|
1896
|
+
}, [isMuted, isActive]);
|
|
1842
1897
|
const [isActuallyPlaying, setIsActuallyPlaying] = useState(false);
|
|
1843
1898
|
useEffect(() => {
|
|
1844
1899
|
const video = videoRef.current;
|
|
@@ -1916,8 +1971,9 @@ function VideoSlotInner({
|
|
|
1916
1971
|
ref: videoRef,
|
|
1917
1972
|
src: mp4Src,
|
|
1918
1973
|
loop: true,
|
|
1919
|
-
muted:
|
|
1974
|
+
muted: true,
|
|
1920
1975
|
playsInline: true,
|
|
1976
|
+
autoPlay: isActive,
|
|
1921
1977
|
preload: shouldLoadSrc ? "auto" : "none",
|
|
1922
1978
|
style: {
|
|
1923
1979
|
width: "100%",
|