@kkcompany/player 2.25.0-canary.1 → 2.25.0-canary.11
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 +59 -0
- package/dist/core.mjs +5 -95
- package/dist/index.js +7656 -7422
- package/dist/index.mjs +729 -496
- package/dist/modules.mjs +163 -136
- package/dist/plugins.mjs +3 -4
- package/dist/react.mjs +605 -380
- package/package.json +1 -2
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,65 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
|
|
4
4
|
|
|
5
|
+
## [2.25.0-canary.11](https://gitlab.kkinternal.com/playback/web-playcraft/compare/v2.25.0-canary.10...v2.25.0-canary.11) (2025-12-05)
|
|
6
|
+
|
|
7
|
+
## [2.25.0-canary.10](https://gitlab.kkinternal.com/playback/web-playcraft/compare/v2.25.0-canary.9...v2.25.0-canary.10) (2025-12-05)
|
|
8
|
+
|
|
9
|
+
## [2.25.0-canary.9](https://gitlab.kkinternal.com/playback/web-playcraft/compare/v2.25.0-canary.8...v2.25.0-canary.9) (2025-12-04)
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
### Features
|
|
13
|
+
|
|
14
|
+
* **premium:** enable audio/text track control ([41d7dd3](https://gitlab.kkinternal.com/playback/web-playcraft/commit/41d7dd3776ab1b5e82b4612605394bb98e22e3b0))
|
|
15
|
+
* subtitle off option is changed to 'none' ([029a41a](https://gitlab.kkinternal.com/playback/web-playcraft/commit/029a41a6e6f69847c01665ca4bd31f9ef77073a7))
|
|
16
|
+
|
|
17
|
+
## [2.25.0-canary.8](https://gitlab.kkinternal.com/playback/web-playcraft/compare/v2.25.0-canary.7...v2.25.0-canary.8) (2025-11-28)
|
|
18
|
+
|
|
19
|
+
## [2.25.0-canary.7](https://gitlab.kkinternal.com/playback/web-playcraft/compare/v2.25.0-canary.6...v2.25.0-canary.7) (2025-11-28)
|
|
20
|
+
|
|
21
|
+
## [2.25.0-canary.6](https://gitlab.kkinternal.com/playback/web-playcraft/compare/v2.25.0-canary.5...v2.25.0-canary.6) (2025-11-28)
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
### Features
|
|
25
|
+
|
|
26
|
+
* add back other sections ([a4d8961](https://gitlab.kkinternal.com/playback/web-playcraft/commit/a4d8961b2985cb0811f619529c92302dde73d9ad))
|
|
27
|
+
|
|
28
|
+
## [2.25.0-canary.5](https://gitlab.kkinternal.com/playback/web-playcraft/compare/v2.25.0-canary.3...v2.25.0-canary.5) (2025-11-25)
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
### Bug Fixes
|
|
32
|
+
|
|
33
|
+
* playback api response handling ([dfe5a5f](https://gitlab.kkinternal.com/playback/web-playcraft/commit/dfe5a5fd60ee7dc0155e63a796df6afe337c4a3d))
|
|
34
|
+
|
|
35
|
+
## [2.25.0-canary.3](https://gitlab.kkinternal.com/playback/web-playcraft/compare/v2.25.0-canary.2...v2.25.0-canary.3) (2025-11-21)
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
### Features
|
|
39
|
+
|
|
40
|
+
* display language menu only when options are available ([f02fbc7](https://gitlab.kkinternal.com/playback/web-playcraft/commit/f02fbc775f351dff406139f2e9f2c2451441de31))
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
### Bug Fixes
|
|
44
|
+
|
|
45
|
+
* undefined audio setting options ([3e4e5ab](https://gitlab.kkinternal.com/playback/web-playcraft/commit/3e4e5ab521b56ba349d7be8416cc98f70ca404ed))
|
|
46
|
+
|
|
47
|
+
## [2.25.0-canary.2](https://gitlab.kkinternal.com/playback/web-playcraft/compare/v2.25.0-canary.1...v2.25.0-canary.2) (2025-11-21)
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
### Features
|
|
51
|
+
|
|
52
|
+
* add change setting support to new audio/subtitle menu ([97728db](https://gitlab.kkinternal.com/playback/web-playcraft/commit/97728dbdc5f223cfccc18818cb5afa3b17be36d3))
|
|
53
|
+
* custom language menu item order ([6bba6dc](https://gitlab.kkinternal.com/playback/web-playcraft/commit/6bba6dc3c137c292eb890ebefcdc49cf1d155d21))
|
|
54
|
+
* display audio / subtitle options even if there's only 1 ([2e23915](https://gitlab.kkinternal.com/playback/web-playcraft/commit/2e23915d7aa7d084b65c9729c8ac468690852eb3))
|
|
55
|
+
* enable custom language menu ([fb2038d](https://gitlab.kkinternal.com/playback/web-playcraft/commit/fb2038da7fc3ea399bad3fbb4b7e1eb1c7bb49f0))
|
|
56
|
+
* export MenuItem + styles of LanguageMenu for custom menu component ([4f37d2e](https://gitlab.kkinternal.com/playback/web-playcraft/commit/4f37d2ed793287885e69dead576ceb1cecbe3320))
|
|
57
|
+
* **ui:** add close button to mobile language menu ([6704ce1](https://gitlab.kkinternal.com/playback/web-playcraft/commit/6704ce14b13e8e5f344615ca43220b3b8f79b5f8))
|
|
58
|
+
* enable custom setting menu sections with slotProps ([013fb63](https://gitlab.kkinternal.com/playback/web-playcraft/commit/013fb6393d7cc17502db6ef36b8b6d9492787529))
|
|
59
|
+
* integrate new audio/subtitle menu to player UI ([d0944cb](https://gitlab.kkinternal.com/playback/web-playcraft/commit/d0944cb469342ae5eb84cd212a17835559e25115))
|
|
60
|
+
* **ui:** add LanguageMenu component ([3ec5456](https://gitlab.kkinternal.com/playback/web-playcraft/commit/3ec5456eb1003b9374505e53bde56d967fef0b68))
|
|
61
|
+
* **ui:** add OverlayPanel for custom setting menu ([dede035](https://gitlab.kkinternal.com/playback/web-playcraft/commit/dede03515b414c7e4afe7b6cb9c687097d46e920))
|
|
62
|
+
* **ui:** add subtitles icon ([e771220](https://gitlab.kkinternal.com/playback/web-playcraft/commit/e7712208a8594aaf7211d55445fb5d4519e776e3))
|
|
63
|
+
|
|
5
64
|
## [2.25.0-canary.1](https://gitlab.kkinternal.com/playback/web-playcraft/compare/v2.9.20...v2.25.0-canary.1) (2025-11-21)
|
|
6
65
|
|
|
7
66
|
|
package/dist/core.mjs
CHANGED
|
@@ -4,14 +4,6 @@ import UAParser from 'ua-parser-js';
|
|
|
4
4
|
new UAParser();
|
|
5
5
|
|
|
6
6
|
const isSafari = () => /^((?!chrome|android|X11|Linux).)*(safari|iPad|iPhone|Version)/i.test(navigator.userAgent);
|
|
7
|
-
|
|
8
|
-
function needNativeHls() {
|
|
9
|
-
// Don't let Android phones play HLS, even if some of them report supported
|
|
10
|
-
// This covers Samsung & OPPO special cases
|
|
11
|
-
const isAndroid = /android|X11|Linux/i.test(navigator.userAgent);
|
|
12
|
-
return isAndroid || /firefox/i.test(navigator.userAgent) ? '' : // canPlayType isn't reliable across all iOS verion / device combinations, so also check user agent
|
|
13
|
-
isSafari() ? 'maybe' : document.createElement('video').canPlayType('application/vnd.apple.mpegURL');
|
|
14
|
-
}
|
|
15
7
|
// navigator.maxTouchPoints() is not supported in Safari 11, iOS Safari 11.0-11.2 compat/compat
|
|
16
8
|
|
|
17
9
|
|
|
@@ -45,7 +37,7 @@ const waitFor = (check, handler) => {
|
|
|
45
37
|
function getVersion() {
|
|
46
38
|
try {
|
|
47
39
|
// eslint-disable-next-line no-undef
|
|
48
|
-
return "2.25.0-canary.
|
|
40
|
+
return "2.25.0-canary.11";
|
|
49
41
|
} catch (e) {
|
|
50
42
|
return undefined;
|
|
51
43
|
}
|
|
@@ -1828,11 +1820,6 @@ const loadShaka = async (videoElement, config = {}, options = {}) => {
|
|
|
1828
1820
|
},
|
|
1829
1821
|
getPlaybackSpeed: () => videoElement.playbackRate,
|
|
1830
1822
|
getVideoElement: () => videoElement,
|
|
1831
|
-
setQuality: restrictions => {
|
|
1832
|
-
if (!restrictions) return; // FIXME: Setting restrictions to {} cannot enable abr.
|
|
1833
|
-
|
|
1834
|
-
player.configure('abr.restrictions', restrictions);
|
|
1835
|
-
},
|
|
1836
1823
|
getVideoQuality,
|
|
1837
1824
|
getAvailableVideoQualities,
|
|
1838
1825
|
isAlive: () => player.getLoadMode() !== shaka.Player.LoadMode.DESTROYED,
|
|
@@ -1842,38 +1829,6 @@ const loadShaka = async (videoElement, config = {}, options = {}) => {
|
|
|
1842
1829
|
return player;
|
|
1843
1830
|
};
|
|
1844
1831
|
|
|
1845
|
-
const timeoutError = () => new Error('request timeout');
|
|
1846
|
-
/**
|
|
1847
|
-
* @param {URL|RequestInfo} url
|
|
1848
|
-
* @param {RequestInit} options
|
|
1849
|
-
* @param {{responseType: 'json'|'text'}}
|
|
1850
|
-
*/
|
|
1851
|
-
|
|
1852
|
-
|
|
1853
|
-
const retryRequest = (url, options = {}, {
|
|
1854
|
-
responseType = 'json',
|
|
1855
|
-
timeout = 6,
|
|
1856
|
-
retryTimes = 6
|
|
1857
|
-
} = {}) => new Promise((resolve, reject) => {
|
|
1858
|
-
setTimeout(() => reject(timeoutError()), timeout * 1000);
|
|
1859
|
-
fetch(url, options).then(response => {
|
|
1860
|
-
var _response$responseTyp;
|
|
1861
|
-
|
|
1862
|
-
return resolve(((_response$responseTyp = response[responseType]) === null || _response$responseTyp === void 0 ? void 0 : _response$responseTyp.call(response)) || response);
|
|
1863
|
-
}).catch(reject);
|
|
1864
|
-
}).catch(error => {
|
|
1865
|
-
console.log(error);
|
|
1866
|
-
|
|
1867
|
-
if (retryTimes > 0) {
|
|
1868
|
-
return retryRequest(url, options, {
|
|
1869
|
-
timeout,
|
|
1870
|
-
retryTimes: retryTimes - 1
|
|
1871
|
-
});
|
|
1872
|
-
}
|
|
1873
|
-
|
|
1874
|
-
return error;
|
|
1875
|
-
});
|
|
1876
|
-
|
|
1877
1832
|
const protocolExtensions = {
|
|
1878
1833
|
hls: 'm3u8',
|
|
1879
1834
|
dash: 'mpd'
|
|
@@ -2026,32 +1981,6 @@ const getDrmOptions = source => {
|
|
|
2026
1981
|
}];
|
|
2027
1982
|
};
|
|
2028
1983
|
|
|
2029
|
-
const matchAll = (input, pattern) => {
|
|
2030
|
-
const flags = [pattern.global && 'g', pattern.ignoreCase && 'i', pattern.multiline && 'm'].filter(Boolean).join('');
|
|
2031
|
-
const clone = new RegExp(pattern, flags);
|
|
2032
|
-
return Array.from(function* () {
|
|
2033
|
-
let matched = true;
|
|
2034
|
-
|
|
2035
|
-
while (1) {
|
|
2036
|
-
matched = clone.exec(input);
|
|
2037
|
-
|
|
2038
|
-
if (!matched) {
|
|
2039
|
-
return;
|
|
2040
|
-
}
|
|
2041
|
-
|
|
2042
|
-
yield matched;
|
|
2043
|
-
}
|
|
2044
|
-
}());
|
|
2045
|
-
};
|
|
2046
|
-
|
|
2047
|
-
const getHlsQualityOptions = manifest => {
|
|
2048
|
-
const resolutionList = matchAll(manifest, /RESOLUTION=\d+x(\d+)/g);
|
|
2049
|
-
return Array.from(new Set(resolutionList.map(([, height]) => ({
|
|
2050
|
-
height: +height
|
|
2051
|
-
})))).sort((a, b) => b.height - a.height);
|
|
2052
|
-
};
|
|
2053
|
-
// for unit test
|
|
2054
|
-
|
|
2055
1984
|
/* eslint-disable no-param-reassign */
|
|
2056
1985
|
// when the gap is small enough, we consider it is on edge.
|
|
2057
1986
|
// The magic number 10s comes from observation of YouTube
|
|
@@ -2065,7 +1994,7 @@ const isLiveDuration = duration => duration >= SHAKA_LIVE_DURATION;
|
|
|
2065
1994
|
const isEnded = media => !isLiveDuration(media.initialDuration) && media.initialDuration - media.currentTime < 1; // When donwload bandwidth is low, Safari may report time update while buffering, ignore it.
|
|
2066
1995
|
|
|
2067
1996
|
|
|
2068
|
-
const isBuffered = media =>
|
|
1997
|
+
const isBuffered = media => isSafari() || Array.from({
|
|
2069
1998
|
length: media.buffered.length
|
|
2070
1999
|
}, (_, index) => ({
|
|
2071
2000
|
start: media.buffered.start(index),
|
|
@@ -2221,22 +2150,6 @@ const subscribePlaybackState = (media, updateState, {
|
|
|
2221
2150
|
return () => registered.forEach(off => off());
|
|
2222
2151
|
};
|
|
2223
2152
|
|
|
2224
|
-
const tryPatchHlsVideoQualities = async (player, hlsUrl) => {
|
|
2225
|
-
if (/(^data)|(mp4$)/.test(hlsUrl)) {
|
|
2226
|
-
return;
|
|
2227
|
-
} // filtered manifest comes with data URI and should be ignored
|
|
2228
|
-
|
|
2229
|
-
|
|
2230
|
-
const manifest = await retryRequest(hlsUrl, {}, {
|
|
2231
|
-
responseType: 'text'
|
|
2232
|
-
}).catch(e => console.warn('Failed to get HLS video qualities', e));
|
|
2233
|
-
const videoQualities = getHlsQualityOptions(manifest);
|
|
2234
|
-
|
|
2235
|
-
if (videoQualities) {
|
|
2236
|
-
player.getAvailableVideoQualities = () => videoQualities;
|
|
2237
|
-
}
|
|
2238
|
-
};
|
|
2239
|
-
|
|
2240
2153
|
const seek = async (media, {
|
|
2241
2154
|
player,
|
|
2242
2155
|
plugins = []
|
|
@@ -2386,10 +2299,6 @@ const load = async (media, {
|
|
|
2386
2299
|
loadStartTime = merged.startTime;
|
|
2387
2300
|
}
|
|
2388
2301
|
|
|
2389
|
-
if (merged.type === 'application/x-mpegurl') {
|
|
2390
|
-
await tryPatchHlsVideoQualities(player, merged.src);
|
|
2391
|
-
}
|
|
2392
|
-
|
|
2393
2302
|
return player.unload().then(() => player.load(merged.src, loadStartTime, merged.type)).then(loadResult => {
|
|
2394
2303
|
getSourceText(source).forEach(({
|
|
2395
2304
|
src,
|
|
@@ -2461,7 +2370,7 @@ const loadPlayer = async (videoElement, {
|
|
|
2461
2370
|
// TODO unsubscribe to release the video element
|
|
2462
2371
|
// when resuming from background, video may play without no media events
|
|
2463
2372
|
// on some iOS devices, pause again to workaround
|
|
2464
|
-
if (
|
|
2373
|
+
if (isIOS()) {
|
|
2465
2374
|
on(document, 'visibilitychange', () => setTimeout(() => videoElement.pause(), 50));
|
|
2466
2375
|
}
|
|
2467
2376
|
|
|
@@ -2491,7 +2400,8 @@ const loadPlayer = async (videoElement, {
|
|
|
2491
2400
|
|
|
2492
2401
|
reloadOnLiveStall(videoElement, {
|
|
2493
2402
|
reload: () => player.reload()
|
|
2494
|
-
});
|
|
2403
|
+
});
|
|
2404
|
+
player.preferredSettings = {}; // TODO load built-in modules here
|
|
2495
2405
|
|
|
2496
2406
|
player.modules = {};
|
|
2497
2407
|
return player;
|