@kkcompany/player 2.9.444 → 2.25.0-anary.15

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/modules.mjs CHANGED
@@ -1,18 +1,16 @@
1
- import axios from 'axios';
2
1
  import mitt from 'mitt';
3
2
  import UAParser from 'ua-parser-js';
4
3
 
5
4
  /* eslint-disable no-param-reassign */
6
-
7
5
  const waitMs$1 = time => new Promise(resolve => {
8
6
  setTimeout(resolve, time);
9
7
  });
10
8
 
11
- const handleRequestError = (result, {
9
+ const handleRequestError = (request, {
12
10
  onError,
13
11
  retryTimes = 0
14
- }) => result.catch(error => onError(error, {
15
- retry: () => handleRequestError(axios(error.config), {
12
+ }) => request().catch(error => onError(error, {
13
+ retry: () => handleRequestError(request, {
16
14
  onError,
17
15
  retryTimes: retryTimes + 1
18
16
  }),
@@ -23,7 +21,7 @@ const ignoreMinorError = async (event, {
23
21
  retry,
24
22
  retryTimes
25
23
  } = {}) => {
26
- var _event$response, _event$response2, _event$config, _event$config2;
24
+ var _event$response, _event$response2, _event$response3;
27
25
 
28
26
  console.warn(event);
29
27
 
@@ -32,17 +30,34 @@ const ignoreMinorError = async (event, {
32
30
  return retry();
33
31
  }
34
32
 
35
- if (/start$|info$|heartbeat$/.test((_event$config = event.config) === null || _event$config === void 0 ? void 0 : _event$config.url)) {
33
+ const url = new URL(((_event$response3 = event.response) === null || _event$response3 === void 0 ? void 0 : _event$response3.url) || 'http://unknown/');
34
+
35
+ if (/start$|info$|heartbeat$/.test(url.pathname)) {
36
36
  return Promise.reject(event);
37
37
  }
38
38
 
39
- if (/end$/.test((_event$config2 = event.config) === null || _event$config2 === void 0 ? void 0 : _event$config2.url)) {
39
+ if (/end$/.test(url.pathname)) {
40
40
  return Promise.resolve();
41
41
  }
42
42
 
43
43
  console.log('Ignore non-critical playback API fail', event);
44
44
  return new Promise(() => {});
45
45
  };
46
+ /** @param {Response} response */
47
+
48
+
49
+ const handleFetchResponse = response => {
50
+ if (response.ok) {
51
+ return response.status === 200 ? response.json() : '';
52
+ }
53
+
54
+ return response.json().then(errorData => {
55
+ const error = new Error(`HTTP error status: ${response.status} ${errorData.message}`);
56
+ error.data = errorData;
57
+ error.response = response;
58
+ return Promise.reject(error);
59
+ });
60
+ };
46
61
 
47
62
  const createApi = (config, {
48
63
  onError = ignoreMinorError
@@ -67,28 +82,26 @@ const createApi = (config, {
67
82
 
68
83
  const request = (url, {
69
84
  method
70
- } = {}) => handleRequestError(axios(url, {
85
+ } = {}) => handleRequestError(() => fetch(`${url}?${new URLSearchParams(params).toString()}`, {
71
86
  method,
72
- headers: getHeaders(),
73
- params
74
- }), {
87
+ headers: getHeaders()
88
+ }).then(handleFetchResponse), {
75
89
  onError
76
- }).then(response => response.data);
90
+ });
77
91
 
78
92
  const sessionRequest = (path, {
79
93
  method = 'POST',
80
94
  type,
81
95
  id,
82
96
  token
83
- }) => handleRequestError(axios(`${host}/sessions/${type}/${id}/playback/${deviceId}/${path}`, {
97
+ }) => handleRequestError(() => fetch(`${host}/sessions/${type}/${id}/playback/${deviceId}/${path}?${new URLSearchParams({ ...params,
98
+ playback_token: token
99
+ }).toString()}`, {
84
100
  method,
85
- headers: getHeaders(),
86
- params: { ...params,
87
- playback_token: token
88
- }
89
- }), {
101
+ headers: getHeaders()
102
+ }).then(handleFetchResponse), {
90
103
  onError
91
- }).then(response => response === null || response === void 0 ? void 0 : response.data);
104
+ });
92
105
 
93
106
  return {
94
107
  config,
@@ -269,28 +282,15 @@ function getDevice() {
269
282
  function getBrowser() {
270
283
  return parser.getBrowser();
271
284
  }
285
+
286
+ const isSafari = () => /^((?!chrome|android|X11|Linux).)*(safari|iPad|iPhone|Version)/i.test(navigator.userAgent);
287
+
272
288
  function needNativeHls() {
273
289
  // Don't let Android phones play HLS, even if some of them report supported
274
290
  // This covers Samsung & OPPO special cases
275
- const isAndroid = /android|X11|Linux/i.test(navigator.userAgent); // canPlayType isn't reliable across all iOS verion / device combinations, so also check user agent
276
-
277
- const isSafari = /^((?!chrome|android|X11|Linux).)*(safari|iPad|iPhone|Version)/i.test(navigator.userAgent); // ref: https://stackoverflow.com/a/12905122/4578017
278
- // none of our supported browsers other than Safari response to this
279
-
280
- const isFirefox = /firefox/i.test(navigator.userAgent);
281
- const isEdge = /edg/i.test(navigator.userAgent);
282
- const isChrome = /chrome/i.test(navigator.userAgent) && !isEdge; // ref: https://stackoverflow.com/a/12905122/4578017
283
- // none of our supported browsers other than Safari response to this
284
-
285
- if (isAndroid || isFirefox || isEdge || isChrome) {
286
- return "";
287
- }
288
-
289
- if (isSafari) {
290
- return 'maybe';
291
- }
292
-
293
- return document.createElement('video').canPlayType('application/vnd.apple.mpegURL');
291
+ const isAndroid = /android|X11|Linux/i.test(navigator.userAgent);
292
+ return isAndroid || /firefox/i.test(navigator.userAgent) ? '' : // canPlayType isn't reliable across all iOS verion / device combinations, so also check user agent
293
+ isSafari() ? 'maybe' : document.createElement('video').canPlayType('application/vnd.apple.mpegURL');
294
294
  }
295
295
 
296
296
  const isDesktop = () => !getDevice().type; // TODO solve lint error:
@@ -390,38 +390,6 @@ const validateEnvironment = (supportEnvironmentList = []) => {
390
390
  }
391
391
  }; // Some touch devices with a mouse can't be distinguished, assume no mouse
392
392
 
393
- const timeoutError = () => new Error('request timeout');
394
- /**
395
- * @param {URL|RequestInfo} url
396
- * @param {RequestInit} options
397
- * @param {{responseType: 'json'|'text'}}
398
- */
399
-
400
-
401
- const retryRequest = (url, options = {}, {
402
- responseType = 'json',
403
- timeout = 6,
404
- retryTimes = 6
405
- } = {}) => new Promise((resolve, reject) => {
406
- setTimeout(() => reject(timeoutError()), timeout * 1000);
407
- fetch(url, options).then(response => {
408
- var _response$responseTyp;
409
-
410
- return resolve(((_response$responseTyp = response[responseType]) === null || _response$responseTyp === void 0 ? void 0 : _response$responseTyp.call(response)) || response);
411
- }).catch(reject);
412
- }).catch(error => {
413
- console.log(error);
414
-
415
- if (retryTimes > 0) {
416
- return retryRequest(url, options, {
417
- timeout,
418
- retryTimes: retryTimes - 1
419
- });
420
- }
421
-
422
- return error;
423
- });
424
-
425
393
  const protocolExtensions = {
426
394
  hls: 'm3u8',
427
395
  dash: 'mpd'
@@ -460,7 +428,7 @@ const getDrmOptions = fallbackDrm => {
460
428
  * @typedef {{hls: string, dash: string}} SourceObjectAlt backward compatiable form
461
429
  *
462
430
  * @param {SourceObject[]|SourceObject|SourceObjectAlt|string} sourceOptions
463
- * @param {{preferManifestType?: ('dash'|'hls')}} options
431
+ * @param {{preferManifestType?: ('dash'|'hls'|'platform')}} options
464
432
  * @return {{src: string, type: string, drm: Object}}
465
433
  */
466
434
 
@@ -503,7 +471,8 @@ const getSource = (sourceOptions, {
503
471
  });
504
472
  }
505
473
 
506
- const matched = sourceOptions.find(source => !preferManifestType || matchType(source, preferManifestType));
474
+ const targetType = preferManifestType !== 'platform' ? preferManifestType : isSafari() ? 'hls' : 'dash';
475
+ const matched = sourceOptions.find(source => matchType(source, targetType));
507
476
  const selected = matched || sourceOptions[0];
508
477
 
509
478
  if (!selected) {
@@ -518,88 +487,6 @@ const getSource = (sourceOptions, {
518
487
  };
519
488
  };
520
489
 
521
- function getVersion() {
522
- try {
523
- // eslint-disable-next-line no-undef
524
- return "2.9.444";
525
- } catch (e) {
526
- return undefined;
527
- }
528
- }
529
-
530
- const matchAll = (input, pattern) => {
531
- const flags = [pattern.global && 'g', pattern.ignoreCase && 'i', pattern.multiline && 'm'].filter(Boolean).join('');
532
- const clone = new RegExp(pattern, flags);
533
- return Array.from(function* () {
534
- let matched = true;
535
-
536
- while (1) {
537
- matched = clone.exec(input);
538
-
539
- if (!matched) {
540
- return;
541
- }
542
-
543
- yield matched;
544
- }
545
- }());
546
- };
547
-
548
- const rewriteUrls = (manifest, sourceUrl) => manifest.replace(/((#EXT-X-MEDIA:.*URI=")([^"]*))|((#EXT-X-STREAM-INF.*\n)(.*)(?=\n))/g, (...matches) => [matches[2], matches[5], new URL(matches[3] || matches[6], sourceUrl)].filter(Boolean).join(''));
549
-
550
- const filterHlsManifestQualities = (originalManifest, filter) => {
551
- if (!filter) {
552
- return;
553
- }
554
-
555
- const manifest = `${originalManifest}\n`;
556
- const profiles = matchAll(manifest, /RESOLUTION=(\d+)x(\d+)/g).map(([, width, height]) => ({
557
- width: +width,
558
- height: +height
559
- }));
560
- const allowed = filter(profiles) || profiles;
561
- const newManifest = manifest.replace(/#EXT-X-STREAM-INF.*RESOLUTION=(\d+)x(\d+).*\n.*\n/g, (item, width, height) => allowed.some(p => p.width === +width && p.height === +height) ? item : '');
562
- return newManifest !== manifest && newManifest;
563
- };
564
-
565
- const meetRestriction = (quality, {
566
- minHeight,
567
- maxHeight
568
- } = {}) => !(quality.height < minHeight || quality.height > maxHeight);
569
-
570
- const selectHlsQualities = async (source, restrictions = {}) => {
571
- if (!needNativeHls() || !(restrictions.minHeight || restrictions.maxHeight)) {
572
- return source;
573
- }
574
-
575
- const selected = getSource(source, {
576
- preferManifestType: 'hls'
577
- });
578
-
579
- if (!((selected === null || selected === void 0 ? void 0 : selected.type.toLowerCase()) === mimeTypes.hls)) {
580
- return source;
581
- }
582
-
583
- const filtered = filterHlsManifestQualities(await retryRequest(selected.src, {}, {
584
- responseType: 'text'
585
- }), items => items.filter(item => meetRestriction(item, restrictions)));
586
-
587
- if (filtered) {
588
- return { ...selected,
589
-
590
- /*
591
- Native Safari couldn't support blob .m3u8. and will throw MediaError: 4
592
- We find the hacky method: dataURI.
593
- By the way, bitmovin also use this form even user gives the blob URI.
594
- */
595
- src: `data:application/x-mpegURL,${encodeURI(rewriteUrls(filtered, selected.src))}`
596
- };
597
- }
598
-
599
- return source;
600
- };
601
- // for unit test
602
-
603
490
  /* eslint-disable no-param-reassign */
604
491
 
605
492
  const SHAKA_LIVE_DURATION = 4294967296;
@@ -1101,6 +988,15 @@ const mapLogEvents$1 = ({
1101
988
  };
1102
989
  };
1103
990
 
991
+ function getVersion() {
992
+ try {
993
+ // eslint-disable-next-line no-undef
994
+ return "2.25.0-anary.15";
995
+ } catch (e) {
996
+ return undefined;
997
+ }
998
+ }
999
+
1104
1000
  const logEventNames = {
1105
1001
  playbackBeganLoading: 'playback_began_player_loading',
1106
1002
  playbackBeganPlayerStartupTime: 'playback_began_player_startup_time',
@@ -1406,6 +1302,12 @@ const retrieveModuleConfig = (modulesConfig, query) => {
1406
1302
 
1407
1303
  /* eslint-disable camelcase */
1408
1304
  const HEARTBEAT_INTERVAL_MS = 10000;
1305
+ //@ts-ignore
1306
+ const axios$1 = {
1307
+ post: (...args) => {
1308
+ console.log(args);
1309
+ }
1310
+ }; // TODO
1409
1311
 
1410
1312
  const eventHeartbeat = ({
1411
1313
  token,
@@ -1438,7 +1340,7 @@ const eventHeartbeat = ({
1438
1340
  }; // Avoid template literals because the env variable would be replaced in the rollup
1439
1341
 
1440
1342
  await retryWithBackoff$1({
1441
- fn: () => axios.post(endpoint, payload, {
1343
+ fn: () => axios$1.post(endpoint, payload, {
1442
1344
  headers: {
1443
1345
  'Kks-Bv-Token': token
1444
1346
  }
@@ -1451,6 +1353,12 @@ var eventHeartbeat$1 = eventHeartbeat;
1451
1353
 
1452
1354
  /* eslint-disable camelcase */
1453
1355
 
1356
+ const axios = {
1357
+ post: (...args) => {
1358
+ console.log(args);
1359
+ }
1360
+ }; // TODO
1361
+
1454
1362
  const getDeviceInfo = () => {
1455
1363
  const browser = getBrowser();
1456
1364
  return {
@@ -1505,7 +1413,7 @@ const createAnalytics = ({
1505
1413
  const logTarget = mapLogEvents({
1506
1414
  video,
1507
1415
  playerName: 'shaka',
1508
- version: "2.9.444"
1416
+ version: "2.25.0-anary.15"
1509
1417
  });
1510
1418
  logTarget.all((type, data) => {
1511
1419
  const payload = {
@@ -1562,6 +1470,113 @@ const createAnalytics = ({
1562
1470
  };
1563
1471
  };
1564
1472
 
1473
+ const timeoutError = () => new Error('request timeout');
1474
+ /**
1475
+ * @param {URL|RequestInfo} url
1476
+ * @param {RequestInit} options
1477
+ * @param {{responseType: 'json'|'text'}}
1478
+ */
1479
+
1480
+
1481
+ const retryRequest = (url, options = {}, {
1482
+ responseType = 'json',
1483
+ timeout = 6,
1484
+ retryTimes = 6
1485
+ } = {}) => new Promise((resolve, reject) => {
1486
+ setTimeout(() => reject(timeoutError()), timeout * 1000);
1487
+ fetch(url, options).then(response => {
1488
+ var _response$responseTyp;
1489
+
1490
+ return resolve(((_response$responseTyp = response[responseType]) === null || _response$responseTyp === void 0 ? void 0 : _response$responseTyp.call(response)) || response);
1491
+ }).catch(reject);
1492
+ }).catch(error => {
1493
+ console.log(error);
1494
+
1495
+ if (retryTimes > 0) {
1496
+ return retryRequest(url, options, {
1497
+ timeout,
1498
+ retryTimes: retryTimes - 1
1499
+ });
1500
+ }
1501
+
1502
+ return error;
1503
+ });
1504
+
1505
+ /* eslint-disable no-param-reassign */
1506
+
1507
+ const matchAll = (input, pattern) => {
1508
+ const flags = [pattern.global && 'g', pattern.ignoreCase && 'i', pattern.multiline && 'm'].filter(Boolean).join('');
1509
+ const clone = new RegExp(pattern, flags);
1510
+ return Array.from(function* () {
1511
+ let matched = true;
1512
+
1513
+ while (1) {
1514
+ matched = clone.exec(input);
1515
+
1516
+ if (!matched) {
1517
+ return;
1518
+ }
1519
+
1520
+ yield matched;
1521
+ }
1522
+ }());
1523
+ };
1524
+
1525
+ const rewriteUrls = (manifest, sourceUrl) => manifest.replace(/((#EXT-X-MEDIA:.*URI=")([^"]*))|((#EXT-X-STREAM-INF.*\n)(.*)(?=\n))/g, (...matches) => [matches[2], matches[5], new URL(matches[3] || matches[6], sourceUrl)].filter(Boolean).join(''));
1526
+
1527
+ const filterHlsManifestQualities = (originalManifest, filter) => {
1528
+ if (!filter) {
1529
+ return;
1530
+ }
1531
+
1532
+ const manifest = `${originalManifest}\n`;
1533
+ const profiles = matchAll(manifest, /RESOLUTION=(\d+)x(\d+)/g).map(([, width, height]) => ({
1534
+ width: +width,
1535
+ height: +height
1536
+ }));
1537
+ const allowed = filter(profiles) || profiles;
1538
+ const newManifest = manifest.replace(/#EXT-X-STREAM-INF.*RESOLUTION=(\d+)x(\d+).*\n.*\n/g, (item, width, height) => allowed.some(p => p.width === +width && p.height === +height) ? item : '');
1539
+ return newManifest !== manifest && newManifest;
1540
+ };
1541
+
1542
+ const meetRestriction = (quality, {
1543
+ minHeight,
1544
+ maxHeight
1545
+ } = {}) => !(quality.height < minHeight || quality.height > maxHeight);
1546
+
1547
+ const selectHlsQualities = async (source, restrictions = {}) => {
1548
+ if (!isSafari() || !(restrictions.minHeight || restrictions.maxHeight)) {
1549
+ return source;
1550
+ }
1551
+
1552
+ const selected = getSource(source, {
1553
+ preferManifestType: 'hls'
1554
+ });
1555
+
1556
+ if (!((selected === null || selected === void 0 ? void 0 : selected.type.toLowerCase()) === mimeTypes.hls)) {
1557
+ return source;
1558
+ }
1559
+
1560
+ const filtered = filterHlsManifestQualities(await retryRequest(selected.src, {}, {
1561
+ responseType: 'text'
1562
+ }), items => items.filter(item => meetRestriction(item, restrictions)));
1563
+
1564
+ if (filtered) {
1565
+ return { ...selected,
1566
+
1567
+ /*
1568
+ Native Safari couldn't support blob .m3u8. and will throw MediaError: 4
1569
+ We find the hacky method: dataURI.
1570
+ By the way, bitmovin also use this form even user gives the blob URI.
1571
+ */
1572
+ src: `data:application/x-mpegURL,${encodeURI(rewriteUrls(filtered, selected.src))}`
1573
+ };
1574
+ }
1575
+
1576
+ return source;
1577
+ };
1578
+ // for unit test
1579
+
1565
1580
  /* eslint-disable no-empty */
1566
1581
  const storageKey = 'playcraft-tab-lock';
1567
1582
  const lockRenewTime = 3000;
package/dist/plugins.mjs CHANGED
@@ -1,5 +1,4 @@
1
1
  import mitt from 'mitt';
2
- import axios from 'axios';
3
2
  import UAParser from 'ua-parser-js';
4
3
 
5
4
  /** @param {string} m3u8Manifest */
@@ -487,13 +486,13 @@ const snapback = ({
487
486
  }
488
487
  };
489
488
 
489
+ const axios = () => {};
490
+
490
491
  const addFetchPolyfill = () => {
491
492
  window.fetch = async (url, {
492
493
  method
493
494
  } = {}) => {
494
- const result = await axios(url, {
495
- method
496
- });
495
+ const result = await axios();
497
496
  return Promise.resolve({
498
497
  json: () => result.data
499
498
  });