@kkcompany/player 2.25.0-canary.0 → 2.25.0-canary.10
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 +55 -7
- package/dist/core.mjs +11 -99
- package/dist/index.js +8567 -8627
- package/dist/index.mjs +429 -483
- package/dist/modules.mjs +148 -130
- package/dist/react.mjs +269 -306
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,27 +2,74 @@
|
|
|
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.
|
|
5
|
+
## [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)
|
|
6
|
+
|
|
7
|
+
## [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)
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
### Features
|
|
11
|
+
|
|
12
|
+
* **premium:** enable audio/text track control ([41d7dd3](https://gitlab.kkinternal.com/playback/web-playcraft/commit/41d7dd3776ab1b5e82b4612605394bb98e22e3b0))
|
|
13
|
+
* subtitle off option is changed to 'none' ([029a41a](https://gitlab.kkinternal.com/playback/web-playcraft/commit/029a41a6e6f69847c01665ca4bd31f9ef77073a7))
|
|
14
|
+
|
|
15
|
+
## [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)
|
|
16
|
+
|
|
17
|
+
## [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)
|
|
18
|
+
|
|
19
|
+
## [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)
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
### Features
|
|
23
|
+
|
|
24
|
+
* add back other sections ([a4d8961](https://gitlab.kkinternal.com/playback/web-playcraft/commit/a4d8961b2985cb0811f619529c92302dde73d9ad))
|
|
25
|
+
|
|
26
|
+
## [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)
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
### Bug Fixes
|
|
30
|
+
|
|
31
|
+
* playback api response handling ([dfe5a5f](https://gitlab.kkinternal.com/playback/web-playcraft/commit/dfe5a5fd60ee7dc0155e63a796df6afe337c4a3d))
|
|
32
|
+
|
|
33
|
+
## [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)
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
### Features
|
|
37
|
+
|
|
38
|
+
* display language menu only when options are available ([f02fbc7](https://gitlab.kkinternal.com/playback/web-playcraft/commit/f02fbc775f351dff406139f2e9f2c2451441de31))
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
### Bug Fixes
|
|
42
|
+
|
|
43
|
+
* undefined audio setting options ([3e4e5ab](https://gitlab.kkinternal.com/playback/web-playcraft/commit/3e4e5ab521b56ba349d7be8416cc98f70ca404ed))
|
|
44
|
+
|
|
45
|
+
## [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)
|
|
6
46
|
|
|
7
47
|
|
|
8
48
|
### Features
|
|
9
49
|
|
|
10
|
-
* add castMedia export with error handling added ([82aa0b6](https://gitlab.kkinternal.com/playback/web-playcraft/commit/82aa0b608aad2f2e5c638b20ca3254298ec77291))
|
|
11
50
|
* add change setting support to new audio/subtitle menu ([97728db](https://gitlab.kkinternal.com/playback/web-playcraft/commit/97728dbdc5f223cfccc18818cb5afa3b17be36d3))
|
|
12
|
-
*
|
|
51
|
+
* custom language menu item order ([6bba6dc](https://gitlab.kkinternal.com/playback/web-playcraft/commit/6bba6dc3c137c292eb890ebefcdc49cf1d155d21))
|
|
13
52
|
* display audio / subtitle options even if there's only 1 ([2e23915](https://gitlab.kkinternal.com/playback/web-playcraft/commit/2e23915d7aa7d084b65c9729c8ac468690852eb3))
|
|
14
53
|
* enable custom language menu ([fb2038d](https://gitlab.kkinternal.com/playback/web-playcraft/commit/fb2038da7fc3ea399bad3fbb4b7e1eb1c7bb49f0))
|
|
15
|
-
* enable custom setting menu sections with slotProps ([013fb63](https://gitlab.kkinternal.com/playback/web-playcraft/commit/013fb6393d7cc17502db6ef36b8b6d9492787529))
|
|
16
54
|
* export MenuItem + styles of LanguageMenu for custom menu component ([4f37d2e](https://gitlab.kkinternal.com/playback/web-playcraft/commit/4f37d2ed793287885e69dead576ceb1cecbe3320))
|
|
17
|
-
* **text:** add style for shaka player text display container ([39e62ec](https://gitlab.kkinternal.com/playback/web-playcraft/commit/39e62eccf99f394d12d682cd3b4a1a5ad1a398b3))
|
|
18
|
-
* **text:** patch vertical text display style ([7725796](https://gitlab.kkinternal.com/playback/web-playcraft/commit/7725796e0d5ef77a6728c88296519eb809f090c5))
|
|
19
|
-
* **text:** remove extra styles from ruby/rt to display properly ([4c77c61](https://gitlab.kkinternal.com/playback/web-playcraft/commit/4c77c61436a28fbdcc69e2bde0cd670681f7fadb))
|
|
20
55
|
* **ui:** add close button to mobile language menu ([6704ce1](https://gitlab.kkinternal.com/playback/web-playcraft/commit/6704ce14b13e8e5f344615ca43220b3b8f79b5f8))
|
|
56
|
+
* enable custom setting menu sections with slotProps ([013fb63](https://gitlab.kkinternal.com/playback/web-playcraft/commit/013fb6393d7cc17502db6ef36b8b6d9492787529))
|
|
21
57
|
* integrate new audio/subtitle menu to player UI ([d0944cb](https://gitlab.kkinternal.com/playback/web-playcraft/commit/d0944cb469342ae5eb84cd212a17835559e25115))
|
|
22
58
|
* **ui:** add LanguageMenu component ([3ec5456](https://gitlab.kkinternal.com/playback/web-playcraft/commit/3ec5456eb1003b9374505e53bde56d967fef0b68))
|
|
23
59
|
* **ui:** add OverlayPanel for custom setting menu ([dede035](https://gitlab.kkinternal.com/playback/web-playcraft/commit/dede03515b414c7e4afe7b6cb9c687097d46e920))
|
|
24
60
|
* **ui:** add subtitles icon ([e771220](https://gitlab.kkinternal.com/playback/web-playcraft/commit/e7712208a8594aaf7211d55445fb5d4519e776e3))
|
|
61
|
+
|
|
62
|
+
## [2.25.0-canary.1](https://gitlab.kkinternal.com/playback/web-playcraft/compare/v2.9.20...v2.25.0-canary.1) (2025-11-21)
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
### Features
|
|
66
|
+
|
|
25
67
|
* add support of external text track / subtitle ([2d2aa9f](https://gitlab.kkinternal.com/playback/web-playcraft/commit/2d2aa9f8b624749795b76f80551dbeca40359a79))
|
|
68
|
+
* **text:** add style for shaka player text display container ([39e62ec](https://gitlab.kkinternal.com/playback/web-playcraft/commit/39e62eccf99f394d12d682cd3b4a1a5ad1a398b3))
|
|
69
|
+
* **text:** patch vertical text display style ([7725796](https://gitlab.kkinternal.com/playback/web-playcraft/commit/7725796e0d5ef77a6728c88296519eb809f090c5))
|
|
70
|
+
* **text:** remove extra styles from ruby/rt to display properly ([4c77c61](https://gitlab.kkinternal.com/playback/web-playcraft/commit/4c77c61436a28fbdcc69e2bde0cd670681f7fadb))
|
|
71
|
+
* add castMedia export with error handling added ([82aa0b6](https://gitlab.kkinternal.com/playback/web-playcraft/commit/82aa0b608aad2f2e5c638b20ca3254298ec77291))
|
|
72
|
+
* basic HLS on MSE ([b02c6f0](https://gitlab.kkinternal.com/playback/web-playcraft/commit/b02c6f0f44a89000aed9f279c1715bb4d0d115dc))
|
|
26
73
|
* enable Shaka player built-in text/subtitle display ([47375d6](https://gitlab.kkinternal.com/playback/web-playcraft/commit/47375d639a94df07e0919a79560f0202540f46fa))
|
|
27
74
|
* expose audio track info ([87426d7](https://gitlab.kkinternal.com/playback/web-playcraft/commit/87426d710262baaa347e07ef7c21cd129671d834))
|
|
28
75
|
* give subtitle a bottom magin while controller is hidden ([6444f6a](https://gitlab.kkinternal.com/playback/web-playcraft/commit/6444f6a5bfe9ed6a040c78e8317a67bcf136fa41))
|
|
@@ -44,6 +91,7 @@ All notable changes to this project will be documented in this file. See [standa
|
|
|
44
91
|
* load sender framework only while the application id exists ([0b0caa9](https://gitlab.kkinternal.com/playback/web-playcraft/commit/0b0caa9e1546af4e2bb5ad6fbed1170dcfe460bd))
|
|
45
92
|
* maintain text track / subtitle setting after Safari quality switch ([74837cc](https://gitlab.kkinternal.com/playback/web-playcraft/commit/74837cc7ec3c7ec7d93f46d37e73e00810878985))
|
|
46
93
|
* match subtitle value as off while subtitle is undefined ([4f8ebd2](https://gitlab.kkinternal.com/playback/web-playcraft/commit/4f8ebd2bfbde374215ec08ff4e3594c78f382799))
|
|
94
|
+
* select DASH/HLS base on DRM key system availablity ([623e1e2](https://gitlab.kkinternal.com/playback/web-playcraft/commit/623e1e2ca77b7313e1ec845b391e4c92166686b8))
|
|
47
95
|
* turn off subtitles when starting playback in iOS browsers ([9afbbf1](https://gitlab.kkinternal.com/playback/web-playcraft/commit/9afbbf1516b0007435153311418c1afc2bcba3df))
|
|
48
96
|
* **core:** provide audio tracks without duplicate variantTracks ([799525d](https://gitlab.kkinternal.com/playback/web-playcraft/commit/799525d8b2e7af4417849ac6517ba194644dd720))
|
|
49
97
|
* should use track.label instead of .name ([249b606](https://gitlab.kkinternal.com/playback/web-playcraft/commit/249b6064d8ed444917aaa0d0465269f7610f111d))
|
package/dist/core.mjs
CHANGED
|
@@ -2,16 +2,8 @@ import UAParser from 'ua-parser-js';
|
|
|
2
2
|
|
|
3
3
|
/* eslint-disable no-plusplus */
|
|
4
4
|
new UAParser();
|
|
5
|
-
function needNativeHls() {
|
|
6
|
-
// Don't let Android phones play HLS, even if some of them report supported
|
|
7
|
-
// This covers Samsung & OPPO special cases
|
|
8
|
-
const isAndroid = /android|X11|Linux/i.test(navigator.userAgent); // canPlayType isn't reliable across all iOS verion / device combinations, so also check user agent
|
|
9
5
|
|
|
10
|
-
|
|
11
|
-
// none of our supported browsers other than Safari response to this
|
|
12
|
-
|
|
13
|
-
return isAndroid || /firefox/i.test(navigator.userAgent) ? '' : isSafari ? 'maybe' : document.createElement('video').canPlayType('application/vnd.apple.mpegURL');
|
|
14
|
-
}
|
|
6
|
+
const isSafari = () => /^((?!chrome|android|X11|Linux).)*(safari|iPad|iPhone|Version)/i.test(navigator.userAgent);
|
|
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.10";
|
|
49
41
|
} catch (e) {
|
|
50
42
|
return undefined;
|
|
51
43
|
}
|
|
@@ -1675,7 +1667,7 @@ const loadShaka = async (videoElement, config = {}, options = {}) => {
|
|
|
1675
1667
|
// See: https://github.com/shaka-project/shaka-player/issues/3526
|
|
1676
1668
|
safeSeekOffset: 0,
|
|
1677
1669
|
rebufferingGoal: 0,
|
|
1678
|
-
...(
|
|
1670
|
+
...(isSafari() && {
|
|
1679
1671
|
preferNativeHls: true
|
|
1680
1672
|
}),
|
|
1681
1673
|
...config.streaming
|
|
@@ -1767,7 +1759,7 @@ const loadShaka = async (videoElement, config = {}, options = {}) => {
|
|
|
1767
1759
|
responseHandlers: [rewriteDashManifest]
|
|
1768
1760
|
};
|
|
1769
1761
|
|
|
1770
|
-
if (
|
|
1762
|
+
if (isSafari()) {
|
|
1771
1763
|
setupKKFariplay(player, extensionOptions);
|
|
1772
1764
|
}
|
|
1773
1765
|
|
|
@@ -1837,38 +1829,6 @@ const loadShaka = async (videoElement, config = {}, options = {}) => {
|
|
|
1837
1829
|
return player;
|
|
1838
1830
|
};
|
|
1839
1831
|
|
|
1840
|
-
const timeoutError = () => new Error('request timeout');
|
|
1841
|
-
/**
|
|
1842
|
-
* @param {URL|RequestInfo} url
|
|
1843
|
-
* @param {RequestInit} options
|
|
1844
|
-
* @param {{responseType: 'json'|'text'}}
|
|
1845
|
-
*/
|
|
1846
|
-
|
|
1847
|
-
|
|
1848
|
-
const retryRequest = (url, options = {}, {
|
|
1849
|
-
responseType = 'json',
|
|
1850
|
-
timeout = 6,
|
|
1851
|
-
retryTimes = 6
|
|
1852
|
-
} = {}) => new Promise((resolve, reject) => {
|
|
1853
|
-
setTimeout(() => reject(timeoutError()), timeout * 1000);
|
|
1854
|
-
fetch(url, options).then(response => {
|
|
1855
|
-
var _response$responseTyp;
|
|
1856
|
-
|
|
1857
|
-
return resolve(((_response$responseTyp = response[responseType]) === null || _response$responseTyp === void 0 ? void 0 : _response$responseTyp.call(response)) || response);
|
|
1858
|
-
}).catch(reject);
|
|
1859
|
-
}).catch(error => {
|
|
1860
|
-
console.log(error);
|
|
1861
|
-
|
|
1862
|
-
if (retryTimes > 0) {
|
|
1863
|
-
return retryRequest(url, options, {
|
|
1864
|
-
timeout,
|
|
1865
|
-
retryTimes: retryTimes - 1
|
|
1866
|
-
});
|
|
1867
|
-
}
|
|
1868
|
-
|
|
1869
|
-
return error;
|
|
1870
|
-
});
|
|
1871
|
-
|
|
1872
1832
|
const protocolExtensions = {
|
|
1873
1833
|
hls: 'm3u8',
|
|
1874
1834
|
dash: 'mpd'
|
|
@@ -1907,7 +1867,7 @@ const getDrmOptions$1 = fallbackDrm => {
|
|
|
1907
1867
|
* @typedef {{hls: string, dash: string}} SourceObjectAlt backward compatiable form
|
|
1908
1868
|
*
|
|
1909
1869
|
* @param {SourceObject[]|SourceObject|SourceObjectAlt|string} sourceOptions
|
|
1910
|
-
* @param {{preferManifestType?: ('dash'|'hls')}} options
|
|
1870
|
+
* @param {{preferManifestType?: ('dash'|'hls'|'platform')}} options
|
|
1911
1871
|
* @return {{src: string, type: string, drm: Object}}
|
|
1912
1872
|
*/
|
|
1913
1873
|
|
|
@@ -1950,7 +1910,8 @@ const getSource = (sourceOptions, {
|
|
|
1950
1910
|
});
|
|
1951
1911
|
}
|
|
1952
1912
|
|
|
1953
|
-
const
|
|
1913
|
+
const targetType = preferManifestType !== 'platform' ? preferManifestType : isSafari() ? 'hls' : 'dash';
|
|
1914
|
+
const matched = sourceOptions.find(source => matchType(source, targetType));
|
|
1954
1915
|
const selected = matched || sourceOptions[0];
|
|
1955
1916
|
|
|
1956
1917
|
if (!selected) {
|
|
@@ -2020,34 +1981,6 @@ const getDrmOptions = source => {
|
|
|
2020
1981
|
}];
|
|
2021
1982
|
};
|
|
2022
1983
|
|
|
2023
|
-
/* eslint-disable no-param-reassign */
|
|
2024
|
-
|
|
2025
|
-
const matchAll = (input, pattern) => {
|
|
2026
|
-
const flags = [pattern.global && 'g', pattern.ignoreCase && 'i', pattern.multiline && 'm'].filter(Boolean).join('');
|
|
2027
|
-
const clone = new RegExp(pattern, flags);
|
|
2028
|
-
return Array.from(function* () {
|
|
2029
|
-
let matched = true;
|
|
2030
|
-
|
|
2031
|
-
while (1) {
|
|
2032
|
-
matched = clone.exec(input);
|
|
2033
|
-
|
|
2034
|
-
if (!matched) {
|
|
2035
|
-
return;
|
|
2036
|
-
}
|
|
2037
|
-
|
|
2038
|
-
yield matched;
|
|
2039
|
-
}
|
|
2040
|
-
}());
|
|
2041
|
-
};
|
|
2042
|
-
|
|
2043
|
-
const getHlsQualityOptions = manifest => {
|
|
2044
|
-
const resolutionList = matchAll(manifest, /RESOLUTION=\d+x(\d+)/g);
|
|
2045
|
-
return Array.from(new Set(resolutionList.map(([, height]) => ({
|
|
2046
|
-
height: +height
|
|
2047
|
-
})))).sort((a, b) => b.height - a.height);
|
|
2048
|
-
};
|
|
2049
|
-
// for unit test
|
|
2050
|
-
|
|
2051
1984
|
/* eslint-disable no-param-reassign */
|
|
2052
1985
|
// when the gap is small enough, we consider it is on edge.
|
|
2053
1986
|
// The magic number 10s comes from observation of YouTube
|
|
@@ -2061,7 +1994,7 @@ const isLiveDuration = duration => duration >= SHAKA_LIVE_DURATION;
|
|
|
2061
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.
|
|
2062
1995
|
|
|
2063
1996
|
|
|
2064
|
-
const isBuffered = media =>
|
|
1997
|
+
const isBuffered = media => isSafari() || Array.from({
|
|
2065
1998
|
length: media.buffered.length
|
|
2066
1999
|
}, (_, index) => ({
|
|
2067
2000
|
start: media.buffered.start(index),
|
|
@@ -2217,22 +2150,6 @@ const subscribePlaybackState = (media, updateState, {
|
|
|
2217
2150
|
return () => registered.forEach(off => off());
|
|
2218
2151
|
};
|
|
2219
2152
|
|
|
2220
|
-
const tryPatchHlsVideoQualities = async (player, hlsUrl) => {
|
|
2221
|
-
if (/(^data)|(mp4$)/.test(hlsUrl)) {
|
|
2222
|
-
return;
|
|
2223
|
-
} // filtered manifest comes with data URI and should be ignored
|
|
2224
|
-
|
|
2225
|
-
|
|
2226
|
-
const manifest = await retryRequest(hlsUrl, {}, {
|
|
2227
|
-
responseType: 'text'
|
|
2228
|
-
}).catch(e => console.warn('Failed to get HLS video qualities', e));
|
|
2229
|
-
const videoQualities = getHlsQualityOptions(manifest);
|
|
2230
|
-
|
|
2231
|
-
if (videoQualities) {
|
|
2232
|
-
player.getVariantTracks = () => videoQualities;
|
|
2233
|
-
}
|
|
2234
|
-
};
|
|
2235
|
-
|
|
2236
2153
|
const seek = async (media, {
|
|
2237
2154
|
player,
|
|
2238
2155
|
plugins = []
|
|
@@ -2288,9 +2205,8 @@ const load = async (media, {
|
|
|
2288
2205
|
startTime,
|
|
2289
2206
|
plugins = []
|
|
2290
2207
|
}, source) => {
|
|
2291
|
-
const preferManifestType = needNativeHls() ? 'hls' : 'dash';
|
|
2292
2208
|
const preferred = getSource(source, {
|
|
2293
|
-
preferManifestType
|
|
2209
|
+
preferManifestType: 'platform'
|
|
2294
2210
|
}); // There's no use case that changing DRM options without changing manifest URL, just skip
|
|
2295
2211
|
|
|
2296
2212
|
if (player.lastSrc === (preferred === null || preferred === void 0 ? void 0 : preferred.src)) {
|
|
@@ -2310,7 +2226,7 @@ const load = async (media, {
|
|
|
2310
2226
|
player,
|
|
2311
2227
|
source: currentSource,
|
|
2312
2228
|
startTime,
|
|
2313
|
-
streamFormat:
|
|
2229
|
+
streamFormat: source.type,
|
|
2314
2230
|
reload: async () => {
|
|
2315
2231
|
// Bitmovin unexpectedly restores muted state, so save to restore
|
|
2316
2232
|
const restoreMuted = player.isMuted && {
|
|
@@ -2383,10 +2299,6 @@ const load = async (media, {
|
|
|
2383
2299
|
loadStartTime = merged.startTime;
|
|
2384
2300
|
}
|
|
2385
2301
|
|
|
2386
|
-
if (needNativeHls() && merged.type === 'application/x-mpegurl') {
|
|
2387
|
-
await tryPatchHlsVideoQualities(player, merged.src);
|
|
2388
|
-
}
|
|
2389
|
-
|
|
2390
2302
|
return player.unload().then(() => player.load(merged.src, loadStartTime, merged.type)).then(loadResult => {
|
|
2391
2303
|
getSourceText(source).forEach(({
|
|
2392
2304
|
src,
|
|
@@ -2458,7 +2370,7 @@ const loadPlayer = async (videoElement, {
|
|
|
2458
2370
|
// TODO unsubscribe to release the video element
|
|
2459
2371
|
// when resuming from background, video may play without no media events
|
|
2460
2372
|
// on some iOS devices, pause again to workaround
|
|
2461
|
-
if (
|
|
2373
|
+
if (isIOS()) {
|
|
2462
2374
|
on(document, 'visibilitychange', () => setTimeout(() => videoElement.pause(), 50));
|
|
2463
2375
|
}
|
|
2464
2376
|
|