@kkcompany/player 2.9.333 → 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,15 +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
- return isAndroid || /firefox/i.test(navigator.userAgent) ? '' : isSafari ? 'maybe' : 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');
281
294
  }
282
295
 
283
296
  const isDesktop = () => !getDevice().type; // TODO solve lint error:
@@ -377,38 +390,6 @@ const validateEnvironment = (supportEnvironmentList = []) => {
377
390
  }
378
391
  }; // Some touch devices with a mouse can't be distinguished, assume no mouse
379
392
 
380
- const timeoutError = () => new Error('request timeout');
381
- /**
382
- * @param {URL|RequestInfo} url
383
- * @param {RequestInit} options
384
- * @param {{responseType: 'json'|'text'}}
385
- */
386
-
387
-
388
- const retryRequest = (url, options = {}, {
389
- responseType = 'json',
390
- timeout = 6,
391
- retryTimes = 6
392
- } = {}) => new Promise((resolve, reject) => {
393
- setTimeout(() => reject(timeoutError()), timeout * 1000);
394
- fetch(url, options).then(response => {
395
- var _response$responseTyp;
396
-
397
- return resolve(((_response$responseTyp = response[responseType]) === null || _response$responseTyp === void 0 ? void 0 : _response$responseTyp.call(response)) || response);
398
- }).catch(reject);
399
- }).catch(error => {
400
- console.log(error);
401
-
402
- if (retryTimes > 0) {
403
- return retryRequest(url, options, {
404
- timeout,
405
- retryTimes: retryTimes - 1
406
- });
407
- }
408
-
409
- return error;
410
- });
411
-
412
393
  const protocolExtensions = {
413
394
  hls: 'm3u8',
414
395
  dash: 'mpd'
@@ -447,7 +428,7 @@ const getDrmOptions = fallbackDrm => {
447
428
  * @typedef {{hls: string, dash: string}} SourceObjectAlt backward compatiable form
448
429
  *
449
430
  * @param {SourceObject[]|SourceObject|SourceObjectAlt|string} sourceOptions
450
- * @param {{preferManifestType?: ('dash'|'hls')}} options
431
+ * @param {{preferManifestType?: ('dash'|'hls'|'platform')}} options
451
432
  * @return {{src: string, type: string, drm: Object}}
452
433
  */
453
434
 
@@ -490,7 +471,8 @@ const getSource = (sourceOptions, {
490
471
  });
491
472
  }
492
473
 
493
- 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));
494
476
  const selected = matched || sourceOptions[0];
495
477
 
496
478
  if (!selected) {
@@ -505,88 +487,6 @@ const getSource = (sourceOptions, {
505
487
  };
506
488
  };
507
489
 
508
- function getVersion() {
509
- try {
510
- // eslint-disable-next-line no-undef
511
- return "2.9.333";
512
- } catch (e) {
513
- return undefined;
514
- }
515
- }
516
-
517
- const matchAll = (input, pattern) => {
518
- const flags = [pattern.global && 'g', pattern.ignoreCase && 'i', pattern.multiline && 'm'].filter(Boolean).join('');
519
- const clone = new RegExp(pattern, flags);
520
- return Array.from(function* () {
521
- let matched = true;
522
-
523
- while (1) {
524
- matched = clone.exec(input);
525
-
526
- if (!matched) {
527
- return;
528
- }
529
-
530
- yield matched;
531
- }
532
- }());
533
- };
534
-
535
- 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(''));
536
-
537
- const filterHlsManifestQualities = (originalManifest, filter) => {
538
- if (!filter) {
539
- return;
540
- }
541
-
542
- const manifest = `${originalManifest}\n`;
543
- const profiles = matchAll(manifest, /RESOLUTION=(\d+)x(\d+)/g).map(([, width, height]) => ({
544
- width: +width,
545
- height: +height
546
- }));
547
- const allowed = filter(profiles) || profiles;
548
- 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 : '');
549
- return newManifest !== manifest && newManifest;
550
- };
551
-
552
- const meetRestriction = (quality, {
553
- minHeight,
554
- maxHeight
555
- } = {}) => !(quality.height < minHeight || quality.height > maxHeight);
556
-
557
- const selectHlsQualities = async (source, restrictions = {}) => {
558
- if (!needNativeHls() || !(restrictions.minHeight || restrictions.maxHeight)) {
559
- return source;
560
- }
561
-
562
- const selected = getSource(source, {
563
- preferManifestType: 'hls'
564
- });
565
-
566
- if (!((selected === null || selected === void 0 ? void 0 : selected.type.toLowerCase()) === mimeTypes.hls)) {
567
- return source;
568
- }
569
-
570
- const filtered = filterHlsManifestQualities(await retryRequest(selected.src, {}, {
571
- responseType: 'text'
572
- }), items => items.filter(item => meetRestriction(item, restrictions)));
573
-
574
- if (filtered) {
575
- return { ...selected,
576
-
577
- /*
578
- Native Safari couldn't support blob .m3u8. and will throw MediaError: 4
579
- We find the hacky method: dataURI.
580
- By the way, bitmovin also use this form even user gives the blob URI.
581
- */
582
- src: `data:application/x-mpegURL,${encodeURI(rewriteUrls(filtered, selected.src))}`
583
- };
584
- }
585
-
586
- return source;
587
- };
588
- // for unit test
589
-
590
490
  /* eslint-disable no-param-reassign */
591
491
 
592
492
  const SHAKA_LIVE_DURATION = 4294967296;
@@ -1088,6 +988,15 @@ const mapLogEvents$1 = ({
1088
988
  };
1089
989
  };
1090
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
+
1091
1000
  const logEventNames = {
1092
1001
  playbackBeganLoading: 'playback_began_player_loading',
1093
1002
  playbackBeganPlayerStartupTime: 'playback_began_player_startup_time',
@@ -1393,6 +1302,12 @@ const retrieveModuleConfig = (modulesConfig, query) => {
1393
1302
 
1394
1303
  /* eslint-disable camelcase */
1395
1304
  const HEARTBEAT_INTERVAL_MS = 10000;
1305
+ //@ts-ignore
1306
+ const axios$1 = {
1307
+ post: (...args) => {
1308
+ console.log(args);
1309
+ }
1310
+ }; // TODO
1396
1311
 
1397
1312
  const eventHeartbeat = ({
1398
1313
  token,
@@ -1425,7 +1340,7 @@ const eventHeartbeat = ({
1425
1340
  }; // Avoid template literals because the env variable would be replaced in the rollup
1426
1341
 
1427
1342
  await retryWithBackoff$1({
1428
- fn: () => axios.post(endpoint, payload, {
1343
+ fn: () => axios$1.post(endpoint, payload, {
1429
1344
  headers: {
1430
1345
  'Kks-Bv-Token': token
1431
1346
  }
@@ -1438,6 +1353,12 @@ var eventHeartbeat$1 = eventHeartbeat;
1438
1353
 
1439
1354
  /* eslint-disable camelcase */
1440
1355
 
1356
+ const axios = {
1357
+ post: (...args) => {
1358
+ console.log(args);
1359
+ }
1360
+ }; // TODO
1361
+
1441
1362
  const getDeviceInfo = () => {
1442
1363
  const browser = getBrowser();
1443
1364
  return {
@@ -1492,7 +1413,7 @@ const createAnalytics = ({
1492
1413
  const logTarget = mapLogEvents({
1493
1414
  video,
1494
1415
  playerName: 'shaka',
1495
- version: "2.9.333"
1416
+ version: "2.25.0-anary.15"
1496
1417
  });
1497
1418
  logTarget.all((type, data) => {
1498
1419
  const payload = {
@@ -1549,6 +1470,113 @@ const createAnalytics = ({
1549
1470
  };
1550
1471
  };
1551
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
+
1552
1580
  /* eslint-disable no-empty */
1553
1581
  const storageKey = 'playcraft-tab-lock';
1554
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
  });