@mottosports/motto-video-player 1.0.1-rc.31 → 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.js CHANGED
@@ -415,6 +415,9 @@ styleInject(`/*! tailwindcss v4.1.8 | MIT License | https://tailwindcss.com */
415
415
  .grid {
416
416
  display: grid;
417
417
  }
418
+ .hidden {
419
+ display: none;
420
+ }
418
421
  .aspect-video {
419
422
  aspect-ratio: var(--aspect-video);
420
423
  }
@@ -1178,7 +1181,7 @@ var isPlayReadySupported = () => {
1178
1181
  var import_mux_data_shakaplayer = __toESM(require("@mux/mux-data-shakaplayer"));
1179
1182
 
1180
1183
  // package.json
1181
- var version = "1.0.1-rc.31";
1184
+ var version = "1.0.1-rc.33";
1182
1185
 
1183
1186
  // src/hooks/useShakePlayer.ts
1184
1187
  var useShakePlayer = ({
@@ -1192,33 +1195,57 @@ var useShakePlayer = ({
1192
1195
  onMuxDataUpdate
1193
1196
  }) => {
1194
1197
  const playerRef = (0, import_react.useRef)(null);
1198
+ const isDestroyingRef = (0, import_react.useRef)(false);
1195
1199
  const initializePlayer = (0, import_react.useCallback)(async (video) => {
1200
+ console.log("\u{1F3AC} PLAYER-INIT: Starting player initialization...");
1201
+ const startTime = performance.now();
1196
1202
  try {
1203
+ console.log("\u{1F3AC} PLAYER-INIT: Installing polyfills...");
1197
1204
  import_shaka_player.default.polyfill.installAll();
1205
+ console.log("\u{1F3AC} PLAYER-INIT: Polyfills installed successfully");
1206
+ console.log("\u{1F3AC} PLAYER-INIT: Checking browser support...");
1198
1207
  if (!import_shaka_player.default.Player.isBrowserSupported()) {
1208
+ console.error("\u{1F3AC} PLAYER-INIT: Browser not supported by Shaka Player");
1199
1209
  throw new Error("Browser not supported by Shaka Player");
1200
1210
  }
1211
+ console.log("\u{1F3AC} PLAYER-INIT: Browser support confirmed");
1212
+ console.log("\u{1F3AC} PLAYER-INIT: Creating player instance...");
1201
1213
  const player = new import_shaka_player.default.Player();
1202
1214
  playerRef.current = player;
1215
+ console.log("\u{1F3AC} PLAYER-INIT: Player instance created successfully");
1216
+ console.log("\u{1F3AC} PLAYER-INIT: Attaching player to video element...");
1203
1217
  await player.attach(video);
1218
+ console.log("\u{1F3AC} PLAYER-INIT: Player attached to video element successfully");
1219
+ console.log("\u{1F3AC} PLAYER-INIT: Configuring player...");
1204
1220
  if (shakaConfig) {
1221
+ console.log("\u{1F3AC} PLAYER-INIT: Applying custom shaka config:", shakaConfig);
1205
1222
  player.configure(shakaConfig);
1223
+ console.log("\u{1F3AC} PLAYER-INIT: Custom shaka config applied");
1224
+ } else {
1225
+ console.log("\u{1F3AC} PLAYER-INIT: No custom shaka config provided");
1206
1226
  }
1207
1227
  let manifestUrl = src.url;
1208
1228
  const isDRM = Boolean(src.drm);
1209
1229
  let cert = null;
1210
1230
  if (isDRM) {
1231
+ console.log("\u{1F3AC} PLAYER-INIT: DRM detected, setting up DRM configuration...");
1211
1232
  const isPlayReady = isPlayReadySupported();
1233
+ console.log("\u{1F3AC} PLAYER-INIT: Device capabilities - Apple:", isAppleDevice(), "PlayReady:", isPlayReady);
1212
1234
  if (isAppleDevice() && src.drm.fairplay?.certificate_url) {
1235
+ console.log("\u{1F3AC} PLAYER-INIT: Setting up FairPlay DRM...");
1213
1236
  const req = await fetch(src.drm.fairplay.certificate_url);
1214
1237
  cert = await req.arrayBuffer();
1215
1238
  manifestUrl = src.drm.fairplay.playlist_url;
1239
+ console.log("\u{1F3AC} PLAYER-INIT: FairPlay certificate loaded");
1216
1240
  } else if (isPlayReady && src.drm.playready?.license_url) {
1241
+ console.log("\u{1F3AC} PLAYER-INIT: Setting up PlayReady DRM...");
1217
1242
  manifestUrl = src.drm.playready.playlist_url;
1218
1243
  } else {
1244
+ console.log("\u{1F3AC} PLAYER-INIT: Setting up Widevine DRM...");
1219
1245
  manifestUrl = src.drm?.widevine?.playlist_url || "";
1220
1246
  }
1221
- player.configure({
1247
+ console.log("\u{1F3AC} PLAYER-INIT: Configuring DRM servers...");
1248
+ const drmConfig2 = {
1222
1249
  drm: {
1223
1250
  servers: {
1224
1251
  "com.widevine.alpha": src.drm.widevine?.license_url,
@@ -1233,34 +1260,52 @@ var useShakePlayer = ({
1233
1260
  }
1234
1261
  }
1235
1262
  }
1236
- });
1263
+ };
1264
+ console.log("\u{1F3AC} PLAYER-INIT: DRM config:", drmConfig2);
1265
+ player.configure(drmConfig2);
1266
+ console.log("\u{1F3AC} PLAYER-INIT: DRM configuration applied");
1267
+ console.log("\u{1F3AC} PLAYER-INIT: Setting up DRM network filters...");
1237
1268
  const netEngine = player.getNetworkingEngine();
1238
1269
  if (netEngine) {
1270
+ console.log("\u{1F3AC} PLAYER-INIT: Registering DRM request filter...");
1239
1271
  netEngine.registerRequestFilter((type, request) => {
1240
1272
  if (type === import_shaka_player.default.net.NetworkingEngine.RequestType.LICENSE) {
1273
+ console.log("\u{1F3AC} PLAYER-INIT: Adding DRM token to license request");
1241
1274
  request.headers["x-dt-custom-data"] = src.drm.token;
1242
1275
  }
1243
1276
  });
1277
+ console.log("\u{1F3AC} PLAYER-INIT: Registering DRM response filter...");
1244
1278
  netEngine.registerResponseFilter((type, response) => {
1245
1279
  if (type === import_shaka_player.default.net.NetworkingEngine.RequestType.LICENSE) {
1246
1280
  const ks = player.keySystem && player.keySystem();
1247
1281
  if (ks === "com.apple.fps") {
1282
+ console.log("\u{1F3AC} PLAYER-INIT: Processing FairPlay license response");
1248
1283
  const responseText = import_shaka_player.default.util.StringUtils.fromUTF8(response.data);
1249
1284
  response.data = import_shaka_player.default.util.Uint8ArrayUtils.fromBase64(responseText).buffer;
1250
1285
  }
1251
1286
  }
1252
1287
  });
1288
+ console.log("\u{1F3AC} PLAYER-INIT: DRM network filters registered");
1289
+ } else {
1290
+ console.warn("\u{1F3AC} PLAYER-INIT: No networking engine available for DRM filters");
1253
1291
  }
1292
+ } else {
1293
+ console.log("\u{1F3AC} PLAYER-INIT: No DRM configuration needed");
1254
1294
  }
1295
+ console.log("\u{1F3AC} PLAYER-INIT: Setting up error handling...");
1255
1296
  player?.addEventListener("error", (event) => {
1256
1297
  const error = event.detail;
1257
1298
  if (error?.code === 7e3) {
1299
+ console.log("\u{1F3AC} PLAYER-INIT: Ignoring benign LOAD_INTERRUPTED error (7000)");
1258
1300
  return;
1259
1301
  }
1260
- console.error("Shaka Player Error:", error);
1302
+ console.error("\u{1F3AC} PLAYER-INIT: Shaka Player Error:", error);
1261
1303
  onError?.(new Error(`Shaka Player Error: ${error.message || "Unknown error"}`));
1262
1304
  });
1305
+ console.log("\u{1F3AC} PLAYER-INIT: Error handling configured");
1306
+ console.log("\u{1F3AC} PLAYER-INIT: Checking Mux configuration...");
1263
1307
  if (muxConfig) {
1308
+ console.log("\u{1F3AC} PLAYER-INIT: Initializing Mux Analytics...");
1264
1309
  try {
1265
1310
  const playerInitTime = import_mux_data_shakaplayer.default.utils.now();
1266
1311
  const muxOptions = {
@@ -1281,33 +1326,54 @@ var useShakePlayer = ({
1281
1326
  ...muxConfig.metadata
1282
1327
  }
1283
1328
  };
1329
+ console.log("\u{1F3AC} PLAYER-INIT: Mux options:", muxOptions);
1284
1330
  (0, import_mux_data_shakaplayer.default)(player, muxOptions, import_shaka_player.default);
1331
+ console.log("\u{1F3AC} PLAYER-INIT: Mux Analytics initialized successfully");
1285
1332
  onMuxReady?.();
1286
1333
  } catch (error) {
1287
- console.error("Failed to initialize Mux Analytics:", error);
1334
+ console.error("\u{1F3AC} PLAYER-INIT: Failed to initialize Mux Analytics:", error);
1288
1335
  }
1336
+ } else {
1337
+ console.log("\u{1F3AC} PLAYER-INIT: No Mux configuration provided");
1289
1338
  }
1339
+ console.log("\u{1F3AC} PLAYER-INIT: Loading manifest:", manifestUrl);
1340
+ console.log("\u{1F3AC} PLAYER-INIT: CRITICAL - Using manifestUrl instead of hardcoded URL");
1290
1341
  await player.load(manifestUrl);
1342
+ console.log("\u{1F3AC} PLAYER-INIT: Manifest loaded successfully");
1343
+ const endTime = performance.now();
1344
+ console.log(`\u{1F3AC} PLAYER-INIT: Player initialization completed in ${(endTime - startTime).toFixed(2)}ms`);
1291
1345
  onPlayerReady?.(player);
1292
1346
  return player;
1293
1347
  } catch (error) {
1294
1348
  if (error?.code === 7e3) {
1349
+ console.log("\u{1F3AC} PLAYER-INIT: Caught benign LOAD_INTERRUPTED error during initialization");
1295
1350
  return;
1296
1351
  }
1297
- console.error("Error initializing Shaka Player:", error);
1352
+ const endTime = performance.now();
1353
+ console.error(`\u{1F3AC} PLAYER-INIT: Error during initialization after ${(endTime - startTime).toFixed(2)}ms:`, error);
1298
1354
  onError?.(error);
1299
1355
  throw error;
1300
1356
  }
1301
1357
  }, [shakaConfig, drmConfig, src, onError, onPlayerReady, muxConfig, onMuxReady]);
1302
1358
  const destroyPlayer = (0, import_react.useCallback)(async () => {
1303
- if (playerRef.current) {
1359
+ if (playerRef.current && !isDestroyingRef.current) {
1360
+ isDestroyingRef.current = true;
1361
+ console.log("\u{1F3AC} PLAYER-DESTROY: Setting destroy flag to prevent race conditions");
1304
1362
  try {
1363
+ console.log("\u{1F3AC} PLAYER-DESTROY: Destroying player instance...");
1305
1364
  await playerRef.current.destroy();
1365
+ console.log("\u{1F3AC} PLAYER-DESTROY: Player instance destroyed successfully");
1306
1366
  } catch (error) {
1307
- console.warn("Error destroying Shaka Player:", error);
1367
+ console.warn("\u{1F3AC} PLAYER-DESTROY: Error destroying Shaka Player:", error);
1308
1368
  } finally {
1309
1369
  playerRef.current = null;
1370
+ isDestroyingRef.current = false;
1371
+ console.log("\u{1F3AC} PLAYER-DESTROY: Player reference cleared and destroy flag reset");
1310
1372
  }
1373
+ } else if (isDestroyingRef.current) {
1374
+ console.log("\u{1F3AC} PLAYER-DESTROY: Destroy already in progress, skipping...");
1375
+ } else {
1376
+ console.log("\u{1F3AC} PLAYER-DESTROY: No player instance to destroy");
1311
1377
  }
1312
1378
  }, [playerRef]);
1313
1379
  return {
@@ -1725,20 +1791,198 @@ var useShakaUI = (playerRef, containerRef, videoRef, controls, chromecastConfig,
1725
1791
  const uiRef = (0, import_react6.useRef)(null);
1726
1792
  const registeredElements = (0, import_react6.useRef)(/* @__PURE__ */ new Set());
1727
1793
  const initializeUI = (0, import_react6.useCallback)(async () => {
1728
- if (!controls || !containerRef.current || !playerRef.current || !videoRef.current) {
1794
+ console.log("\u{1F3AE} UI-INIT: Starting Shaka UI initialization...");
1795
+ const startTime = performance.now();
1796
+ if (!controls) {
1797
+ console.log("\u{1F3AE} UI-INIT: Controls disabled, skipping UI initialization");
1798
+ return null;
1799
+ }
1800
+ if (!containerRef.current) {
1801
+ console.warn("\u{1F3AE} UI-INIT: Container ref not available, skipping UI initialization");
1802
+ return null;
1803
+ }
1804
+ if (!playerRef.current) {
1805
+ console.warn("\u{1F3AE} UI-INIT: Player ref not available, skipping UI initialization");
1806
+ console.warn("\u{1F3AE} UI-INIT: This might be due to a race condition - player destroyed before UI init");
1807
+ console.log("\u{1F3AE} UI-INIT: Attempting to wait for player reference...");
1808
+ let waitAttempts = 0;
1809
+ const maxWaitAttempts = 10;
1810
+ while (!playerRef.current && waitAttempts < maxWaitAttempts) {
1811
+ await new Promise((resolve) => setTimeout(resolve, 100));
1812
+ waitAttempts++;
1813
+ console.log(`\u{1F3AE} UI-INIT: Waiting for player ref... attempt ${waitAttempts}`);
1814
+ }
1815
+ if (!playerRef.current) {
1816
+ console.error("\u{1F3AE} UI-INIT: Player ref still not available after waiting, aborting UI initialization");
1817
+ return null;
1818
+ } else {
1819
+ console.log(`\u{1F3AE} UI-INIT: Player ref became available after ${waitAttempts * 100}ms`);
1820
+ }
1821
+ }
1822
+ const player = playerRef.current;
1823
+ console.log("\u{1F3AE} UI-INIT: RACE CHECK - Player state analysis:");
1824
+ console.log("\u{1F3AE} UI-INIT: - Player exists:", !!player);
1825
+ if (!player) {
1826
+ console.error("\u{1F3AE} UI-INIT: CRITICAL - Player reference is null during UI initialization!");
1827
+ console.error("\u{1F3AE} UI-INIT: This indicates a race condition between player destruction and UI initialization");
1828
+ return null;
1829
+ }
1830
+ console.log("\u{1F3AE} UI-INIT: - Player isDestroyed:", player.isDestroyed && player.isDestroyed());
1831
+ console.log("\u{1F3AE} UI-INIT: - Player getNetworkingEngine:", !!player.getNetworkingEngine());
1832
+ console.log("\u{1F3AE} UI-INIT: - Player getConfiguration:", !!player.getConfiguration);
1833
+ try {
1834
+ const config = player.getConfiguration();
1835
+ console.log("\u{1F3AE} UI-INIT: - Player configuration available:", !!config);
1836
+ if (player.isDestroyed && player.isDestroyed()) {
1837
+ console.error("\u{1F3AE} UI-INIT: CRITICAL - Player is destroyed, aborting UI initialization");
1838
+ return null;
1839
+ }
1840
+ } catch (error) {
1841
+ console.warn("\u{1F3AE} UI-INIT: - WARNING: Could not get player configuration:", error);
1842
+ console.warn("\u{1F3AE} UI-INIT: - This may indicate the player is in an invalid state");
1843
+ return null;
1844
+ }
1845
+ if (!videoRef.current) {
1846
+ console.warn("\u{1F3AE} UI-INIT: Video ref not available, skipping UI initialization");
1729
1847
  return null;
1730
1848
  }
1849
+ console.log("\u{1F3AE} UI-INIT: All prerequisites met, proceeding with initialization");
1850
+ const chromecastAPICheck = {
1851
+ chromeExists: !!window.chrome,
1852
+ castExists: !!window.chrome?.cast,
1853
+ isAvailable: !!window.chrome?.cast?.isAvailable,
1854
+ sessionExists: !!window.chrome?.cast?.Session,
1855
+ receiverExists: !!window.chrome?.cast?.ReceiverAvailability
1856
+ };
1857
+ console.log("\u{1F3AE} UI-INIT: CRITICAL - Chromecast API state before UI init:", chromecastAPICheck);
1858
+ if (chromecastConfig) {
1859
+ try {
1860
+ console.log("\u{1F3AE} CAST-DIAG: Secure context:", window.isSecureContext, "Protocol:", window.location.protocol);
1861
+ console.log("\u{1F3AE} CAST-DIAG: UserAgent:", navigator.userAgent);
1862
+ console.log("\u{1F3AE} CAST-DIAG: In iframe:", window.top !== window.self);
1863
+ const existingCastScript = document.querySelector('script#gcast_sender, script[src*="cast_sender.js"]');
1864
+ if (existingCastScript) {
1865
+ console.log("\u{1F3AE} CAST-DIAG: Found existing cast sender script:", {
1866
+ id: existingCastScript.id,
1867
+ src: existingCastScript.src,
1868
+ async: existingCastScript.async,
1869
+ defer: existingCastScript.defer,
1870
+ dataset: existingCastScript.dataset
1871
+ });
1872
+ } else {
1873
+ console.log("\u{1F3AE} CAST-DIAG: No cast sender script present yet");
1874
+ }
1875
+ } catch (e) {
1876
+ console.warn("\u{1F3AE} CAST-DIAG: Environment diagnostics failed", e);
1877
+ }
1878
+ const hasCastFramework = !!window.chrome?.cast?.framework?.CastContext;
1879
+ if (!hasCastFramework) {
1880
+ console.warn("\u{1F3AE} UI-INIT: Cast Framework not loaded. Attempting to load sender library...");
1881
+ const loadCastFramework = () => new Promise((resolve) => {
1882
+ if (window.chrome?.cast?.framework?.CastContext) {
1883
+ return resolve();
1884
+ }
1885
+ if (!document.getElementById("gcast_sender")) {
1886
+ const script = document.createElement("script");
1887
+ script.id = "gcast_sender";
1888
+ script.src = "https://www.gstatic.com/cv/js/sender/v1/cast_sender.js?loadCastFramework=1";
1889
+ script.async = true;
1890
+ script.defer = true;
1891
+ script.addEventListener("load", () => {
1892
+ console.log("\u{1F3AE} CAST-LOAD: cast_sender.js loaded");
1893
+ });
1894
+ script.addEventListener("error", (err) => {
1895
+ console.error("\u{1F3AE} CAST-LOAD: cast_sender.js failed to load", err);
1896
+ });
1897
+ document.head.appendChild(script);
1898
+ console.log("\u{1F3AE} CAST-LOAD: Injected cast sender script tag");
1899
+ }
1900
+ const previousCallback = window.__onGCastApiAvailable;
1901
+ window.__onGCastApiAvailable = (isAvailable) => {
1902
+ console.log("\u{1F3AE} UI-INIT: __onGCastApiAvailable called. Available:", isAvailable);
1903
+ try {
1904
+ console.log("\u{1F3AE} CAST-CB: chrome.cast exists:", !!window.chrome?.cast);
1905
+ console.log("\u{1F3AE} CAST-CB: chrome.cast.isAvailable:", !!window.chrome?.cast?.isAvailable);
1906
+ console.log("\u{1F3AE} CAST-CB: chrome.cast.framework exists:", !!window.chrome?.cast?.framework);
1907
+ console.log("\u{1F3AE} CAST-CB: CastContext exists:", !!window.chrome?.cast?.framework?.CastContext);
1908
+ } catch (e) {
1909
+ console.warn("\u{1F3AE} CAST-CB: Diagnostics failed", e);
1910
+ }
1911
+ if (typeof previousCallback === "function") {
1912
+ try {
1913
+ previousCallback(isAvailable);
1914
+ } catch {
1915
+ }
1916
+ }
1917
+ resolve();
1918
+ };
1919
+ let attempts = 0;
1920
+ const maxAttempts = 50;
1921
+ const poll = setInterval(() => {
1922
+ attempts++;
1923
+ const hasCast = !!window.chrome?.cast;
1924
+ const hasFramework = !!window.chrome?.cast?.framework;
1925
+ const hasContext = !!window.chrome?.cast?.framework?.CastContext;
1926
+ if (attempts % 10 === 0) {
1927
+ console.log(`\u{1F3AE} CAST-POLL: attempt=${attempts} cast=${hasCast} framework=${hasFramework} context=${hasContext}`);
1928
+ }
1929
+ if (hasContext || attempts >= maxAttempts) {
1930
+ clearInterval(poll);
1931
+ resolve();
1932
+ }
1933
+ }, 100);
1934
+ });
1935
+ await loadCastFramework();
1936
+ console.log("\u{1F3AE} UI-INIT: Cast Framework load attempt complete. Framework present:", !!window.chrome?.cast?.framework?.CastContext);
1937
+ if (!window.chrome?.cast?.framework?.CastContext) {
1938
+ console.warn("\u{1F3AE} UI-INIT: CastContext still missing after load. Potential causes:");
1939
+ console.warn("\u{1F3AE} UI-INIT: - Script blocked by CSP/adblock");
1940
+ console.warn("\u{1F3AE} UI-INIT: - Non-secure origin (requires https/localhost)");
1941
+ console.warn("\u{1F3AE} UI-INIT: - Non-Chrome browser or incognito restrictions");
1942
+ }
1943
+ }
1944
+ }
1945
+ if (chromecastConfig && !chromecastAPICheck.castExists) {
1946
+ console.warn("\u{1F3AE} UI-INIT: WARNING - Chromecast config provided but Cast API not available!");
1947
+ console.warn("\u{1F3AE} UI-INIT: This could cause race condition issues");
1948
+ console.log("\u{1F3AE} UI-INIT: Waiting for Cast API to be available...");
1949
+ let waitAttempts = 0;
1950
+ const maxWaitAttempts = 50;
1951
+ while (!window.chrome?.cast?.isAvailable && waitAttempts < maxWaitAttempts) {
1952
+ await new Promise((resolve) => setTimeout(resolve, 100));
1953
+ waitAttempts++;
1954
+ if (waitAttempts % 10 === 0) {
1955
+ console.log(`\u{1F3AE} UI-INIT: Still waiting for Cast API... (${waitAttempts * 100}ms)`);
1956
+ }
1957
+ }
1958
+ if (window.chrome?.cast?.isAvailable) {
1959
+ console.log(`\u{1F3AE} UI-INIT: Cast API became available after ${waitAttempts * 100}ms`);
1960
+ } else {
1961
+ console.warn(`\u{1F3AE} UI-INIT: Cast API not available after ${waitAttempts * 100}ms, proceeding anyway`);
1962
+ }
1963
+ }
1964
+ console.log("\u{1F3AE} UI-INIT: Registering custom UI elements...");
1731
1965
  if (!registeredElements.current.has("skip_back_button")) {
1966
+ console.log("\u{1F3AE} UI-INIT: Registering skip_back_button element");
1732
1967
  import_shaka_player3.ui.Controls.registerElement("skip_back_button", new SkipBackButtonFactory(onSkipBack, iconSizes?.skipButtons));
1733
1968
  registeredElements.current.add("skip_back_button");
1969
+ } else {
1970
+ console.log("\u{1F3AE} UI-INIT: skip_back_button already registered");
1734
1971
  }
1735
1972
  if (!registeredElements.current.has("skip_forward_button")) {
1973
+ console.log("\u{1F3AE} UI-INIT: Registering skip_forward_button element");
1736
1974
  import_shaka_player3.ui.Controls.registerElement("skip_forward_button", new SkipForwardButtonFactory(onSkipForward, iconSizes?.skipButtons));
1737
1975
  registeredElements.current.add("skip_forward_button");
1976
+ } else {
1977
+ console.log("\u{1F3AE} UI-INIT: skip_forward_button already registered");
1738
1978
  }
1979
+ console.log("\u{1F3AE} UI-INIT: Creating Shaka UI Overlay...");
1739
1980
  const ui = new import_shaka_player3.ui.Overlay(playerRef.current, containerRef.current, videoRef.current);
1740
1981
  uiRef.current = ui;
1982
+ console.log("\u{1F3AE} UI-INIT: Shaka UI Overlay created successfully");
1741
1983
  const isMobile = window.innerWidth <= 767;
1984
+ console.log("\u{1F3AE} UI-INIT: Device detection - Mobile:", isMobile, "Width:", window.innerWidth);
1985
+ console.log("\u{1F3AE} UI-INIT: Building control panel elements...");
1742
1986
  const controlPanelElements = [
1743
1987
  ...isMobile ? [] : ["skip_back_button"],
1744
1988
  ...isMobile ? [] : ["play_pause"],
@@ -1750,8 +1994,14 @@ var useShakaUI = (playerRef, containerRef, videoRef, controls, chromecastConfig,
1750
1994
  "spacer",
1751
1995
  "fullscreen",
1752
1996
  "cast",
1997
+ // Always show cast button
1753
1998
  "overflow_menu"
1754
1999
  ];
2000
+ console.log("\u{1F3AE} UI-INIT: Control panel elements:", controlPanelElements);
2001
+ console.log("\u{1F3AE} UI-INIT: Configuring Chromecast settings...");
2002
+ const castReceiverAppId = chromecastConfig?.receiverApplicationId || "CC1AD845";
2003
+ console.log("\u{1F3AE} UI-INIT: Cast receiver app ID:", castReceiverAppId);
2004
+ console.log("\u{1F3AE} UI-INIT: Chromecast config provided:", !!chromecastConfig, chromecastConfig);
1755
2005
  const uiConfig = {
1756
2006
  seekBarColors: {
1757
2007
  base: seekbarColors?.base || "rgba(255, 255, 255, 0.3)",
@@ -1763,25 +2013,76 @@ var useShakaUI = (playerRef, containerRef, videoRef, controls, chromecastConfig,
1763
2013
  },
1764
2014
  controlPanelElements,
1765
2015
  addBigPlayButton: isMobile,
1766
- ...chromecastConfig?.receiverApplicationId && {
1767
- "castReceiverAppId": chromecastConfig.receiverApplicationId,
1768
- "castAndroidReceiverCompatible": false
1769
- },
2016
+ // Always configure chromecast with defaults or provided config
2017
+ castReceiverAppId,
2018
+ castAndroidReceiverCompatible: true,
2019
+ // Enable Android TV compatibility
1770
2020
  overflowMenuButtons: [
1771
2021
  "quality",
1772
2022
  "picture_in_picture",
1773
2023
  "playback_rate"
1774
2024
  ]
1775
2025
  };
1776
- if (chromecastConfig?.receiverApplicationId) {
1777
- uiConfig.castReceiverAppId = chromecastConfig.receiverApplicationId;
1778
- uiConfig.castAndroidReceiverCompatible = false;
2026
+ console.log("\u{1F3AE} UI-INIT: Final UI config:", uiConfig);
2027
+ console.log("\u{1F3AE} UI-INIT: Applying UI configuration...");
2028
+ console.log("\u{1F3AE} UI-INIT: RACE CHECK - Pre-configure state:");
2029
+ console.log("\u{1F3AE} UI-INIT: - UI exists:", !!ui);
2030
+ console.log("\u{1F3AE} UI-INIT: - Cast receiver ID:", uiConfig.castReceiverAppId);
2031
+ console.log("\u{1F3AE} UI-INIT: - Cast compatibility:", uiConfig.castAndroidReceiverCompatible);
2032
+ const configureStartTime = performance.now();
2033
+ try {
2034
+ ui.configure(uiConfig);
2035
+ const configureEndTime = performance.now();
2036
+ console.log(`\u{1F3AE} UI-INIT: UI configuration applied successfully in ${(configureEndTime - configureStartTime).toFixed(2)}ms`);
2037
+ setTimeout(() => {
2038
+ const castButton = containerRef.current?.querySelector(".shaka-cast-button");
2039
+ const castAvailable = !!window.chrome?.cast?.isAvailable;
2040
+ console.log("\u{1F3AE} UI-INIT: POST-CONFIGURE CAST CHECK:");
2041
+ console.log("\u{1F3AE} UI-INIT: - Cast button found:", !!castButton);
2042
+ console.log("\u{1F3AE} UI-INIT: - Chrome cast API available:", castAvailable);
2043
+ console.log("\u{1F3AE} UI-INIT: - Cast button visible:", castButton ? !castButton.hasAttribute("hidden") : false);
2044
+ if (castButton) {
2045
+ castButton.addEventListener("click", async () => {
2046
+ console.log("\u{1F3AE} CAST-CLICK: Cast button clicked!");
2047
+ console.log("\u{1F3AE} CAST-CLICK: Player state:", {
2048
+ exists: !!playerRef.current,
2049
+ isDestroyed: playerRef.current?.isDestroyed?.(),
2050
+ videoLoaded: !!videoRef.current?.src,
2051
+ videoCurrentTime: videoRef.current?.currentTime,
2052
+ videoDuration: videoRef.current?.duration
2053
+ });
2054
+ const cast = window.chrome?.cast;
2055
+ const framework = cast?.framework;
2056
+ if (framework?.CastContext) {
2057
+ const castContext = framework.CastContext.getInstance();
2058
+ try {
2059
+ castContext.setOptions?.({
2060
+ receiverApplicationId: chromecastConfig?.receiverApplicationId || "CC1AD845",
2061
+ autoJoinPolicy: cast?.AutoJoinPolicy?.TAB_AND_ORIGIN_SCOPED || "origin_scoped"
2062
+ });
2063
+ console.log("\u{1F3AE} CAST-CLICK: CastContext options set");
2064
+ } catch (e) {
2065
+ console.warn("\u{1F3AE} CAST-CLICK: Failed to set CastContext options", e);
2066
+ }
2067
+ console.log("\u{1F3AE} CAST-CLICK: Cast state:", castContext.getCastState?.());
2068
+ } else {
2069
+ console.warn("\u{1F3AE} CAST-CLICK: Cast framework not available on click");
2070
+ }
2071
+ });
2072
+ }
2073
+ }, 50);
2074
+ } catch (error) {
2075
+ const configureEndTime = performance.now();
2076
+ console.error(`\u{1F3AE} UI-INIT: ERROR during UI configuration after ${(configureEndTime - configureStartTime).toFixed(2)}ms:`, error);
2077
+ throw error;
1779
2078
  }
1780
- ui.configure(uiConfig);
2079
+ console.log("\u{1F3AE} UI-INIT: Setting up mobile-specific customizations...");
1781
2080
  if (isMobile) {
2081
+ console.log("\u{1F3AE} UI-INIT: Setting up big play button customization for mobile");
1782
2082
  const customizeBigPlayButton = () => {
1783
2083
  const bigPlayButton = containerRef.current?.querySelector(".shaka-big-play-button");
1784
2084
  if (bigPlayButton && !bigPlayButton.hasAttribute("data-customized")) {
2085
+ console.log("\u{1F3AE} UI-INIT: Customizing big play button");
1785
2086
  const buttonSize = iconSizes?.bigPlayButton || 40;
1786
2087
  bigPlayButton.innerHTML = renderIcon(BigPlayIcon, { size: buttonSize });
1787
2088
  bigPlayButton.setAttribute("data-customized", "true");
@@ -1789,8 +2090,10 @@ var useShakaUI = (playerRef, containerRef, videoRef, controls, chromecastConfig,
1789
2090
  buttonElement.style.display = "flex";
1790
2091
  buttonElement.style.alignItems = "center";
1791
2092
  buttonElement.style.justifyContent = "center";
2093
+ console.log("\u{1F3AE} UI-INIT: Big play button customized successfully");
1792
2094
  }
1793
2095
  };
2096
+ console.log("\u{1F3AE} UI-INIT: Scheduling big play button customization");
1794
2097
  setTimeout(customizeBigPlayButton, 100);
1795
2098
  const observer = new MutationObserver(() => {
1796
2099
  customizeBigPlayButton();
@@ -1801,18 +2104,29 @@ var useShakaUI = (playerRef, containerRef, videoRef, controls, chromecastConfig,
1801
2104
  subtree: true,
1802
2105
  attributes: false
1803
2106
  });
2107
+ console.log("\u{1F3AE} UI-INIT: Mutation observer set up for big play button");
1804
2108
  }
2109
+ } else {
2110
+ console.log("\u{1F3AE} UI-INIT: Desktop mode - skipping big play button customization");
1805
2111
  }
2112
+ console.log("\u{1F3AE} UI-INIT: Seekbar styling handled by CSS");
2113
+ const endTime = performance.now();
2114
+ console.log(`\u{1F3AE} UI-INIT: UI initialization completed successfully in ${(endTime - startTime).toFixed(2)}ms`);
1806
2115
  return ui;
1807
2116
  }, [controls, containerRef, playerRef, videoRef, chromecastConfig, seekbarColors, onSkipBack, onSkipForward, iconSizes]);
1808
2117
  const destroyUI = (0, import_react6.useCallback)(() => {
1809
2118
  if (uiRef.current) {
1810
2119
  try {
2120
+ console.log("\u{1F3AE} UI-DESTROY: Destroying Shaka UI...");
1811
2121
  uiRef.current.destroy();
2122
+ console.log("\u{1F3AE} UI-DESTROY: Shaka UI destroyed successfully");
1812
2123
  } catch (error) {
1813
- console.error("Error destroying UI:", error);
2124
+ console.error("\u{1F3AE} UI-DESTROY: Error destroying UI:", error);
1814
2125
  }
1815
2126
  uiRef.current = null;
2127
+ console.log("\u{1F3AE} UI-DESTROY: UI reference cleared");
2128
+ } else {
2129
+ console.log("\u{1F3AE} UI-DESTROY: No UI instance to destroy");
1816
2130
  }
1817
2131
  }, []);
1818
2132
  return {
@@ -2579,6 +2893,9 @@ styleInject(`/*! tailwindcss v4.1.8 | MIT License | https://tailwindcss.com */
2579
2893
  .grid {
2580
2894
  display: grid;
2581
2895
  }
2896
+ .hidden {
2897
+ display: none;
2898
+ }
2582
2899
  .aspect-video {
2583
2900
  aspect-ratio: var(--aspect-video);
2584
2901
  }
@@ -3336,14 +3653,18 @@ var Player = (0, import_react12.forwardRef)(
3336
3653
  const videoRef = (0, import_react12.useRef)(null);
3337
3654
  const containerRef = (0, import_react12.useRef)(null);
3338
3655
  const adContainerRef = (0, import_react12.useRef)(null);
3656
+ const isInitializingRef = (0, import_react12.useRef)(false);
3657
+ const stableShakaConfig = (0, import_react12.useMemo)(() => shakaConfig, [shakaConfig]);
3658
+ const stableDrmConfig = (0, import_react12.useMemo)(() => drmConfig, [drmConfig]);
3659
+ const stableMuxConfig = (0, import_react12.useMemo)(() => muxConfig, [muxConfig]);
3339
3660
  (0, import_react12.useImperativeHandle)(ref, () => videoRef.current, []);
3340
3661
  const { playerRef, initializePlayer, destroyPlayer } = useShakePlayer({
3341
3662
  src,
3342
- shakaConfig,
3343
- drmConfig,
3663
+ shakaConfig: stableShakaConfig,
3664
+ drmConfig: stableDrmConfig,
3344
3665
  onError: events?.onError,
3345
3666
  onPlayerReady: events?.onPlayerReady,
3346
- muxConfig,
3667
+ muxConfig: stableMuxConfig,
3347
3668
  onMuxReady: events?.onMuxReady,
3348
3669
  onMuxDataUpdate: events?.onMuxDataUpdate
3349
3670
  });
@@ -3377,7 +3698,7 @@ var Player = (0, import_react12.forwardRef)(
3377
3698
  onLoadStart: events?.onLoadStart,
3378
3699
  onCanPlay: events?.onCanPlay
3379
3700
  });
3380
- const { uiRef, initializeUI, destroyUI } = useShakaUI(
3701
+ const { uiRef, initializeUI } = useShakaUI(
3381
3702
  playerRef,
3382
3703
  containerRef,
3383
3704
  videoRef,
@@ -3430,43 +3751,105 @@ var Player = (0, import_react12.forwardRef)(
3430
3751
  }
3431
3752
  }
3432
3753
  };
3433
- const initializeChromecast = () => {
3434
- if (!chromecastConfig?.enabled) {
3435
- return;
3436
- }
3437
- try {
3438
- if (events?.onCastStateChange) {
3439
- setTimeout(() => events.onCastStateChange(false), 100);
3440
- }
3441
- } catch (error) {
3442
- console.warn("Chromecast initialization failed:", error);
3443
- }
3444
- };
3445
3754
  (0, import_react12.useEffect)(() => {
3755
+ console.log("SOURCE IS", src);
3756
+ console.log("\u{1F680} MAIN-INIT: Starting main player initialization sequence...");
3757
+ const initStartTime = performance.now();
3446
3758
  const video = videoRef.current;
3447
- if (!video) return;
3759
+ if (!video) {
3760
+ console.warn("\u{1F680} MAIN-INIT: Video element not available, skipping initialization");
3761
+ return;
3762
+ }
3763
+ console.log("\u{1F680} MAIN-INIT: Video element available, proceeding with initialization");
3448
3764
  const initialize = async () => {
3765
+ if (isInitializingRef.current) {
3766
+ console.log("\u{1F680} MAIN-INIT: Initialization already in progress, skipping...");
3767
+ return;
3768
+ }
3769
+ if (playerRef.current && !playerRef.current.isDestroyed?.()) {
3770
+ console.log("\u{1F680} MAIN-INIT: Player already exists and is not destroyed, loading new source instead of re-initialization");
3771
+ try {
3772
+ const manifestUrl = src.url;
3773
+ console.log("\u{1F680} MAIN-INIT: Loading new manifest:", manifestUrl);
3774
+ await playerRef.current.load(manifestUrl);
3775
+ console.log("\u{1F680} MAIN-INIT: New manifest loaded successfully without re-initialization");
3776
+ isInitializingRef.current = false;
3777
+ return;
3778
+ } catch (error) {
3779
+ if (error && typeof error === "object" && "code" in error && error.code === 7e3) {
3780
+ console.log("\u{1F680} MAIN-INIT: Benign LOAD_INTERRUPTED (7000) while loading new source. Skipping re-init.");
3781
+ isInitializingRef.current = false;
3782
+ return;
3783
+ }
3784
+ console.error("\u{1F680} MAIN-INIT: Failed to load new source, proceeding with full re-initialization:", error);
3785
+ }
3786
+ }
3787
+ isInitializingRef.current = true;
3788
+ console.log("\u{1F680} MAIN-INIT: Setting initialization flag to prevent race conditions");
3449
3789
  try {
3790
+ console.log("\u{1F680} MAIN-INIT: === STEP 1: Initialize Player ===");
3791
+ const playerInitStart = performance.now();
3450
3792
  await initializePlayer(video);
3793
+ const playerInitEnd = performance.now();
3794
+ console.log(`\u{1F680} MAIN-INIT: Player initialization completed in ${(playerInitEnd - playerInitStart).toFixed(2)}ms`);
3795
+ console.log("\u{1F680} MAIN-INIT: === STEP 2: Setup Event Listeners ===");
3796
+ const eventListenersStart = performance.now();
3451
3797
  setupEventListeners();
3798
+ const eventListenersEnd = performance.now();
3799
+ console.log(`\u{1F680} MAIN-INIT: Event listeners setup completed in ${(eventListenersEnd - eventListenersStart).toFixed(2)}ms`);
3800
+ console.log("\u{1F680} MAIN-INIT: === STEP 3: Setup Quality Tracking ===");
3801
+ const qualityStart = performance.now();
3452
3802
  const cleanupQuality = setupQualityTracking();
3453
3803
  configureQuality();
3804
+ const qualityEnd = performance.now();
3805
+ console.log(`\u{1F680} MAIN-INIT: Quality setup completed in ${(qualityEnd - qualityStart).toFixed(2)}ms`);
3806
+ console.log("\u{1F680} MAIN-INIT: === STEP 4: Initialize UI (Including Chromecast) ===");
3807
+ const timeSincePlayerInit = performance.now() - playerInitEnd;
3808
+ console.log(`\u{1F680} MAIN-INIT: RACE CHECK - Time gap between player and UI init: ${timeSincePlayerInit.toFixed(2)}ms`);
3809
+ const uiInitStart = performance.now();
3454
3810
  await initializeUI();
3811
+ const uiInitEnd = performance.now();
3812
+ console.log(`\u{1F680} MAIN-INIT: UI initialization completed in ${(uiInitEnd - uiInitStart).toFixed(2)}ms`);
3813
+ console.log("\u{1F680} MAIN-INIT: === STEP 5: Initialize Ads ===");
3814
+ const adsInitStart = performance.now();
3455
3815
  initializeAds();
3456
- initializeChromecast();
3816
+ const adsInitEnd = performance.now();
3817
+ console.log(`\u{1F680} MAIN-INIT: Ads initialization completed in ${(adsInitEnd - adsInitStart).toFixed(2)}ms`);
3818
+ const totalInitTime = performance.now() - initStartTime;
3819
+ console.log(`\u{1F680} MAIN-INIT: === INITIALIZATION COMPLETE ===`);
3820
+ console.log(`\u{1F680} MAIN-INIT: Total initialization time: ${totalInitTime.toFixed(2)}ms`);
3457
3821
  } catch (error) {
3458
- console.error("Error during player initialization:", error);
3822
+ const errorTime = performance.now() - initStartTime;
3823
+ console.error(`\u{1F680} MAIN-INIT: Error during player initialization after ${errorTime.toFixed(2)}ms:`, error);
3459
3824
  handleMuxError(error);
3825
+ } finally {
3826
+ isInitializingRef.current = false;
3827
+ console.log("\u{1F680} MAIN-INIT: Clearing initialization flag");
3460
3828
  }
3461
3829
  };
3462
3830
  initialize();
3463
3831
  return () => {
3832
+ console.log("\u{1F680} MAIN-CLEANUP: Starting cleanup sequence...");
3833
+ const cleanupStart = performance.now();
3834
+ if (!playerRef.current && !isInitializingRef.current) {
3835
+ console.log("\u{1F680} MAIN-CLEANUP: No player to cleanup and no initialization in progress, skipping cleanup");
3836
+ return;
3837
+ }
3838
+ if (playerRef.current && !playerRef.current.isDestroyed?.()) {
3839
+ console.log("\u{1F680} MAIN-CLEANUP: Player exists and is not destroyed - this might be a source change");
3840
+ console.log("\u{1F680} MAIN-CLEANUP: Checking if this is a real unmount or just a re-render...");
3841
+ }
3842
+ isInitializingRef.current = false;
3843
+ console.log("\u{1F680} MAIN-CLEANUP: Reset initialization flag");
3844
+ console.log("\u{1F680} MAIN-CLEANUP: Cleaning up event listeners...");
3464
3845
  cleanupEventListeners();
3465
- destroyUI();
3846
+ console.log("\u{1F680} MAIN-CLEANUP: Destroying UI...");
3847
+ console.log("\u{1F680} MAIN-CLEANUP: Destroying Mux...");
3466
3848
  destroyMux();
3467
- destroyPlayer();
3849
+ const cleanupEnd = performance.now();
3850
+ console.log(`\u{1F680} MAIN-CLEANUP: Cleanup completed in ${(cleanupEnd - cleanupStart).toFixed(2)}ms`);
3468
3851
  };
3469
- }, [src]);
3852
+ }, [src?.url]);
3470
3853
  (0, import_react12.useEffect)(() => {
3471
3854
  const video = videoRef.current;
3472
3855
  if (!video) return;
@@ -3529,8 +3912,6 @@ var Player = (0, import_react12.forwardRef)(
3529
3912
  ref: containerRef,
3530
3913
  className: containerClasses,
3531
3914
  style: containerStyle,
3532
- "data-shaka-player-container": true,
3533
- "data-shaka-player-cast-receiver-id": chromecastConfig?.receiverApplicationId,
3534
3915
  children: [
3535
3916
  /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
3536
3917
  "video",