@mottosports/motto-video-player 1.0.1-rc.35 → 1.0.1-rc.37

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
@@ -1106,8 +1106,8 @@ styleInject(`/*! tailwindcss v4.1.8 | MIT License | https://tailwindcss.com */
1106
1106
  import { forwardRef, useEffect as useEffect5, useRef as useRef8, useImperativeHandle } from "react";
1107
1107
  import shaka3 from "shaka-player/dist/shaka-player.ui";
1108
1108
 
1109
- // src/hooks/useShakePlayer.ts
1110
- import { useRef, useCallback } from "react";
1109
+ // src/hooks/useShakaPlayer.ts
1110
+ import { useRef, useCallback, useState } from "react";
1111
1111
  import shaka from "shaka-player/dist/shaka-player.ui";
1112
1112
 
1113
1113
  // src/utils/devices.ts
@@ -1132,15 +1132,183 @@ var isPlayReadySupported = () => {
1132
1132
  const isIE = /Trident|MSIE/.test(userAgent);
1133
1133
  return isXbox || isEdge || isIE;
1134
1134
  };
1135
+ var isChrome64PlusOnMacOrWindows = () => {
1136
+ if (typeof navigator === "undefined") {
1137
+ return false;
1138
+ }
1139
+ const userAgent = navigator.userAgent || "";
1140
+ const isChromeMatch = userAgent.match(/Chrome\/(\d+)/);
1141
+ if (!isChromeMatch) {
1142
+ return false;
1143
+ }
1144
+ if (/Edg|OPR|Opera/.test(userAgent)) {
1145
+ return false;
1146
+ }
1147
+ const chromeVersion = parseInt(isChromeMatch[1], 10);
1148
+ if (chromeVersion < 64) {
1149
+ return false;
1150
+ }
1151
+ const isMacOS = /Mac OS X|Macintosh/.test(userAgent);
1152
+ const isWindows = /Windows/.test(userAgent);
1153
+ return isMacOS || isWindows;
1154
+ };
1135
1155
 
1136
- // src/hooks/useShakePlayer.ts
1156
+ // src/hooks/useShakaPlayer.ts
1137
1157
  import initShakaPlayerMux from "@mux/mux-data-shakaplayer";
1138
1158
 
1139
1159
  // package.json
1140
- var version = "1.0.1-rc.35";
1160
+ var version = "1.0.1-rc.37";
1161
+
1162
+ // src/utils/licenseCache.ts
1163
+ var PERSISTENT_LICENSE_PREFIX = "motto_lic_";
1164
+ var LICENSE_EXPIRY_MS = 7 * 24 * 60 * 60 * 1e3;
1165
+ var LICENSE_MAX_RETRY_ATTEMPTS = 10;
1166
+ var getAllLicenseCacheKeys = () => {
1167
+ const keys = [];
1168
+ for (let i = 0; i < localStorage.length; i++) {
1169
+ const key = localStorage.key(i);
1170
+ if (key?.startsWith(PERSISTENT_LICENSE_PREFIX)) {
1171
+ keys.push(key);
1172
+ }
1173
+ }
1174
+ return keys;
1175
+ };
1176
+ var getAllLicenseCacheEntries = () => {
1177
+ const keys = getAllLicenseCacheKeys();
1178
+ const entries = [];
1179
+ for (const key of keys) {
1180
+ try {
1181
+ const stored = localStorage.getItem(key);
1182
+ if (stored) {
1183
+ const data = JSON.parse(stored);
1184
+ entries.push({ key, data });
1185
+ }
1186
+ } catch (error) {
1187
+ console.warn(`Failed to parse license cache entry for key ${key}:`, error);
1188
+ localStorage.removeItem(key);
1189
+ }
1190
+ }
1191
+ return entries;
1192
+ };
1193
+ var evictLRUEntry = () => {
1194
+ const entries = getAllLicenseCacheEntries();
1195
+ if (entries.length === 0) {
1196
+ return false;
1197
+ }
1198
+ entries.sort((a, b) => {
1199
+ const oldestA = Math.min(...a.data.map((session) => session.timestamp));
1200
+ const oldestB = Math.min(...b.data.map((session) => session.timestamp));
1201
+ return oldestA - oldestB;
1202
+ });
1203
+ const lruEntry = entries[0];
1204
+ localStorage.removeItem(lruEntry.key);
1205
+ console.log(`Evicted LRU license cache entry: ${lruEntry.key}`);
1206
+ return true;
1207
+ };
1208
+ var storeWithQuotaHandling = (key, data) => {
1209
+ let attempts = 0;
1210
+ while (attempts < LICENSE_MAX_RETRY_ATTEMPTS) {
1211
+ try {
1212
+ localStorage.setItem(key, data);
1213
+ return true;
1214
+ } catch (error) {
1215
+ if (error instanceof DOMException && (error.code === 22 || // QUOTA_EXCEEDED_ERR
1216
+ error.name === "QuotaExceededError" || error.name === "NS_ERROR_DOM_QUOTA_REACHED")) {
1217
+ console.warn(`QuotaExceededError on attempt ${attempts + 1}, attempting LRU eviction...`);
1218
+ if (!evictLRUEntry()) {
1219
+ console.error("No more entries to evict, storage operation failed");
1220
+ return false;
1221
+ }
1222
+ attempts++;
1223
+ } else {
1224
+ console.error("Failed to store license cache data:", error);
1225
+ return false;
1226
+ }
1227
+ }
1228
+ }
1229
+ console.error(`Failed to store license cache data after ${LICENSE_MAX_RETRY_ATTEMPTS} eviction attempts`);
1230
+ return false;
1231
+ };
1232
+ var managePersistentLicenseStorage = (playlistId, licenseCacheKey, newSessionMetadata) => {
1233
+ try {
1234
+ const storageKey = `${PERSISTENT_LICENSE_PREFIX}${playlistId}_${licenseCacheKey}`;
1235
+ const stored = localStorage.getItem(storageKey);
1236
+ let existingSessions = [];
1237
+ if (stored) {
1238
+ try {
1239
+ existingSessions = JSON.parse(stored);
1240
+ } catch (parseError) {
1241
+ console.warn("Failed to parse existing persistent license data:", parseError);
1242
+ existingSessions = [];
1243
+ }
1244
+ }
1245
+ const now = Date.now();
1246
+ let validSessions = existingSessions.filter(
1247
+ (session) => now - session.timestamp < LICENSE_EXPIRY_MS
1248
+ );
1249
+ if (newSessionMetadata && newSessionMetadata.length > 0) {
1250
+ const newSessions = newSessionMetadata.map((session) => {
1251
+ const uint8Array = new Uint8Array(session.initData);
1252
+ const binaryString = Array.from(uint8Array).map((byte) => String.fromCharCode(byte)).join("");
1253
+ return {
1254
+ sessionId: session.sessionId,
1255
+ initData: btoa(binaryString),
1256
+ initDataType: session.initDataType,
1257
+ keySystem: session.keySystem,
1258
+ timestamp: now
1259
+ };
1260
+ });
1261
+ const newSessionIds = new Set(newSessions.map((s) => s.sessionId));
1262
+ validSessions = validSessions.filter((session) => !newSessionIds.has(session.sessionId));
1263
+ validSessions = [...validSessions, ...newSessions];
1264
+ }
1265
+ if (validSessions.length === 0) {
1266
+ localStorage.removeItem(storageKey);
1267
+ } else {
1268
+ const dataToStore = JSON.stringify(validSessions);
1269
+ const success = storeWithQuotaHandling(storageKey, dataToStore);
1270
+ if (!success) {
1271
+ console.error(`Failed to store license cache for ${storageKey} after quota handling`);
1272
+ return validSessions;
1273
+ }
1274
+ }
1275
+ return validSessions;
1276
+ } catch (error) {
1277
+ console.warn("Failed to manage persistent license storage:", error);
1278
+ return [];
1279
+ }
1280
+ };
1281
+ var storePersistentLicense = (playlistId, licenseCacheKey, sessionMetadata) => {
1282
+ managePersistentLicenseStorage(playlistId, licenseCacheKey, sessionMetadata);
1283
+ };
1284
+ var retrievePersistentLicense = (playlistId, licenseCacheKey) => {
1285
+ try {
1286
+ const validSessions = managePersistentLicenseStorage(playlistId, licenseCacheKey);
1287
+ return validSessions.map((session) => ({
1288
+ sessionId: session.sessionId,
1289
+ initData: Uint8Array.from(atob(session.initData), (c) => c.charCodeAt(0)).buffer,
1290
+ initDataType: session.initDataType,
1291
+ keySystem: session.keySystem
1292
+ }));
1293
+ } catch (error) {
1294
+ console.warn("Failed to retrieve persistent license:", error);
1295
+ return [];
1296
+ }
1297
+ };
1298
+ var clearAllPersistentLicenses = () => {
1299
+ try {
1300
+ const keys = getAllLicenseCacheKeys();
1301
+ for (const key of keys) {
1302
+ localStorage.removeItem(key);
1303
+ }
1304
+ console.log(`Cleared ${keys.length} persistent license cache entries`);
1305
+ } catch (error) {
1306
+ console.error("Failed to clear persistent licenses:", error);
1307
+ }
1308
+ };
1141
1309
 
1142
- // src/hooks/useShakePlayer.ts
1143
- var useShakePlayer = ({
1310
+ // src/hooks/useShakaPlayer.ts
1311
+ var useShakaPlayer = ({
1144
1312
  src,
1145
1313
  shakaConfig,
1146
1314
  drmConfig,
@@ -1151,8 +1319,26 @@ var useShakePlayer = ({
1151
1319
  onMuxDataUpdate
1152
1320
  }) => {
1153
1321
  const playerRef = useRef(null);
1154
- const initializePlayer = useCallback(async (video) => {
1322
+ const [isRetrying, setIsRetrying] = useState(false);
1323
+ const videoElementRef = useRef(null);
1324
+ const getManifestUrl = useCallback(() => {
1325
+ let manifestUrl = src.url;
1326
+ const isDRM = Boolean(src.drm);
1327
+ if (isDRM) {
1328
+ const isPlayReady = isPlayReadySupported();
1329
+ if (isAppleDevice() && src.drm.fairplay?.certificateUrl) {
1330
+ manifestUrl = src.drm.fairplay.playlistUrl;
1331
+ } else if (isPlayReady && src.drm.playready?.licenseUrl) {
1332
+ manifestUrl = src.drm.playready.playlistUrl;
1333
+ } else {
1334
+ manifestUrl = src.drm?.widevine?.playlistUrl || "";
1335
+ }
1336
+ }
1337
+ return manifestUrl;
1338
+ }, [src]);
1339
+ const initializePlayerInternal = useCallback(async (video) => {
1155
1340
  try {
1341
+ videoElementRef.current = video;
1156
1342
  shaka.polyfill.installAll();
1157
1343
  if (!shaka.Player.isBrowserSupported()) {
1158
1344
  throw new Error("Browser not supported by Shaka Player");
@@ -1163,36 +1349,55 @@ var useShakePlayer = ({
1163
1349
  if (shakaConfig) {
1164
1350
  player.configure(shakaConfig);
1165
1351
  }
1166
- let manifestUrl = src.url;
1352
+ const manifestUrl = getManifestUrl();
1353
+ let playlistId = src.id;
1167
1354
  const isDRM = Boolean(src.drm);
1168
- let cert = null;
1355
+ let storedSessionsMetadata = [];
1356
+ if (isDRM && playlistId) {
1357
+ storedSessionsMetadata = retrievePersistentLicense(playlistId, src.drm.licenseCacheKey ?? "");
1358
+ }
1169
1359
  if (isDRM) {
1170
- const isPlayReady = isPlayReadySupported();
1171
- if (isAppleDevice() && src.drm.fairplay?.certificateUrl) {
1172
- const req = await fetch(src.drm.fairplay.certificateUrl);
1173
- cert = await req.arrayBuffer();
1174
- manifestUrl = src.drm.fairplay.playlistUrl;
1175
- } else if (isPlayReady && src.drm.playready?.licenseUrl) {
1176
- manifestUrl = src.drm.playready.playlistUrl;
1177
- } else {
1178
- manifestUrl = src.drm?.widevine?.playlistUrl || "";
1179
- }
1180
- player.configure({
1181
- drm: {
1182
- servers: {
1183
- "com.widevine.alpha": src.drm.widevine?.licenseUrl,
1184
- "com.microsoft.playready": src.drm.playready?.licenseUrl,
1185
- "com.apple.fps": src.drm.fairplay?.licenseUrl
1186
- },
1187
- ...cert && {
1188
- advanced: {
1189
- "com.apple.fps": {
1190
- serverCertificate: new Uint8Array(cert)
1191
- }
1360
+ const drmConfig2 = {
1361
+ servers: {
1362
+ "com.widevine.alpha": src.drm.widevine?.licenseUrl,
1363
+ "com.microsoft.playready": src.drm.playready?.licenseUrl,
1364
+ "com.apple.fps": src.drm.fairplay?.licenseUrl
1365
+ },
1366
+ ...src.drm.fairplay && {
1367
+ advanced: {
1368
+ "com.apple.fps": {
1369
+ serverCertificateUri: src.drm.fairplay.certificateUrl
1192
1370
  }
1193
1371
  }
1194
1372
  }
1195
- });
1373
+ };
1374
+ drmConfig2.advanced = {
1375
+ ...drmConfig2.advanced,
1376
+ "com.widevine.alpha": {
1377
+ ...drmConfig2.advanced?.["com.widevine.alpha"],
1378
+ // set to `persistent-license` only on Chrome 64+ on MacOS/Windows: https://shaka-player-demo.appspot.com/docs/api/tutorial-faq.html
1379
+ sessionType: isChrome64PlusOnMacOrWindows() ? "persistent-license" : "temporary"
1380
+ },
1381
+ "com.microsoft.playready": {
1382
+ ...drmConfig2.advanced?.["com.microsoft.playready"],
1383
+ sessionType: "temporary"
1384
+ // PlayReady always uses temporary sessions
1385
+ },
1386
+ "com.apple.fps": {
1387
+ ...drmConfig2.advanced?.["com.apple.fps"],
1388
+ sessionType: "temporary"
1389
+ // FairPlay always uses temporary sessions - Safari won't play with persistent-license
1390
+ }
1391
+ };
1392
+ if (storedSessionsMetadata.length > 0) {
1393
+ drmConfig2.persistentSessionOnlinePlayback = true;
1394
+ drmConfig2.persistentSessionsMetadata = storedSessionsMetadata.map((session) => ({
1395
+ sessionId: session.sessionId,
1396
+ initData: new Uint8Array(session.initData),
1397
+ initDataType: session.initDataType
1398
+ }));
1399
+ }
1400
+ player.configure({ drm: drmConfig2 });
1196
1401
  const netEngine = player.getNetworkingEngine();
1197
1402
  if (netEngine) {
1198
1403
  netEngine.registerRequestFilter((type, request) => {
@@ -1216,6 +1421,28 @@ var useShakePlayer = ({
1216
1421
  if (error?.code === 7e3) {
1217
1422
  return;
1218
1423
  }
1424
+ if (error?.code >= 6e3 && error?.code < 7e3 && !isRetrying && videoElementRef.current) {
1425
+ console.warn(`DRM error detected (code: ${error.code}), clearing licenses and retrying...`);
1426
+ setIsRetrying(true);
1427
+ clearAllPersistentLicenses();
1428
+ setTimeout(async () => {
1429
+ try {
1430
+ const video2 = videoElementRef.current;
1431
+ const currentPlayer = playerRef.current;
1432
+ if (video2 && currentPlayer) {
1433
+ console.log("Reloading manifest after license cache clear...");
1434
+ await currentPlayer.load(getManifestUrl());
1435
+ console.log("Manifest reloaded successfully");
1436
+ }
1437
+ } catch (retryError) {
1438
+ console.error("Failed to retry after license clear:", retryError);
1439
+ onError?.(retryError);
1440
+ } finally {
1441
+ setIsRetrying(false);
1442
+ }
1443
+ }, 500);
1444
+ return;
1445
+ }
1219
1446
  console.error("Shaka Player Error:", error);
1220
1447
  onError?.(new Error(`Shaka Player Error: ${error.message || "Unknown error"}`));
1221
1448
  });
@@ -1247,6 +1474,30 @@ var useShakePlayer = ({
1247
1474
  }
1248
1475
  }
1249
1476
  await player.load(manifestUrl);
1477
+ if (isDRM && playlistId) {
1478
+ try {
1479
+ setTimeout(() => {
1480
+ const activeDrmSessions = player.getActiveSessionsMetadata?.();
1481
+ if (activeDrmSessions) {
1482
+ const persistentSessions = activeDrmSessions.filter(
1483
+ (session) => session.sessionType === "persistent-license"
1484
+ );
1485
+ if (persistentSessions.length > 0) {
1486
+ const sessionsToStore = persistentSessions.map((session) => ({
1487
+ sessionId: session.sessionId,
1488
+ initData: session.initData,
1489
+ initDataType: session.initDataType,
1490
+ keySystem: session.keySystem || "com.widevine.alpha"
1491
+ // fallback
1492
+ }));
1493
+ storePersistentLicense(playlistId, src.drm.licenseCacheKey ?? "", sessionsToStore);
1494
+ }
1495
+ }
1496
+ }, 2e3);
1497
+ } catch (error) {
1498
+ console.warn("Failed to store persistent license sessions:", error);
1499
+ }
1500
+ }
1250
1501
  onPlayerReady?.(player);
1251
1502
  return player;
1252
1503
  } catch (error) {
@@ -1257,7 +1508,10 @@ var useShakePlayer = ({
1257
1508
  onError?.(error);
1258
1509
  throw error;
1259
1510
  }
1260
- }, [shakaConfig, drmConfig, src, onError, onPlayerReady, muxConfig, onMuxReady]);
1511
+ }, [shakaConfig, drmConfig, src, onError, onPlayerReady, muxConfig, onMuxReady, isRetrying, getManifestUrl]);
1512
+ const initializePlayer = useCallback(async (video) => {
1513
+ return initializePlayerInternal(video);
1514
+ }, [initializePlayerInternal]);
1261
1515
  const destroyPlayer = useCallback(async () => {
1262
1516
  if (playerRef.current) {
1263
1517
  try {
@@ -1272,7 +1526,8 @@ var useShakePlayer = ({
1272
1526
  return {
1273
1527
  playerRef,
1274
1528
  initializePlayer,
1275
- destroyPlayer
1529
+ destroyPlayer,
1530
+ isRetrying
1276
1531
  };
1277
1532
  };
1278
1533
 
@@ -1809,11 +2064,11 @@ var useEventHandlers = (videoRef, handlers) => {
1809
2064
  };
1810
2065
 
1811
2066
  // src/hooks/useLiveBadge.ts
1812
- import { useEffect, useState, useRef as useRef5 } from "react";
2067
+ import { useEffect, useState as useState2, useRef as useRef5 } from "react";
1813
2068
  var useLiveBadge = (playerRef, options = {}) => {
1814
- const [isLive, setIsLive] = useState(false);
1815
- const [isVisible, setIsVisible] = useState(false);
1816
- const [isNearLiveEdge, setIsNearLiveEdge] = useState(false);
2069
+ const [isLive, setIsLive] = useState2(false);
2070
+ const [isVisible, setIsVisible] = useState2(false);
2071
+ const [isNearLiveEdge, setIsNearLiveEdge] = useState2(false);
1817
2072
  const intervalRef = useRef5(null);
1818
2073
  const { enabled = true, onLiveStateChange, liveThresholdSeconds = 15 } = options;
1819
2074
  const checkLiveStatus = () => {
@@ -1900,7 +2155,7 @@ var useLiveBadge = (playerRef, options = {}) => {
1900
2155
  };
1901
2156
 
1902
2157
  // src/hooks/usePosterFallback.ts
1903
- import { useEffect as useEffect2, useState as useState2 } from "react";
2158
+ import { useEffect as useEffect2, useState as useState3 } from "react";
1904
2159
 
1905
2160
  // src/hooks/useLiveIndicator.ts
1906
2161
  import { useEffect as useEffect3, useRef as useRef7 } from "react";
@@ -3294,7 +3549,7 @@ var Player = forwardRef(
3294
3549
  const containerRef = useRef8(null);
3295
3550
  const adContainerRef = useRef8(null);
3296
3551
  useImperativeHandle(ref, () => videoRef.current, []);
3297
- const { playerRef, initializePlayer, destroyPlayer } = useShakePlayer({
3552
+ const { playerRef, initializePlayer, destroyPlayer, isRetrying } = useShakaPlayer({
3298
3553
  src,
3299
3554
  shakaConfig,
3300
3555
  drmConfig,
@@ -3671,7 +3926,7 @@ var getErrorType = (error, video) => {
3671
3926
  };
3672
3927
 
3673
3928
  // src/messages/useMessages.tsx
3674
- import { useState as useState3, useEffect as useEffect6 } from "react";
3929
+ import { useState as useState4, useEffect as useEffect6 } from "react";
3675
3930
 
3676
3931
  // src/messages/en.json
3677
3932
  var en_default = {
@@ -3973,8 +4228,8 @@ var getBrowserLanguage = () => {
3973
4228
  return availableLanguages[language] ? language : "en";
3974
4229
  };
3975
4230
  var useMessages = (locale) => {
3976
- const [language, setLanguage] = useState3("en");
3977
- const [translations, setTranslations] = useState3(availableLanguages.en);
4231
+ const [language, setLanguage] = useState4("en");
4232
+ const [translations, setTranslations] = useState4(availableLanguages.en);
3978
4233
  useEffect6(() => {
3979
4234
  const lang = !!availableLanguages?.[locale] ? locale : getBrowserLanguage();
3980
4235
  ;
@@ -4089,7 +4344,7 @@ var Video = ({
4089
4344
  };
4090
4345
 
4091
4346
  // src/Event.tsx
4092
- import { useCallback as useCallback9, useEffect as useEffect8, useState as useState4 } from "react";
4347
+ import { useCallback as useCallback9, useEffect as useEffect8, useState as useState5 } from "react";
4093
4348
  import { twMerge as twMerge4 } from "tailwind-merge";
4094
4349
  import { useQuery as useQuery2 } from "@tanstack/react-query";
4095
4350
  import { Fragment, jsx as jsx10, jsxs as jsxs8 } from "react/jsx-runtime";
@@ -4122,8 +4377,8 @@ var Event = ({
4122
4377
  retry: queryOptions.retry ?? 3,
4123
4378
  retryDelay: queryOptions.retryDelay ?? ((attemptIndex) => Math.min(1e3 * 2 ** attemptIndex, 3e4))
4124
4379
  });
4125
- const [activePlaylist, setActivePlaylist] = useState4();
4126
- const [activeVideoId, setActiveVideoId] = useState4();
4380
+ const [activePlaylist, setActivePlaylist] = useState5();
4381
+ const [activeVideoId, setActiveVideoId] = useState5();
4127
4382
  const videoIds = eventData?.videoIds ?? [];
4128
4383
  const {
4129
4384
  data: videosData,
@@ -4139,7 +4394,7 @@ var Event = ({
4139
4394
  retry: queryOptions.retry ?? 3,
4140
4395
  retryDelay: queryOptions.retryDelay ?? ((attemptIndex) => Math.min(1e3 * 2 ** attemptIndex, 3e4))
4141
4396
  });
4142
- const [loadingApisState, setLoadingApisState] = useState4(true);
4397
+ const [loadingApisState, setLoadingApisState] = useState5(true);
4143
4398
  useEffect8(() => {
4144
4399
  if (videosData !== void 0) {
4145
4400
  setLoadingApisState(false);
@@ -4149,9 +4404,11 @@ var Event = ({
4149
4404
  if (videosWithPlaylists.length > 0) {
4150
4405
  let hlsPlaylistFound = false;
4151
4406
  for (const video of videosWithPlaylists) {
4152
- const hlsPlaylist = findHLSPlaylist(video);
4153
- if (hlsPlaylist?.url) {
4154
- setActivePlaylist(hlsPlaylist);
4407
+ const activePlaylist2 = findHLSPlaylist(video);
4408
+ const activePlaylistUrl = activePlaylist2?.url ?? activePlaylist2?.drm?.widevine?.playlistUrl ?? activePlaylist2?.drm?.playready?.playlistUrl ?? activePlaylist2?.drm?.fairplay?.playlistUrl;
4409
+ const activePlaylistHasUrl = !!activePlaylistUrl;
4410
+ if (activePlaylist2 && activePlaylistHasUrl) {
4411
+ setActivePlaylist(activePlaylist2);
4155
4412
  setActiveVideoId(video.id);
4156
4413
  hlsPlaylistFound = true;
4157
4414
  break;
@@ -4185,8 +4442,8 @@ var Event = ({
4185
4442
  }
4186
4443
  }
4187
4444
  }, [activeVideoId, videosData, events]);
4188
- const [error, setError] = useState4(null);
4189
- const [loadingPlaylist, setLoadingPlaylist] = useState4(true);
4445
+ const [error, setError] = useState5(null);
4446
+ const [loadingPlaylist, setLoadingPlaylist] = useState5(true);
4190
4447
  const videosDataError = videosData?.some((video) => !!video.error);
4191
4448
  useEffect8(() => {
4192
4449
  if (isEventLoading || videosIsLoading || loadingApisState) {
@@ -4285,7 +4542,7 @@ function PreEvent({
4285
4542
  }) {
4286
4543
  const date = new Date(event.startTime);
4287
4544
  const now = /* @__PURE__ */ new Date();
4288
- const [remainingTime, setRemainingTime] = useState4(
4545
+ const [remainingTime, setRemainingTime] = useState5(
4289
4546
  date.getTime() - now.getTime()
4290
4547
  );
4291
4548
  const shouldBeStarted = remainingTime < 0;
@@ -4430,7 +4687,7 @@ var TitleAndDescription = ({
4430
4687
  };
4431
4688
 
4432
4689
  // src/CreativeWork.tsx
4433
- import { useEffect as useEffect9, useState as useState5 } from "react";
4690
+ import { useEffect as useEffect9, useState as useState6 } from "react";
4434
4691
  import { twMerge as twMerge5 } from "tailwind-merge";
4435
4692
  import { useQuery as useQuery3 } from "@tanstack/react-query";
4436
4693
  import { Fragment as Fragment2, jsx as jsx11, jsxs as jsxs9 } from "react/jsx-runtime";
@@ -4463,9 +4720,9 @@ var CreativeWork = ({
4463
4720
  retry: queryOptions.retry ?? 3,
4464
4721
  retryDelay: queryOptions.retryDelay ?? ((attemptIndex) => Math.min(1e3 * 2 ** attemptIndex, 3e4))
4465
4722
  });
4466
- const [activePlaylist, setActivePlaylist] = useState5();
4467
- const [activeVideoId, setActiveVideoId] = useState5();
4468
- const [showCountDown, setShowCountDown] = useState5(false);
4723
+ const [activePlaylist, setActivePlaylist] = useState6();
4724
+ const [activeVideoId, setActiveVideoId] = useState6();
4725
+ const [showCountDown, setShowCountDown] = useState6(false);
4469
4726
  const videoIds = creativeWorkData?.videoIds ?? [];
4470
4727
  const {
4471
4728
  data: videosData,
@@ -4481,7 +4738,7 @@ var CreativeWork = ({
4481
4738
  retry: queryOptions.retry ?? 3,
4482
4739
  retryDelay: queryOptions.retryDelay ?? ((attemptIndex) => Math.min(1e3 * 2 ** attemptIndex, 3e4))
4483
4740
  });
4484
- const [loadingApisState, setLoadingApisState] = useState5(true);
4741
+ const [loadingApisState, setLoadingApisState] = useState6(true);
4485
4742
  useEffect9(() => {
4486
4743
  if (videosData !== void 0) {
4487
4744
  setLoadingApisState(false);
@@ -4491,9 +4748,11 @@ var CreativeWork = ({
4491
4748
  if (videosWithPlaylists.length > 0) {
4492
4749
  let hlsPlaylistFound = false;
4493
4750
  for (const video of videosWithPlaylists) {
4494
- const hlsPlaylist = findHLSPlaylist(video);
4495
- if (hlsPlaylist?.url) {
4496
- setActivePlaylist(hlsPlaylist);
4751
+ const activePlaylist2 = findHLSPlaylist(video);
4752
+ const activePlaylistUrl = activePlaylist2?.url ?? activePlaylist2?.drm?.widevine?.playlistUrl ?? activePlaylist2?.drm?.playready?.playlistUrl ?? activePlaylist2?.drm?.fairplay?.playlistUrl;
4753
+ const activePlaylistHasUrl = !!activePlaylistUrl;
4754
+ if (activePlaylist2 && activePlaylistHasUrl) {
4755
+ setActivePlaylist(activePlaylist2);
4497
4756
  setActiveVideoId(video.id);
4498
4757
  hlsPlaylistFound = true;
4499
4758
  break;
@@ -4530,7 +4789,7 @@ var CreativeWork = ({
4530
4789
  }
4531
4790
  }
4532
4791
  }, [activeVideoId, videosData, events]);
4533
- const [error, setError] = useState5(null);
4792
+ const [error, setError] = useState6(null);
4534
4793
  const videosDataError = videosData?.some((video) => !!video.error);
4535
4794
  useEffect9(() => {
4536
4795
  if (creativeWorkError || videosError || videosDataError) {
@@ -4554,7 +4813,7 @@ var CreativeWork = ({
4554
4813
  }
4555
4814
  ) }) });
4556
4815
  }
4557
- const [loadingPlaylist, setLoadingPlaylist] = useState5(true);
4816
+ const [loadingPlaylist, setLoadingPlaylist] = useState6(true);
4558
4817
  useEffect9(() => {
4559
4818
  const creativeWorkLoadedWithNoVideos = !isCreativeWorkLoading && creativeWorkData && creativeWorkData.videoIds && creativeWorkData.videoIds.length === 0;
4560
4819
  const creativeWorkLoadedWithNoData = !isCreativeWorkLoading && creativeWorkData && !creativeWorkData.videoIds;
@@ -4631,7 +4890,7 @@ function PreCreativeWork({
4631
4890
  }) {
4632
4891
  const date = new Date(creativeWork.releaseTime);
4633
4892
  const now = /* @__PURE__ */ new Date();
4634
- const [remainingTime, setRemainingTime] = useState5(
4893
+ const [remainingTime, setRemainingTime] = useState6(
4635
4894
  date.getTime() - now.getTime()
4636
4895
  );
4637
4896
  const shouldBeStarted = remainingTime < 0;