@mottosports/motto-video-player 1.0.1-rc.17 → 1.0.1-rc.19

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.js CHANGED
@@ -1743,8 +1743,9 @@ var import_react8 = require("react");
1743
1743
  var useLiveBadge = (playerRef, options = {}) => {
1744
1744
  const [isLive, setIsLive] = (0, import_react8.useState)(false);
1745
1745
  const [isVisible, setIsVisible] = (0, import_react8.useState)(false);
1746
+ const [isNearLiveEdge, setIsNearLiveEdge] = (0, import_react8.useState)(false);
1746
1747
  const intervalRef = (0, import_react8.useRef)(null);
1747
- const { enabled = true, onLiveStateChange } = options;
1748
+ const { enabled = true, onLiveStateChange, liveThresholdSeconds = 15 } = options;
1748
1749
  const checkLiveStatus = () => {
1749
1750
  if (!playerRef.current || !enabled) {
1750
1751
  return;
@@ -1763,11 +1764,30 @@ var useLiveBadge = (playerRef, options = {}) => {
1763
1764
  return;
1764
1765
  }
1765
1766
  const liveStatus = timeline.isLive();
1767
+ let nearLiveEdge = false;
1768
+ if (liveStatus) {
1769
+ try {
1770
+ const seekRange = player.getSeekRange();
1771
+ const videoElement = player.getMediaElement();
1772
+ if (seekRange && videoElement) {
1773
+ const liveEdge = seekRange.end;
1774
+ const currentTime = videoElement.currentTime;
1775
+ const timeBehindLive = liveEdge - currentTime;
1776
+ nearLiveEdge = timeBehindLive <= liveThresholdSeconds;
1777
+ }
1778
+ } catch (error) {
1779
+ console.error("Error checking live edge position:", error);
1780
+ nearLiveEdge = liveStatus;
1781
+ }
1782
+ }
1766
1783
  if (liveStatus !== isLive) {
1767
1784
  setIsLive(liveStatus);
1768
- setIsVisible(liveStatus);
1769
1785
  onLiveStateChange?.(liveStatus);
1770
1786
  }
1787
+ if (nearLiveEdge !== isNearLiveEdge) {
1788
+ setIsNearLiveEdge(nearLiveEdge);
1789
+ setIsVisible(nearLiveEdge);
1790
+ }
1771
1791
  } catch (error) {
1772
1792
  if (error instanceof Error && !error.message.includes("not a function")) {
1773
1793
  console.error("Error checking live status:", error);
@@ -1778,17 +1798,18 @@ var useLiveBadge = (playerRef, options = {}) => {
1778
1798
  if (!enabled) {
1779
1799
  setIsLive(false);
1780
1800
  setIsVisible(false);
1801
+ setIsNearLiveEdge(false);
1781
1802
  return;
1782
1803
  }
1783
1804
  checkLiveStatus();
1784
- intervalRef.current = setInterval(checkLiveStatus, 2e3);
1805
+ intervalRef.current = setInterval(checkLiveStatus, 1e3);
1785
1806
  return () => {
1786
1807
  if (intervalRef.current) {
1787
1808
  clearInterval(intervalRef.current);
1788
1809
  intervalRef.current = null;
1789
1810
  }
1790
1811
  };
1791
- }, [enabled, playerRef.current]);
1812
+ }, [enabled, playerRef.current, liveThresholdSeconds]);
1792
1813
  (0, import_react8.useEffect)(() => {
1793
1814
  return () => {
1794
1815
  if (intervalRef.current) {
@@ -1801,6 +1822,7 @@ var useLiveBadge = (playerRef, options = {}) => {
1801
1822
  return {
1802
1823
  isLive,
1803
1824
  isVisible,
1825
+ isNearLiveEdge,
1804
1826
  hideBadge,
1805
1827
  showBadge,
1806
1828
  checkLiveStatus
@@ -1812,16 +1834,48 @@ var import_react9 = require("react");
1812
1834
 
1813
1835
  // src/hooks/useLiveIndicator.ts
1814
1836
  var import_react10 = require("react");
1815
- var useLiveIndicator = (containerRef, options = {}) => {
1837
+ var useLiveIndicator = (containerRef, playerRef, options = {}) => {
1816
1838
  const observerRef = (0, import_react10.useRef)(null);
1839
+ const intervalRef = (0, import_react10.useRef)(null);
1817
1840
  const {
1818
1841
  enabled = true,
1819
1842
  indicatorColor = "#ff0000",
1820
1843
  indicatorSize = 8,
1821
- showPulseAnimation = true
1844
+ showPulseAnimation = true,
1845
+ liveThresholdSeconds = 15
1822
1846
  } = options;
1847
+ const isNearLiveEdge = (player) => {
1848
+ if (!player) return false;
1849
+ try {
1850
+ if (!player.getManifest || !player.getPresentationTimeline || typeof player.getPresentationTimeline !== "function") {
1851
+ return false;
1852
+ }
1853
+ const manifest = player.getManifest();
1854
+ if (!manifest) {
1855
+ return false;
1856
+ }
1857
+ const timeline = player.getPresentationTimeline();
1858
+ if (!timeline || typeof timeline.isLive !== "function") {
1859
+ return false;
1860
+ }
1861
+ const liveStatus = timeline.isLive();
1862
+ if (!liveStatus) return false;
1863
+ const seekRange = player.getSeekRange();
1864
+ const videoElement = player.getMediaElement();
1865
+ if (seekRange && videoElement) {
1866
+ const liveEdge = seekRange.end;
1867
+ const currentTime = videoElement.currentTime;
1868
+ const timeBehindLive = liveEdge - currentTime;
1869
+ return timeBehindLive <= liveThresholdSeconds;
1870
+ }
1871
+ return false;
1872
+ } catch (error) {
1873
+ console.error("Error checking live edge position in indicator:", error);
1874
+ return false;
1875
+ }
1876
+ };
1823
1877
  (0, import_react10.useEffect)(() => {
1824
- if (!containerRef.current || !enabled) {
1878
+ if (!containerRef.current || !playerRef.current || !enabled) {
1825
1879
  return;
1826
1880
  }
1827
1881
  const addLiveIndicator = (currentTimeElement) => {
@@ -1852,7 +1906,7 @@ var useLiveIndicator = (containerRef, options = {}) => {
1852
1906
  const currentTimeElements = containerRef.current?.querySelectorAll(".shaka-current-time");
1853
1907
  currentTimeElements?.forEach((element) => {
1854
1908
  const textContent = element.textContent?.trim() || "";
1855
- if (textContent.toLowerCase().includes("live")) {
1909
+ if (textContent.toLowerCase().includes("live") && isNearLiveEdge(playerRef.current)) {
1856
1910
  addLiveIndicator(element);
1857
1911
  } else {
1858
1912
  removeLiveIndicator(element);
@@ -1860,6 +1914,7 @@ var useLiveIndicator = (containerRef, options = {}) => {
1860
1914
  });
1861
1915
  };
1862
1916
  checkForLiveContent();
1917
+ intervalRef.current = setInterval(checkForLiveContent, 1e3);
1863
1918
  observerRef.current = new MutationObserver((mutations) => {
1864
1919
  let shouldCheck = false;
1865
1920
  mutations.forEach((mutation) => {
@@ -1889,15 +1944,18 @@ var useLiveIndicator = (containerRef, options = {}) => {
1889
1944
  if (observerRef.current) {
1890
1945
  observerRef.current.disconnect();
1891
1946
  }
1947
+ if (intervalRef.current) {
1948
+ clearInterval(intervalRef.current);
1949
+ }
1892
1950
  };
1893
- }, [containerRef, enabled, indicatorColor, indicatorSize, showPulseAnimation]);
1951
+ }, [containerRef, playerRef, enabled, indicatorColor, indicatorSize, showPulseAnimation, liveThresholdSeconds]);
1894
1952
  return {
1895
1953
  // Expose method to manually trigger check if needed
1896
1954
  checkForLiveContent: () => {
1897
1955
  const currentTimeElements = containerRef.current?.querySelectorAll(".shaka-current-time");
1898
1956
  currentTimeElements?.forEach((element) => {
1899
1957
  const textContent = element.textContent?.trim() || "";
1900
- if (textContent.toLowerCase().includes("live")) {
1958
+ if (textContent.toLowerCase().includes("live") && isNearLiveEdge(playerRef.current)) {
1901
1959
  }
1902
1960
  });
1903
1961
  }
@@ -3207,15 +3265,17 @@ var Player = (0, import_react12.forwardRef)(
3207
3265
  );
3208
3266
  const { isLive, isVisible: isLiveBadgeVisible } = useLiveBadge(playerRef, {
3209
3267
  enabled: true,
3268
+ liveThresholdSeconds: 15,
3210
3269
  onLiveStateChange: (isLive2) => {
3211
3270
  events?.onLiveStateChange?.(isLive2);
3212
3271
  }
3213
3272
  });
3214
- useLiveIndicator(containerRef, {
3273
+ useLiveIndicator(containerRef, playerRef, {
3215
3274
  enabled: true,
3216
3275
  indicatorColor: "#ff0000",
3217
3276
  indicatorSize: 8,
3218
- showPulseAnimation: true
3277
+ showPulseAnimation: true,
3278
+ liveThresholdSeconds: 15
3219
3279
  });
3220
3280
  const initializeAds = () => {
3221
3281
  if (!imaConfig || !playerRef.current || !videoRef.current) return;
@@ -3335,7 +3395,7 @@ var Player = (0, import_react12.forwardRef)(
3335
3395
  const containerStyle = isResponsive ? {
3336
3396
  aspectRatio: aspectRatio.toString()
3337
3397
  } : { width, height };
3338
- const videoClasses = isResponsive ? "motto-video-responsive" : "w-full h-full ";
3398
+ const videoClasses = isResponsive ? "motto-video-responsive w-full" : "w-full h-full ";
3339
3399
  const videoStyle = isResponsive ? {} : { width, height };
3340
3400
  const filteredVideoProps = { ...videoProps };
3341
3401
  delete filteredVideoProps.controls;