@mottosports/motto-video-player 1.0.1-rc.32 → 1.0.1-rc.33

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.mjs CHANGED
@@ -374,6 +374,9 @@ styleInject(`/*! tailwindcss v4.1.8 | MIT License | https://tailwindcss.com */
374
374
  .grid {
375
375
  display: grid;
376
376
  }
377
+ .hidden {
378
+ display: none;
379
+ }
377
380
  .aspect-video {
378
381
  aspect-ratio: var(--aspect-video);
379
382
  }
@@ -1103,7 +1106,7 @@ styleInject(`/*! tailwindcss v4.1.8 | MIT License | https://tailwindcss.com */
1103
1106
  `);
1104
1107
 
1105
1108
  // src/Player.tsx
1106
- import { forwardRef, useEffect as useEffect5, useRef as useRef8, useImperativeHandle } from "react";
1109
+ import { forwardRef, useEffect as useEffect5, useRef as useRef8, useImperativeHandle, useMemo } from "react";
1107
1110
  import shaka3 from "shaka-player/dist/shaka-player.ui";
1108
1111
 
1109
1112
  // src/hooks/useShakePlayer.ts
@@ -1137,7 +1140,7 @@ var isPlayReadySupported = () => {
1137
1140
  import initShakaPlayerMux from "@mux/mux-data-shakaplayer";
1138
1141
 
1139
1142
  // package.json
1140
- var version = "1.0.1-rc.32";
1143
+ var version = "1.0.1-rc.33";
1141
1144
 
1142
1145
  // src/hooks/useShakePlayer.ts
1143
1146
  var useShakePlayer = ({
@@ -1151,33 +1154,57 @@ var useShakePlayer = ({
1151
1154
  onMuxDataUpdate
1152
1155
  }) => {
1153
1156
  const playerRef = useRef(null);
1157
+ const isDestroyingRef = useRef(false);
1154
1158
  const initializePlayer = useCallback(async (video) => {
1159
+ console.log("\u{1F3AC} PLAYER-INIT: Starting player initialization...");
1160
+ const startTime = performance.now();
1155
1161
  try {
1162
+ console.log("\u{1F3AC} PLAYER-INIT: Installing polyfills...");
1156
1163
  shaka.polyfill.installAll();
1164
+ console.log("\u{1F3AC} PLAYER-INIT: Polyfills installed successfully");
1165
+ console.log("\u{1F3AC} PLAYER-INIT: Checking browser support...");
1157
1166
  if (!shaka.Player.isBrowserSupported()) {
1167
+ console.error("\u{1F3AC} PLAYER-INIT: Browser not supported by Shaka Player");
1158
1168
  throw new Error("Browser not supported by Shaka Player");
1159
1169
  }
1170
+ console.log("\u{1F3AC} PLAYER-INIT: Browser support confirmed");
1171
+ console.log("\u{1F3AC} PLAYER-INIT: Creating player instance...");
1160
1172
  const player = new shaka.Player();
1161
1173
  playerRef.current = player;
1174
+ console.log("\u{1F3AC} PLAYER-INIT: Player instance created successfully");
1175
+ console.log("\u{1F3AC} PLAYER-INIT: Attaching player to video element...");
1162
1176
  await player.attach(video);
1177
+ console.log("\u{1F3AC} PLAYER-INIT: Player attached to video element successfully");
1178
+ console.log("\u{1F3AC} PLAYER-INIT: Configuring player...");
1163
1179
  if (shakaConfig) {
1180
+ console.log("\u{1F3AC} PLAYER-INIT: Applying custom shaka config:", shakaConfig);
1164
1181
  player.configure(shakaConfig);
1182
+ console.log("\u{1F3AC} PLAYER-INIT: Custom shaka config applied");
1183
+ } else {
1184
+ console.log("\u{1F3AC} PLAYER-INIT: No custom shaka config provided");
1165
1185
  }
1166
1186
  let manifestUrl = src.url;
1167
1187
  const isDRM = Boolean(src.drm);
1168
1188
  let cert = null;
1169
1189
  if (isDRM) {
1190
+ console.log("\u{1F3AC} PLAYER-INIT: DRM detected, setting up DRM configuration...");
1170
1191
  const isPlayReady = isPlayReadySupported();
1192
+ console.log("\u{1F3AC} PLAYER-INIT: Device capabilities - Apple:", isAppleDevice(), "PlayReady:", isPlayReady);
1171
1193
  if (isAppleDevice() && src.drm.fairplay?.certificate_url) {
1194
+ console.log("\u{1F3AC} PLAYER-INIT: Setting up FairPlay DRM...");
1172
1195
  const req = await fetch(src.drm.fairplay.certificate_url);
1173
1196
  cert = await req.arrayBuffer();
1174
1197
  manifestUrl = src.drm.fairplay.playlist_url;
1198
+ console.log("\u{1F3AC} PLAYER-INIT: FairPlay certificate loaded");
1175
1199
  } else if (isPlayReady && src.drm.playready?.license_url) {
1200
+ console.log("\u{1F3AC} PLAYER-INIT: Setting up PlayReady DRM...");
1176
1201
  manifestUrl = src.drm.playready.playlist_url;
1177
1202
  } else {
1203
+ console.log("\u{1F3AC} PLAYER-INIT: Setting up Widevine DRM...");
1178
1204
  manifestUrl = src.drm?.widevine?.playlist_url || "";
1179
1205
  }
1180
- player.configure({
1206
+ console.log("\u{1F3AC} PLAYER-INIT: Configuring DRM servers...");
1207
+ const drmConfig2 = {
1181
1208
  drm: {
1182
1209
  servers: {
1183
1210
  "com.widevine.alpha": src.drm.widevine?.license_url,
@@ -1192,34 +1219,52 @@ var useShakePlayer = ({
1192
1219
  }
1193
1220
  }
1194
1221
  }
1195
- });
1222
+ };
1223
+ console.log("\u{1F3AC} PLAYER-INIT: DRM config:", drmConfig2);
1224
+ player.configure(drmConfig2);
1225
+ console.log("\u{1F3AC} PLAYER-INIT: DRM configuration applied");
1226
+ console.log("\u{1F3AC} PLAYER-INIT: Setting up DRM network filters...");
1196
1227
  const netEngine = player.getNetworkingEngine();
1197
1228
  if (netEngine) {
1229
+ console.log("\u{1F3AC} PLAYER-INIT: Registering DRM request filter...");
1198
1230
  netEngine.registerRequestFilter((type, request) => {
1199
1231
  if (type === shaka.net.NetworkingEngine.RequestType.LICENSE) {
1232
+ console.log("\u{1F3AC} PLAYER-INIT: Adding DRM token to license request");
1200
1233
  request.headers["x-dt-custom-data"] = src.drm.token;
1201
1234
  }
1202
1235
  });
1236
+ console.log("\u{1F3AC} PLAYER-INIT: Registering DRM response filter...");
1203
1237
  netEngine.registerResponseFilter((type, response) => {
1204
1238
  if (type === shaka.net.NetworkingEngine.RequestType.LICENSE) {
1205
1239
  const ks = player.keySystem && player.keySystem();
1206
1240
  if (ks === "com.apple.fps") {
1241
+ console.log("\u{1F3AC} PLAYER-INIT: Processing FairPlay license response");
1207
1242
  const responseText = shaka.util.StringUtils.fromUTF8(response.data);
1208
1243
  response.data = shaka.util.Uint8ArrayUtils.fromBase64(responseText).buffer;
1209
1244
  }
1210
1245
  }
1211
1246
  });
1247
+ console.log("\u{1F3AC} PLAYER-INIT: DRM network filters registered");
1248
+ } else {
1249
+ console.warn("\u{1F3AC} PLAYER-INIT: No networking engine available for DRM filters");
1212
1250
  }
1251
+ } else {
1252
+ console.log("\u{1F3AC} PLAYER-INIT: No DRM configuration needed");
1213
1253
  }
1254
+ console.log("\u{1F3AC} PLAYER-INIT: Setting up error handling...");
1214
1255
  player?.addEventListener("error", (event) => {
1215
1256
  const error = event.detail;
1216
1257
  if (error?.code === 7e3) {
1258
+ console.log("\u{1F3AC} PLAYER-INIT: Ignoring benign LOAD_INTERRUPTED error (7000)");
1217
1259
  return;
1218
1260
  }
1219
- console.error("Shaka Player Error:", error);
1261
+ console.error("\u{1F3AC} PLAYER-INIT: Shaka Player Error:", error);
1220
1262
  onError?.(new Error(`Shaka Player Error: ${error.message || "Unknown error"}`));
1221
1263
  });
1264
+ console.log("\u{1F3AC} PLAYER-INIT: Error handling configured");
1265
+ console.log("\u{1F3AC} PLAYER-INIT: Checking Mux configuration...");
1222
1266
  if (muxConfig) {
1267
+ console.log("\u{1F3AC} PLAYER-INIT: Initializing Mux Analytics...");
1223
1268
  try {
1224
1269
  const playerInitTime = initShakaPlayerMux.utils.now();
1225
1270
  const muxOptions = {
@@ -1240,33 +1285,54 @@ var useShakePlayer = ({
1240
1285
  ...muxConfig.metadata
1241
1286
  }
1242
1287
  };
1288
+ console.log("\u{1F3AC} PLAYER-INIT: Mux options:", muxOptions);
1243
1289
  initShakaPlayerMux(player, muxOptions, shaka);
1290
+ console.log("\u{1F3AC} PLAYER-INIT: Mux Analytics initialized successfully");
1244
1291
  onMuxReady?.();
1245
1292
  } catch (error) {
1246
- console.error("Failed to initialize Mux Analytics:", error);
1293
+ console.error("\u{1F3AC} PLAYER-INIT: Failed to initialize Mux Analytics:", error);
1247
1294
  }
1295
+ } else {
1296
+ console.log("\u{1F3AC} PLAYER-INIT: No Mux configuration provided");
1248
1297
  }
1298
+ console.log("\u{1F3AC} PLAYER-INIT: Loading manifest:", manifestUrl);
1299
+ console.log("\u{1F3AC} PLAYER-INIT: CRITICAL - Using manifestUrl instead of hardcoded URL");
1249
1300
  await player.load(manifestUrl);
1301
+ console.log("\u{1F3AC} PLAYER-INIT: Manifest loaded successfully");
1302
+ const endTime = performance.now();
1303
+ console.log(`\u{1F3AC} PLAYER-INIT: Player initialization completed in ${(endTime - startTime).toFixed(2)}ms`);
1250
1304
  onPlayerReady?.(player);
1251
1305
  return player;
1252
1306
  } catch (error) {
1253
1307
  if (error?.code === 7e3) {
1308
+ console.log("\u{1F3AC} PLAYER-INIT: Caught benign LOAD_INTERRUPTED error during initialization");
1254
1309
  return;
1255
1310
  }
1256
- console.error("Error initializing Shaka Player:", error);
1311
+ const endTime = performance.now();
1312
+ console.error(`\u{1F3AC} PLAYER-INIT: Error during initialization after ${(endTime - startTime).toFixed(2)}ms:`, error);
1257
1313
  onError?.(error);
1258
1314
  throw error;
1259
1315
  }
1260
1316
  }, [shakaConfig, drmConfig, src, onError, onPlayerReady, muxConfig, onMuxReady]);
1261
1317
  const destroyPlayer = useCallback(async () => {
1262
- if (playerRef.current) {
1318
+ if (playerRef.current && !isDestroyingRef.current) {
1319
+ isDestroyingRef.current = true;
1320
+ console.log("\u{1F3AC} PLAYER-DESTROY: Setting destroy flag to prevent race conditions");
1263
1321
  try {
1322
+ console.log("\u{1F3AC} PLAYER-DESTROY: Destroying player instance...");
1264
1323
  await playerRef.current.destroy();
1324
+ console.log("\u{1F3AC} PLAYER-DESTROY: Player instance destroyed successfully");
1265
1325
  } catch (error) {
1266
- console.warn("Error destroying Shaka Player:", error);
1326
+ console.warn("\u{1F3AC} PLAYER-DESTROY: Error destroying Shaka Player:", error);
1267
1327
  } finally {
1268
1328
  playerRef.current = null;
1329
+ isDestroyingRef.current = false;
1330
+ console.log("\u{1F3AC} PLAYER-DESTROY: Player reference cleared and destroy flag reset");
1269
1331
  }
1332
+ } else if (isDestroyingRef.current) {
1333
+ console.log("\u{1F3AC} PLAYER-DESTROY: Destroy already in progress, skipping...");
1334
+ } else {
1335
+ console.log("\u{1F3AC} PLAYER-DESTROY: No player instance to destroy");
1270
1336
  }
1271
1337
  }, [playerRef]);
1272
1338
  return {
@@ -1684,20 +1750,198 @@ var useShakaUI = (playerRef, containerRef, videoRef, controls, chromecastConfig,
1684
1750
  const uiRef = useRef4(null);
1685
1751
  const registeredElements = useRef4(/* @__PURE__ */ new Set());
1686
1752
  const initializeUI = useCallback5(async () => {
1687
- if (!controls || !containerRef.current || !playerRef.current || !videoRef.current) {
1753
+ console.log("\u{1F3AE} UI-INIT: Starting Shaka UI initialization...");
1754
+ const startTime = performance.now();
1755
+ if (!controls) {
1756
+ console.log("\u{1F3AE} UI-INIT: Controls disabled, skipping UI initialization");
1757
+ return null;
1758
+ }
1759
+ if (!containerRef.current) {
1760
+ console.warn("\u{1F3AE} UI-INIT: Container ref not available, skipping UI initialization");
1761
+ return null;
1762
+ }
1763
+ if (!playerRef.current) {
1764
+ console.warn("\u{1F3AE} UI-INIT: Player ref not available, skipping UI initialization");
1765
+ console.warn("\u{1F3AE} UI-INIT: This might be due to a race condition - player destroyed before UI init");
1766
+ console.log("\u{1F3AE} UI-INIT: Attempting to wait for player reference...");
1767
+ let waitAttempts = 0;
1768
+ const maxWaitAttempts = 10;
1769
+ while (!playerRef.current && waitAttempts < maxWaitAttempts) {
1770
+ await new Promise((resolve) => setTimeout(resolve, 100));
1771
+ waitAttempts++;
1772
+ console.log(`\u{1F3AE} UI-INIT: Waiting for player ref... attempt ${waitAttempts}`);
1773
+ }
1774
+ if (!playerRef.current) {
1775
+ console.error("\u{1F3AE} UI-INIT: Player ref still not available after waiting, aborting UI initialization");
1776
+ return null;
1777
+ } else {
1778
+ console.log(`\u{1F3AE} UI-INIT: Player ref became available after ${waitAttempts * 100}ms`);
1779
+ }
1780
+ }
1781
+ const player = playerRef.current;
1782
+ console.log("\u{1F3AE} UI-INIT: RACE CHECK - Player state analysis:");
1783
+ console.log("\u{1F3AE} UI-INIT: - Player exists:", !!player);
1784
+ if (!player) {
1785
+ console.error("\u{1F3AE} UI-INIT: CRITICAL - Player reference is null during UI initialization!");
1786
+ console.error("\u{1F3AE} UI-INIT: This indicates a race condition between player destruction and UI initialization");
1787
+ return null;
1788
+ }
1789
+ console.log("\u{1F3AE} UI-INIT: - Player isDestroyed:", player.isDestroyed && player.isDestroyed());
1790
+ console.log("\u{1F3AE} UI-INIT: - Player getNetworkingEngine:", !!player.getNetworkingEngine());
1791
+ console.log("\u{1F3AE} UI-INIT: - Player getConfiguration:", !!player.getConfiguration);
1792
+ try {
1793
+ const config = player.getConfiguration();
1794
+ console.log("\u{1F3AE} UI-INIT: - Player configuration available:", !!config);
1795
+ if (player.isDestroyed && player.isDestroyed()) {
1796
+ console.error("\u{1F3AE} UI-INIT: CRITICAL - Player is destroyed, aborting UI initialization");
1797
+ return null;
1798
+ }
1799
+ } catch (error) {
1800
+ console.warn("\u{1F3AE} UI-INIT: - WARNING: Could not get player configuration:", error);
1801
+ console.warn("\u{1F3AE} UI-INIT: - This may indicate the player is in an invalid state");
1802
+ return null;
1803
+ }
1804
+ if (!videoRef.current) {
1805
+ console.warn("\u{1F3AE} UI-INIT: Video ref not available, skipping UI initialization");
1688
1806
  return null;
1689
1807
  }
1808
+ console.log("\u{1F3AE} UI-INIT: All prerequisites met, proceeding with initialization");
1809
+ const chromecastAPICheck = {
1810
+ chromeExists: !!window.chrome,
1811
+ castExists: !!window.chrome?.cast,
1812
+ isAvailable: !!window.chrome?.cast?.isAvailable,
1813
+ sessionExists: !!window.chrome?.cast?.Session,
1814
+ receiverExists: !!window.chrome?.cast?.ReceiverAvailability
1815
+ };
1816
+ console.log("\u{1F3AE} UI-INIT: CRITICAL - Chromecast API state before UI init:", chromecastAPICheck);
1817
+ if (chromecastConfig) {
1818
+ try {
1819
+ console.log("\u{1F3AE} CAST-DIAG: Secure context:", window.isSecureContext, "Protocol:", window.location.protocol);
1820
+ console.log("\u{1F3AE} CAST-DIAG: UserAgent:", navigator.userAgent);
1821
+ console.log("\u{1F3AE} CAST-DIAG: In iframe:", window.top !== window.self);
1822
+ const existingCastScript = document.querySelector('script#gcast_sender, script[src*="cast_sender.js"]');
1823
+ if (existingCastScript) {
1824
+ console.log("\u{1F3AE} CAST-DIAG: Found existing cast sender script:", {
1825
+ id: existingCastScript.id,
1826
+ src: existingCastScript.src,
1827
+ async: existingCastScript.async,
1828
+ defer: existingCastScript.defer,
1829
+ dataset: existingCastScript.dataset
1830
+ });
1831
+ } else {
1832
+ console.log("\u{1F3AE} CAST-DIAG: No cast sender script present yet");
1833
+ }
1834
+ } catch (e) {
1835
+ console.warn("\u{1F3AE} CAST-DIAG: Environment diagnostics failed", e);
1836
+ }
1837
+ const hasCastFramework = !!window.chrome?.cast?.framework?.CastContext;
1838
+ if (!hasCastFramework) {
1839
+ console.warn("\u{1F3AE} UI-INIT: Cast Framework not loaded. Attempting to load sender library...");
1840
+ const loadCastFramework = () => new Promise((resolve) => {
1841
+ if (window.chrome?.cast?.framework?.CastContext) {
1842
+ return resolve();
1843
+ }
1844
+ if (!document.getElementById("gcast_sender")) {
1845
+ const script = document.createElement("script");
1846
+ script.id = "gcast_sender";
1847
+ script.src = "https://www.gstatic.com/cv/js/sender/v1/cast_sender.js?loadCastFramework=1";
1848
+ script.async = true;
1849
+ script.defer = true;
1850
+ script.addEventListener("load", () => {
1851
+ console.log("\u{1F3AE} CAST-LOAD: cast_sender.js loaded");
1852
+ });
1853
+ script.addEventListener("error", (err) => {
1854
+ console.error("\u{1F3AE} CAST-LOAD: cast_sender.js failed to load", err);
1855
+ });
1856
+ document.head.appendChild(script);
1857
+ console.log("\u{1F3AE} CAST-LOAD: Injected cast sender script tag");
1858
+ }
1859
+ const previousCallback = window.__onGCastApiAvailable;
1860
+ window.__onGCastApiAvailable = (isAvailable) => {
1861
+ console.log("\u{1F3AE} UI-INIT: __onGCastApiAvailable called. Available:", isAvailable);
1862
+ try {
1863
+ console.log("\u{1F3AE} CAST-CB: chrome.cast exists:", !!window.chrome?.cast);
1864
+ console.log("\u{1F3AE} CAST-CB: chrome.cast.isAvailable:", !!window.chrome?.cast?.isAvailable);
1865
+ console.log("\u{1F3AE} CAST-CB: chrome.cast.framework exists:", !!window.chrome?.cast?.framework);
1866
+ console.log("\u{1F3AE} CAST-CB: CastContext exists:", !!window.chrome?.cast?.framework?.CastContext);
1867
+ } catch (e) {
1868
+ console.warn("\u{1F3AE} CAST-CB: Diagnostics failed", e);
1869
+ }
1870
+ if (typeof previousCallback === "function") {
1871
+ try {
1872
+ previousCallback(isAvailable);
1873
+ } catch {
1874
+ }
1875
+ }
1876
+ resolve();
1877
+ };
1878
+ let attempts = 0;
1879
+ const maxAttempts = 50;
1880
+ const poll = setInterval(() => {
1881
+ attempts++;
1882
+ const hasCast = !!window.chrome?.cast;
1883
+ const hasFramework = !!window.chrome?.cast?.framework;
1884
+ const hasContext = !!window.chrome?.cast?.framework?.CastContext;
1885
+ if (attempts % 10 === 0) {
1886
+ console.log(`\u{1F3AE} CAST-POLL: attempt=${attempts} cast=${hasCast} framework=${hasFramework} context=${hasContext}`);
1887
+ }
1888
+ if (hasContext || attempts >= maxAttempts) {
1889
+ clearInterval(poll);
1890
+ resolve();
1891
+ }
1892
+ }, 100);
1893
+ });
1894
+ await loadCastFramework();
1895
+ console.log("\u{1F3AE} UI-INIT: Cast Framework load attempt complete. Framework present:", !!window.chrome?.cast?.framework?.CastContext);
1896
+ if (!window.chrome?.cast?.framework?.CastContext) {
1897
+ console.warn("\u{1F3AE} UI-INIT: CastContext still missing after load. Potential causes:");
1898
+ console.warn("\u{1F3AE} UI-INIT: - Script blocked by CSP/adblock");
1899
+ console.warn("\u{1F3AE} UI-INIT: - Non-secure origin (requires https/localhost)");
1900
+ console.warn("\u{1F3AE} UI-INIT: - Non-Chrome browser or incognito restrictions");
1901
+ }
1902
+ }
1903
+ }
1904
+ if (chromecastConfig && !chromecastAPICheck.castExists) {
1905
+ console.warn("\u{1F3AE} UI-INIT: WARNING - Chromecast config provided but Cast API not available!");
1906
+ console.warn("\u{1F3AE} UI-INIT: This could cause race condition issues");
1907
+ console.log("\u{1F3AE} UI-INIT: Waiting for Cast API to be available...");
1908
+ let waitAttempts = 0;
1909
+ const maxWaitAttempts = 50;
1910
+ while (!window.chrome?.cast?.isAvailable && waitAttempts < maxWaitAttempts) {
1911
+ await new Promise((resolve) => setTimeout(resolve, 100));
1912
+ waitAttempts++;
1913
+ if (waitAttempts % 10 === 0) {
1914
+ console.log(`\u{1F3AE} UI-INIT: Still waiting for Cast API... (${waitAttempts * 100}ms)`);
1915
+ }
1916
+ }
1917
+ if (window.chrome?.cast?.isAvailable) {
1918
+ console.log(`\u{1F3AE} UI-INIT: Cast API became available after ${waitAttempts * 100}ms`);
1919
+ } else {
1920
+ console.warn(`\u{1F3AE} UI-INIT: Cast API not available after ${waitAttempts * 100}ms, proceeding anyway`);
1921
+ }
1922
+ }
1923
+ console.log("\u{1F3AE} UI-INIT: Registering custom UI elements...");
1690
1924
  if (!registeredElements.current.has("skip_back_button")) {
1925
+ console.log("\u{1F3AE} UI-INIT: Registering skip_back_button element");
1691
1926
  ShakaUI.Controls.registerElement("skip_back_button", new SkipBackButtonFactory(onSkipBack, iconSizes?.skipButtons));
1692
1927
  registeredElements.current.add("skip_back_button");
1928
+ } else {
1929
+ console.log("\u{1F3AE} UI-INIT: skip_back_button already registered");
1693
1930
  }
1694
1931
  if (!registeredElements.current.has("skip_forward_button")) {
1932
+ console.log("\u{1F3AE} UI-INIT: Registering skip_forward_button element");
1695
1933
  ShakaUI.Controls.registerElement("skip_forward_button", new SkipForwardButtonFactory(onSkipForward, iconSizes?.skipButtons));
1696
1934
  registeredElements.current.add("skip_forward_button");
1935
+ } else {
1936
+ console.log("\u{1F3AE} UI-INIT: skip_forward_button already registered");
1697
1937
  }
1938
+ console.log("\u{1F3AE} UI-INIT: Creating Shaka UI Overlay...");
1698
1939
  const ui = new ShakaUI.Overlay(playerRef.current, containerRef.current, videoRef.current);
1699
1940
  uiRef.current = ui;
1941
+ console.log("\u{1F3AE} UI-INIT: Shaka UI Overlay created successfully");
1700
1942
  const isMobile = window.innerWidth <= 767;
1943
+ console.log("\u{1F3AE} UI-INIT: Device detection - Mobile:", isMobile, "Width:", window.innerWidth);
1944
+ console.log("\u{1F3AE} UI-INIT: Building control panel elements...");
1701
1945
  const controlPanelElements = [
1702
1946
  ...isMobile ? [] : ["skip_back_button"],
1703
1947
  ...isMobile ? [] : ["play_pause"],
@@ -1712,6 +1956,11 @@ var useShakaUI = (playerRef, containerRef, videoRef, controls, chromecastConfig,
1712
1956
  // Always show cast button
1713
1957
  "overflow_menu"
1714
1958
  ];
1959
+ console.log("\u{1F3AE} UI-INIT: Control panel elements:", controlPanelElements);
1960
+ console.log("\u{1F3AE} UI-INIT: Configuring Chromecast settings...");
1961
+ const castReceiverAppId = chromecastConfig?.receiverApplicationId || "CC1AD845";
1962
+ console.log("\u{1F3AE} UI-INIT: Cast receiver app ID:", castReceiverAppId);
1963
+ console.log("\u{1F3AE} UI-INIT: Chromecast config provided:", !!chromecastConfig, chromecastConfig);
1715
1964
  const uiConfig = {
1716
1965
  seekBarColors: {
1717
1966
  base: seekbarColors?.base || "rgba(255, 255, 255, 0.3)",
@@ -1724,8 +1973,7 @@ var useShakaUI = (playerRef, containerRef, videoRef, controls, chromecastConfig,
1724
1973
  controlPanelElements,
1725
1974
  addBigPlayButton: isMobile,
1726
1975
  // Always configure chromecast with defaults or provided config
1727
- castReceiverAppId: chromecastConfig?.receiverApplicationId || "CC1AD845",
1728
- // Default Media Receiver
1976
+ castReceiverAppId,
1729
1977
  castAndroidReceiverCompatible: true,
1730
1978
  // Enable Android TV compatibility
1731
1979
  overflowMenuButtons: [
@@ -1734,11 +1982,66 @@ var useShakaUI = (playerRef, containerRef, videoRef, controls, chromecastConfig,
1734
1982
  "playback_rate"
1735
1983
  ]
1736
1984
  };
1737
- ui.configure(uiConfig);
1985
+ console.log("\u{1F3AE} UI-INIT: Final UI config:", uiConfig);
1986
+ console.log("\u{1F3AE} UI-INIT: Applying UI configuration...");
1987
+ console.log("\u{1F3AE} UI-INIT: RACE CHECK - Pre-configure state:");
1988
+ console.log("\u{1F3AE} UI-INIT: - UI exists:", !!ui);
1989
+ console.log("\u{1F3AE} UI-INIT: - Cast receiver ID:", uiConfig.castReceiverAppId);
1990
+ console.log("\u{1F3AE} UI-INIT: - Cast compatibility:", uiConfig.castAndroidReceiverCompatible);
1991
+ const configureStartTime = performance.now();
1992
+ try {
1993
+ ui.configure(uiConfig);
1994
+ const configureEndTime = performance.now();
1995
+ console.log(`\u{1F3AE} UI-INIT: UI configuration applied successfully in ${(configureEndTime - configureStartTime).toFixed(2)}ms`);
1996
+ setTimeout(() => {
1997
+ const castButton = containerRef.current?.querySelector(".shaka-cast-button");
1998
+ const castAvailable = !!window.chrome?.cast?.isAvailable;
1999
+ console.log("\u{1F3AE} UI-INIT: POST-CONFIGURE CAST CHECK:");
2000
+ console.log("\u{1F3AE} UI-INIT: - Cast button found:", !!castButton);
2001
+ console.log("\u{1F3AE} UI-INIT: - Chrome cast API available:", castAvailable);
2002
+ console.log("\u{1F3AE} UI-INIT: - Cast button visible:", castButton ? !castButton.hasAttribute("hidden") : false);
2003
+ if (castButton) {
2004
+ castButton.addEventListener("click", async () => {
2005
+ console.log("\u{1F3AE} CAST-CLICK: Cast button clicked!");
2006
+ console.log("\u{1F3AE} CAST-CLICK: Player state:", {
2007
+ exists: !!playerRef.current,
2008
+ isDestroyed: playerRef.current?.isDestroyed?.(),
2009
+ videoLoaded: !!videoRef.current?.src,
2010
+ videoCurrentTime: videoRef.current?.currentTime,
2011
+ videoDuration: videoRef.current?.duration
2012
+ });
2013
+ const cast = window.chrome?.cast;
2014
+ const framework = cast?.framework;
2015
+ if (framework?.CastContext) {
2016
+ const castContext = framework.CastContext.getInstance();
2017
+ try {
2018
+ castContext.setOptions?.({
2019
+ receiverApplicationId: chromecastConfig?.receiverApplicationId || "CC1AD845",
2020
+ autoJoinPolicy: cast?.AutoJoinPolicy?.TAB_AND_ORIGIN_SCOPED || "origin_scoped"
2021
+ });
2022
+ console.log("\u{1F3AE} CAST-CLICK: CastContext options set");
2023
+ } catch (e) {
2024
+ console.warn("\u{1F3AE} CAST-CLICK: Failed to set CastContext options", e);
2025
+ }
2026
+ console.log("\u{1F3AE} CAST-CLICK: Cast state:", castContext.getCastState?.());
2027
+ } else {
2028
+ console.warn("\u{1F3AE} CAST-CLICK: Cast framework not available on click");
2029
+ }
2030
+ });
2031
+ }
2032
+ }, 50);
2033
+ } catch (error) {
2034
+ const configureEndTime = performance.now();
2035
+ console.error(`\u{1F3AE} UI-INIT: ERROR during UI configuration after ${(configureEndTime - configureStartTime).toFixed(2)}ms:`, error);
2036
+ throw error;
2037
+ }
2038
+ console.log("\u{1F3AE} UI-INIT: Setting up mobile-specific customizations...");
1738
2039
  if (isMobile) {
2040
+ console.log("\u{1F3AE} UI-INIT: Setting up big play button customization for mobile");
1739
2041
  const customizeBigPlayButton = () => {
1740
2042
  const bigPlayButton = containerRef.current?.querySelector(".shaka-big-play-button");
1741
2043
  if (bigPlayButton && !bigPlayButton.hasAttribute("data-customized")) {
2044
+ console.log("\u{1F3AE} UI-INIT: Customizing big play button");
1742
2045
  const buttonSize = iconSizes?.bigPlayButton || 40;
1743
2046
  bigPlayButton.innerHTML = renderIcon(BigPlayIcon, { size: buttonSize });
1744
2047
  bigPlayButton.setAttribute("data-customized", "true");
@@ -1746,8 +2049,10 @@ var useShakaUI = (playerRef, containerRef, videoRef, controls, chromecastConfig,
1746
2049
  buttonElement.style.display = "flex";
1747
2050
  buttonElement.style.alignItems = "center";
1748
2051
  buttonElement.style.justifyContent = "center";
2052
+ console.log("\u{1F3AE} UI-INIT: Big play button customized successfully");
1749
2053
  }
1750
2054
  };
2055
+ console.log("\u{1F3AE} UI-INIT: Scheduling big play button customization");
1751
2056
  setTimeout(customizeBigPlayButton, 100);
1752
2057
  const observer = new MutationObserver(() => {
1753
2058
  customizeBigPlayButton();
@@ -1758,18 +2063,29 @@ var useShakaUI = (playerRef, containerRef, videoRef, controls, chromecastConfig,
1758
2063
  subtree: true,
1759
2064
  attributes: false
1760
2065
  });
2066
+ console.log("\u{1F3AE} UI-INIT: Mutation observer set up for big play button");
1761
2067
  }
2068
+ } else {
2069
+ console.log("\u{1F3AE} UI-INIT: Desktop mode - skipping big play button customization");
1762
2070
  }
2071
+ console.log("\u{1F3AE} UI-INIT: Seekbar styling handled by CSS");
2072
+ const endTime = performance.now();
2073
+ console.log(`\u{1F3AE} UI-INIT: UI initialization completed successfully in ${(endTime - startTime).toFixed(2)}ms`);
1763
2074
  return ui;
1764
2075
  }, [controls, containerRef, playerRef, videoRef, chromecastConfig, seekbarColors, onSkipBack, onSkipForward, iconSizes]);
1765
2076
  const destroyUI = useCallback5(() => {
1766
2077
  if (uiRef.current) {
1767
2078
  try {
2079
+ console.log("\u{1F3AE} UI-DESTROY: Destroying Shaka UI...");
1768
2080
  uiRef.current.destroy();
2081
+ console.log("\u{1F3AE} UI-DESTROY: Shaka UI destroyed successfully");
1769
2082
  } catch (error) {
1770
- console.error("Error destroying UI:", error);
2083
+ console.error("\u{1F3AE} UI-DESTROY: Error destroying UI:", error);
1771
2084
  }
1772
2085
  uiRef.current = null;
2086
+ console.log("\u{1F3AE} UI-DESTROY: UI reference cleared");
2087
+ } else {
2088
+ console.log("\u{1F3AE} UI-DESTROY: No UI instance to destroy");
1773
2089
  }
1774
2090
  }, []);
1775
2091
  return {
@@ -2536,6 +2852,9 @@ styleInject(`/*! tailwindcss v4.1.8 | MIT License | https://tailwindcss.com */
2536
2852
  .grid {
2537
2853
  display: grid;
2538
2854
  }
2855
+ .hidden {
2856
+ display: none;
2857
+ }
2539
2858
  .aspect-video {
2540
2859
  aspect-ratio: var(--aspect-video);
2541
2860
  }
@@ -3293,14 +3612,18 @@ var Player = forwardRef(
3293
3612
  const videoRef = useRef8(null);
3294
3613
  const containerRef = useRef8(null);
3295
3614
  const adContainerRef = useRef8(null);
3615
+ const isInitializingRef = useRef8(false);
3616
+ const stableShakaConfig = useMemo(() => shakaConfig, [shakaConfig]);
3617
+ const stableDrmConfig = useMemo(() => drmConfig, [drmConfig]);
3618
+ const stableMuxConfig = useMemo(() => muxConfig, [muxConfig]);
3296
3619
  useImperativeHandle(ref, () => videoRef.current, []);
3297
3620
  const { playerRef, initializePlayer, destroyPlayer } = useShakePlayer({
3298
3621
  src,
3299
- shakaConfig,
3300
- drmConfig,
3622
+ shakaConfig: stableShakaConfig,
3623
+ drmConfig: stableDrmConfig,
3301
3624
  onError: events?.onError,
3302
3625
  onPlayerReady: events?.onPlayerReady,
3303
- muxConfig,
3626
+ muxConfig: stableMuxConfig,
3304
3627
  onMuxReady: events?.onMuxReady,
3305
3628
  onMuxDataUpdate: events?.onMuxDataUpdate
3306
3629
  });
@@ -3334,7 +3657,7 @@ var Player = forwardRef(
3334
3657
  onLoadStart: events?.onLoadStart,
3335
3658
  onCanPlay: events?.onCanPlay
3336
3659
  });
3337
- const { uiRef, initializeUI, destroyUI } = useShakaUI(
3660
+ const { uiRef, initializeUI } = useShakaUI(
3338
3661
  playerRef,
3339
3662
  containerRef,
3340
3663
  videoRef,
@@ -3387,57 +3710,105 @@ var Player = forwardRef(
3387
3710
  }
3388
3711
  }
3389
3712
  };
3390
- const initializeChromecast = () => {
3391
- try {
3392
- if (typeof window !== "undefined" && window.chrome?.cast) {
3393
- const castContext = window.chrome.cast.CastContext.getInstance();
3394
- if (castContext) {
3395
- castContext.setOptions({
3396
- receiverApplicationId: chromecastConfig?.receiverApplicationId || "CC1AD845"
3397
- // Default Media Receiver
3398
- });
3399
- castContext.addEventListener("caststatechanged", (event) => {
3400
- const isCasting = event.castState === "CONNECTED";
3401
- events?.onCastStateChange?.(isCasting);
3402
- });
3403
- }
3404
- } else {
3405
- if (events?.onCastStateChange) {
3406
- setTimeout(() => events.onCastStateChange(false), 100);
3407
- }
3408
- }
3409
- } catch (error) {
3410
- console.warn("Chromecast initialization failed:", error);
3411
- if (events?.onCastStateChange) {
3412
- setTimeout(() => events.onCastStateChange(false), 100);
3413
- }
3414
- }
3415
- };
3416
3713
  useEffect5(() => {
3714
+ console.log("SOURCE IS", src);
3715
+ console.log("\u{1F680} MAIN-INIT: Starting main player initialization sequence...");
3716
+ const initStartTime = performance.now();
3417
3717
  const video = videoRef.current;
3418
- if (!video) return;
3718
+ if (!video) {
3719
+ console.warn("\u{1F680} MAIN-INIT: Video element not available, skipping initialization");
3720
+ return;
3721
+ }
3722
+ console.log("\u{1F680} MAIN-INIT: Video element available, proceeding with initialization");
3419
3723
  const initialize = async () => {
3724
+ if (isInitializingRef.current) {
3725
+ console.log("\u{1F680} MAIN-INIT: Initialization already in progress, skipping...");
3726
+ return;
3727
+ }
3728
+ if (playerRef.current && !playerRef.current.isDestroyed?.()) {
3729
+ console.log("\u{1F680} MAIN-INIT: Player already exists and is not destroyed, loading new source instead of re-initialization");
3730
+ try {
3731
+ const manifestUrl = src.url;
3732
+ console.log("\u{1F680} MAIN-INIT: Loading new manifest:", manifestUrl);
3733
+ await playerRef.current.load(manifestUrl);
3734
+ console.log("\u{1F680} MAIN-INIT: New manifest loaded successfully without re-initialization");
3735
+ isInitializingRef.current = false;
3736
+ return;
3737
+ } catch (error) {
3738
+ if (error && typeof error === "object" && "code" in error && error.code === 7e3) {
3739
+ console.log("\u{1F680} MAIN-INIT: Benign LOAD_INTERRUPTED (7000) while loading new source. Skipping re-init.");
3740
+ isInitializingRef.current = false;
3741
+ return;
3742
+ }
3743
+ console.error("\u{1F680} MAIN-INIT: Failed to load new source, proceeding with full re-initialization:", error);
3744
+ }
3745
+ }
3746
+ isInitializingRef.current = true;
3747
+ console.log("\u{1F680} MAIN-INIT: Setting initialization flag to prevent race conditions");
3420
3748
  try {
3749
+ console.log("\u{1F680} MAIN-INIT: === STEP 1: Initialize Player ===");
3750
+ const playerInitStart = performance.now();
3421
3751
  await initializePlayer(video);
3752
+ const playerInitEnd = performance.now();
3753
+ console.log(`\u{1F680} MAIN-INIT: Player initialization completed in ${(playerInitEnd - playerInitStart).toFixed(2)}ms`);
3754
+ console.log("\u{1F680} MAIN-INIT: === STEP 2: Setup Event Listeners ===");
3755
+ const eventListenersStart = performance.now();
3422
3756
  setupEventListeners();
3757
+ const eventListenersEnd = performance.now();
3758
+ console.log(`\u{1F680} MAIN-INIT: Event listeners setup completed in ${(eventListenersEnd - eventListenersStart).toFixed(2)}ms`);
3759
+ console.log("\u{1F680} MAIN-INIT: === STEP 3: Setup Quality Tracking ===");
3760
+ const qualityStart = performance.now();
3423
3761
  const cleanupQuality = setupQualityTracking();
3424
3762
  configureQuality();
3763
+ const qualityEnd = performance.now();
3764
+ console.log(`\u{1F680} MAIN-INIT: Quality setup completed in ${(qualityEnd - qualityStart).toFixed(2)}ms`);
3765
+ console.log("\u{1F680} MAIN-INIT: === STEP 4: Initialize UI (Including Chromecast) ===");
3766
+ const timeSincePlayerInit = performance.now() - playerInitEnd;
3767
+ console.log(`\u{1F680} MAIN-INIT: RACE CHECK - Time gap between player and UI init: ${timeSincePlayerInit.toFixed(2)}ms`);
3768
+ const uiInitStart = performance.now();
3425
3769
  await initializeUI();
3770
+ const uiInitEnd = performance.now();
3771
+ console.log(`\u{1F680} MAIN-INIT: UI initialization completed in ${(uiInitEnd - uiInitStart).toFixed(2)}ms`);
3772
+ console.log("\u{1F680} MAIN-INIT: === STEP 5: Initialize Ads ===");
3773
+ const adsInitStart = performance.now();
3426
3774
  initializeAds();
3427
- initializeChromecast();
3775
+ const adsInitEnd = performance.now();
3776
+ console.log(`\u{1F680} MAIN-INIT: Ads initialization completed in ${(adsInitEnd - adsInitStart).toFixed(2)}ms`);
3777
+ const totalInitTime = performance.now() - initStartTime;
3778
+ console.log(`\u{1F680} MAIN-INIT: === INITIALIZATION COMPLETE ===`);
3779
+ console.log(`\u{1F680} MAIN-INIT: Total initialization time: ${totalInitTime.toFixed(2)}ms`);
3428
3780
  } catch (error) {
3429
- console.error("Error during player initialization:", error);
3781
+ const errorTime = performance.now() - initStartTime;
3782
+ console.error(`\u{1F680} MAIN-INIT: Error during player initialization after ${errorTime.toFixed(2)}ms:`, error);
3430
3783
  handleMuxError(error);
3784
+ } finally {
3785
+ isInitializingRef.current = false;
3786
+ console.log("\u{1F680} MAIN-INIT: Clearing initialization flag");
3431
3787
  }
3432
3788
  };
3433
3789
  initialize();
3434
3790
  return () => {
3791
+ console.log("\u{1F680} MAIN-CLEANUP: Starting cleanup sequence...");
3792
+ const cleanupStart = performance.now();
3793
+ if (!playerRef.current && !isInitializingRef.current) {
3794
+ console.log("\u{1F680} MAIN-CLEANUP: No player to cleanup and no initialization in progress, skipping cleanup");
3795
+ return;
3796
+ }
3797
+ if (playerRef.current && !playerRef.current.isDestroyed?.()) {
3798
+ console.log("\u{1F680} MAIN-CLEANUP: Player exists and is not destroyed - this might be a source change");
3799
+ console.log("\u{1F680} MAIN-CLEANUP: Checking if this is a real unmount or just a re-render...");
3800
+ }
3801
+ isInitializingRef.current = false;
3802
+ console.log("\u{1F680} MAIN-CLEANUP: Reset initialization flag");
3803
+ console.log("\u{1F680} MAIN-CLEANUP: Cleaning up event listeners...");
3435
3804
  cleanupEventListeners();
3436
- destroyUI();
3805
+ console.log("\u{1F680} MAIN-CLEANUP: Destroying UI...");
3806
+ console.log("\u{1F680} MAIN-CLEANUP: Destroying Mux...");
3437
3807
  destroyMux();
3438
- destroyPlayer();
3808
+ const cleanupEnd = performance.now();
3809
+ console.log(`\u{1F680} MAIN-CLEANUP: Cleanup completed in ${(cleanupEnd - cleanupStart).toFixed(2)}ms`);
3439
3810
  };
3440
- }, [src]);
3811
+ }, [src?.url]);
3441
3812
  useEffect5(() => {
3442
3813
  const video = videoRef.current;
3443
3814
  if (!video) return;
@@ -3500,8 +3871,6 @@ var Player = forwardRef(
3500
3871
  ref: containerRef,
3501
3872
  className: containerClasses,
3502
3873
  style: containerStyle,
3503
- "data-shaka-player-container": true,
3504
- "data-shaka-player-cast-receiver-id": chromecastConfig?.receiverApplicationId,
3505
3874
  children: [
3506
3875
  /* @__PURE__ */ jsx8(
3507
3876
  "video",