@kkcompany/player 2.25.0-canary.2 → 2.25.0-canary.20
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/CHANGELOG.md +26 -22
- package/dist/core.mjs +670 -95
- package/dist/index.js +9444 -8684
- package/dist/index.mjs +882 -211
- package/dist/modules.mjs +139 -122
- package/dist/react.mjs +905 -217
- package/package.json +1 -1
package/dist/modules.mjs
CHANGED
|
@@ -21,7 +21,7 @@ const ignoreMinorError = async (event, {
|
|
|
21
21
|
retry,
|
|
22
22
|
retryTimes
|
|
23
23
|
} = {}) => {
|
|
24
|
-
var _event$response, _event$response2, _event$
|
|
24
|
+
var _event$response, _event$response2, _event$response3;
|
|
25
25
|
|
|
26
26
|
console.warn(event);
|
|
27
27
|
|
|
@@ -30,17 +30,34 @@ const ignoreMinorError = async (event, {
|
|
|
30
30
|
return retry();
|
|
31
31
|
}
|
|
32
32
|
|
|
33
|
-
|
|
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)) {
|
|
34
36
|
return Promise.reject(event);
|
|
35
37
|
}
|
|
36
38
|
|
|
37
|
-
if (/end$/.test(
|
|
39
|
+
if (/end$/.test(url.pathname)) {
|
|
38
40
|
return Promise.resolve();
|
|
39
41
|
}
|
|
40
42
|
|
|
41
43
|
console.log('Ignore non-critical playback API fail', event);
|
|
42
44
|
return new Promise(() => {});
|
|
43
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
|
+
};
|
|
44
61
|
|
|
45
62
|
const createApi = (config, {
|
|
46
63
|
onError = ignoreMinorError
|
|
@@ -68,7 +85,7 @@ const createApi = (config, {
|
|
|
68
85
|
} = {}) => handleRequestError(() => fetch(`${url}?${new URLSearchParams(params).toString()}`, {
|
|
69
86
|
method,
|
|
70
87
|
headers: getHeaders()
|
|
71
|
-
}).then(
|
|
88
|
+
}).then(handleFetchResponse), {
|
|
72
89
|
onError
|
|
73
90
|
});
|
|
74
91
|
|
|
@@ -82,7 +99,7 @@ const createApi = (config, {
|
|
|
82
99
|
}).toString()}`, {
|
|
83
100
|
method,
|
|
84
101
|
headers: getHeaders()
|
|
85
|
-
}).then(
|
|
102
|
+
}).then(handleFetchResponse), {
|
|
86
103
|
onError
|
|
87
104
|
});
|
|
88
105
|
|
|
@@ -373,38 +390,6 @@ const validateEnvironment = (supportEnvironmentList = []) => {
|
|
|
373
390
|
}
|
|
374
391
|
}; // Some touch devices with a mouse can't be distinguished, assume no mouse
|
|
375
392
|
|
|
376
|
-
const timeoutError = () => new Error('request timeout');
|
|
377
|
-
/**
|
|
378
|
-
* @param {URL|RequestInfo} url
|
|
379
|
-
* @param {RequestInit} options
|
|
380
|
-
* @param {{responseType: 'json'|'text'}}
|
|
381
|
-
*/
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
const retryRequest = (url, options = {}, {
|
|
385
|
-
responseType = 'json',
|
|
386
|
-
timeout = 6,
|
|
387
|
-
retryTimes = 6
|
|
388
|
-
} = {}) => new Promise((resolve, reject) => {
|
|
389
|
-
setTimeout(() => reject(timeoutError()), timeout * 1000);
|
|
390
|
-
fetch(url, options).then(response => {
|
|
391
|
-
var _response$responseTyp;
|
|
392
|
-
|
|
393
|
-
return resolve(((_response$responseTyp = response[responseType]) === null || _response$responseTyp === void 0 ? void 0 : _response$responseTyp.call(response)) || response);
|
|
394
|
-
}).catch(reject);
|
|
395
|
-
}).catch(error => {
|
|
396
|
-
console.log(error);
|
|
397
|
-
|
|
398
|
-
if (retryTimes > 0) {
|
|
399
|
-
return retryRequest(url, options, {
|
|
400
|
-
timeout,
|
|
401
|
-
retryTimes: retryTimes - 1
|
|
402
|
-
});
|
|
403
|
-
}
|
|
404
|
-
|
|
405
|
-
return error;
|
|
406
|
-
});
|
|
407
|
-
|
|
408
393
|
const protocolExtensions = {
|
|
409
394
|
hls: 'm3u8',
|
|
410
395
|
dash: 'mpd'
|
|
@@ -502,90 +487,6 @@ const getSource = (sourceOptions, {
|
|
|
502
487
|
};
|
|
503
488
|
};
|
|
504
489
|
|
|
505
|
-
function getVersion() {
|
|
506
|
-
try {
|
|
507
|
-
// eslint-disable-next-line no-undef
|
|
508
|
-
return "2.25.0-canary.2";
|
|
509
|
-
} catch (e) {
|
|
510
|
-
return undefined;
|
|
511
|
-
}
|
|
512
|
-
}
|
|
513
|
-
|
|
514
|
-
/* eslint-disable no-param-reassign */
|
|
515
|
-
|
|
516
|
-
const matchAll = (input, pattern) => {
|
|
517
|
-
const flags = [pattern.global && 'g', pattern.ignoreCase && 'i', pattern.multiline && 'm'].filter(Boolean).join('');
|
|
518
|
-
const clone = new RegExp(pattern, flags);
|
|
519
|
-
return Array.from(function* () {
|
|
520
|
-
let matched = true;
|
|
521
|
-
|
|
522
|
-
while (1) {
|
|
523
|
-
matched = clone.exec(input);
|
|
524
|
-
|
|
525
|
-
if (!matched) {
|
|
526
|
-
return;
|
|
527
|
-
}
|
|
528
|
-
|
|
529
|
-
yield matched;
|
|
530
|
-
}
|
|
531
|
-
}());
|
|
532
|
-
};
|
|
533
|
-
|
|
534
|
-
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(''));
|
|
535
|
-
|
|
536
|
-
const filterHlsManifestQualities = (originalManifest, filter) => {
|
|
537
|
-
if (!filter) {
|
|
538
|
-
return;
|
|
539
|
-
}
|
|
540
|
-
|
|
541
|
-
const manifest = `${originalManifest}\n`;
|
|
542
|
-
const profiles = matchAll(manifest, /RESOLUTION=(\d+)x(\d+)/g).map(([, width, height]) => ({
|
|
543
|
-
width: +width,
|
|
544
|
-
height: +height
|
|
545
|
-
}));
|
|
546
|
-
const allowed = filter(profiles) || profiles;
|
|
547
|
-
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 : '');
|
|
548
|
-
return newManifest !== manifest && newManifest;
|
|
549
|
-
};
|
|
550
|
-
|
|
551
|
-
const meetRestriction = (quality, {
|
|
552
|
-
minHeight,
|
|
553
|
-
maxHeight
|
|
554
|
-
} = {}) => !(quality.height < minHeight || quality.height > maxHeight);
|
|
555
|
-
|
|
556
|
-
const selectHlsQualities = async (source, restrictions = {}) => {
|
|
557
|
-
if (!needNativeHls() || !(restrictions.minHeight || restrictions.maxHeight)) {
|
|
558
|
-
return source;
|
|
559
|
-
}
|
|
560
|
-
|
|
561
|
-
const selected = getSource(source, {
|
|
562
|
-
preferManifestType: 'hls'
|
|
563
|
-
});
|
|
564
|
-
|
|
565
|
-
if (!((selected === null || selected === void 0 ? void 0 : selected.type.toLowerCase()) === mimeTypes.hls)) {
|
|
566
|
-
return source;
|
|
567
|
-
}
|
|
568
|
-
|
|
569
|
-
const filtered = filterHlsManifestQualities(await retryRequest(selected.src, {}, {
|
|
570
|
-
responseType: 'text'
|
|
571
|
-
}), items => items.filter(item => meetRestriction(item, restrictions)));
|
|
572
|
-
|
|
573
|
-
if (filtered) {
|
|
574
|
-
return { ...selected,
|
|
575
|
-
|
|
576
|
-
/*
|
|
577
|
-
Native Safari couldn't support blob .m3u8. and will throw MediaError: 4
|
|
578
|
-
We find the hacky method: dataURI.
|
|
579
|
-
By the way, bitmovin also use this form even user gives the blob URI.
|
|
580
|
-
*/
|
|
581
|
-
src: `data:application/x-mpegURL,${encodeURI(rewriteUrls(filtered, selected.src))}`
|
|
582
|
-
};
|
|
583
|
-
}
|
|
584
|
-
|
|
585
|
-
return source;
|
|
586
|
-
};
|
|
587
|
-
// for unit test
|
|
588
|
-
|
|
589
490
|
/* eslint-disable no-param-reassign */
|
|
590
491
|
|
|
591
492
|
const SHAKA_LIVE_DURATION = 4294967296;
|
|
@@ -1087,6 +988,15 @@ const mapLogEvents$1 = ({
|
|
|
1087
988
|
};
|
|
1088
989
|
};
|
|
1089
990
|
|
|
991
|
+
function getVersion() {
|
|
992
|
+
try {
|
|
993
|
+
// eslint-disable-next-line no-undef
|
|
994
|
+
return "2.25.0-canary.20";
|
|
995
|
+
} catch (e) {
|
|
996
|
+
return undefined;
|
|
997
|
+
}
|
|
998
|
+
}
|
|
999
|
+
|
|
1090
1000
|
const logEventNames = {
|
|
1091
1001
|
playbackBeganLoading: 'playback_began_player_loading',
|
|
1092
1002
|
playbackBeganPlayerStartupTime: 'playback_began_player_startup_time',
|
|
@@ -1503,7 +1413,7 @@ const createAnalytics = ({
|
|
|
1503
1413
|
const logTarget = mapLogEvents({
|
|
1504
1414
|
video,
|
|
1505
1415
|
playerName: 'shaka',
|
|
1506
|
-
version: "2.25.0-canary.
|
|
1416
|
+
version: "2.25.0-canary.20"
|
|
1507
1417
|
});
|
|
1508
1418
|
logTarget.all((type, data) => {
|
|
1509
1419
|
const payload = {
|
|
@@ -1560,6 +1470,113 @@ const createAnalytics = ({
|
|
|
1560
1470
|
};
|
|
1561
1471
|
};
|
|
1562
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
|
+
|
|
1563
1580
|
/* eslint-disable no-empty */
|
|
1564
1581
|
const storageKey = 'playcraft-tab-lock';
|
|
1565
1582
|
const lockRenewTime = 3000;
|