@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/CHANGELOG.md CHANGED
@@ -2,6 +2,107 @@
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-anary.15](https://gitlab.kkinternal.com/playback/web-playcraft/compare/v2.25.0-canary.9...v2.25.0-anary.15) (2025-12-15)
6
+
7
+
8
+ ### Features
9
+
10
+ * override track display name in language menu ([338f5cc](https://gitlab.kkinternal.com/playback/web-playcraft/commit/338f5cc232d488eb36a07cdc339402cb9bd5d886))
11
+
12
+ ## [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)
13
+
14
+
15
+ ### Features
16
+
17
+ * **premium:** enable audio/text track control ([41d7dd3](https://gitlab.kkinternal.com/playback/web-playcraft/commit/41d7dd3776ab1b5e82b4612605394bb98e22e3b0))
18
+ * subtitle off option is changed to 'none' ([029a41a](https://gitlab.kkinternal.com/playback/web-playcraft/commit/029a41a6e6f69847c01665ca4bd31f9ef77073a7))
19
+
20
+ ## [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)
21
+
22
+ ## [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)
23
+
24
+ ## [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)
25
+
26
+
27
+ ### Features
28
+
29
+ * add back other sections ([a4d8961](https://gitlab.kkinternal.com/playback/web-playcraft/commit/a4d8961b2985cb0811f619529c92302dde73d9ad))
30
+
31
+ ## [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)
32
+
33
+
34
+ ### Bug Fixes
35
+
36
+ * playback api response handling ([dfe5a5f](https://gitlab.kkinternal.com/playback/web-playcraft/commit/dfe5a5fd60ee7dc0155e63a796df6afe337c4a3d))
37
+
38
+ ## [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)
39
+
40
+
41
+ ### Features
42
+
43
+ * display language menu only when options are available ([f02fbc7](https://gitlab.kkinternal.com/playback/web-playcraft/commit/f02fbc775f351dff406139f2e9f2c2451441de31))
44
+
45
+
46
+ ### Bug Fixes
47
+
48
+ * undefined audio setting options ([3e4e5ab](https://gitlab.kkinternal.com/playback/web-playcraft/commit/3e4e5ab521b56ba349d7be8416cc98f70ca404ed))
49
+
50
+ ## [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)
51
+
52
+
53
+ ### Features
54
+
55
+ * add change setting support to new audio/subtitle menu ([97728db](https://gitlab.kkinternal.com/playback/web-playcraft/commit/97728dbdc5f223cfccc18818cb5afa3b17be36d3))
56
+ * custom language menu item order ([6bba6dc](https://gitlab.kkinternal.com/playback/web-playcraft/commit/6bba6dc3c137c292eb890ebefcdc49cf1d155d21))
57
+ * display audio / subtitle options even if there's only 1 ([2e23915](https://gitlab.kkinternal.com/playback/web-playcraft/commit/2e23915d7aa7d084b65c9729c8ac468690852eb3))
58
+ * enable custom language menu ([fb2038d](https://gitlab.kkinternal.com/playback/web-playcraft/commit/fb2038da7fc3ea399bad3fbb4b7e1eb1c7bb49f0))
59
+ * export MenuItem + styles of LanguageMenu for custom menu component ([4f37d2e](https://gitlab.kkinternal.com/playback/web-playcraft/commit/4f37d2ed793287885e69dead576ceb1cecbe3320))
60
+ * **ui:** add close button to mobile language menu ([6704ce1](https://gitlab.kkinternal.com/playback/web-playcraft/commit/6704ce14b13e8e5f344615ca43220b3b8f79b5f8))
61
+ * enable custom setting menu sections with slotProps ([013fb63](https://gitlab.kkinternal.com/playback/web-playcraft/commit/013fb6393d7cc17502db6ef36b8b6d9492787529))
62
+ * integrate new audio/subtitle menu to player UI ([d0944cb](https://gitlab.kkinternal.com/playback/web-playcraft/commit/d0944cb469342ae5eb84cd212a17835559e25115))
63
+ * **ui:** add LanguageMenu component ([3ec5456](https://gitlab.kkinternal.com/playback/web-playcraft/commit/3ec5456eb1003b9374505e53bde56d967fef0b68))
64
+ * **ui:** add OverlayPanel for custom setting menu ([dede035](https://gitlab.kkinternal.com/playback/web-playcraft/commit/dede03515b414c7e4afe7b6cb9c687097d46e920))
65
+ * **ui:** add subtitles icon ([e771220](https://gitlab.kkinternal.com/playback/web-playcraft/commit/e7712208a8594aaf7211d55445fb5d4519e776e3))
66
+
67
+ ## [2.25.0-canary.1](https://gitlab.kkinternal.com/playback/web-playcraft/compare/v2.9.20...v2.25.0-canary.1) (2025-11-21)
68
+
69
+
70
+ ### Features
71
+
72
+ * add support of external text track / subtitle ([2d2aa9f](https://gitlab.kkinternal.com/playback/web-playcraft/commit/2d2aa9f8b624749795b76f80551dbeca40359a79))
73
+ * **text:** add style for shaka player text display container ([39e62ec](https://gitlab.kkinternal.com/playback/web-playcraft/commit/39e62eccf99f394d12d682cd3b4a1a5ad1a398b3))
74
+ * **text:** patch vertical text display style ([7725796](https://gitlab.kkinternal.com/playback/web-playcraft/commit/7725796e0d5ef77a6728c88296519eb809f090c5))
75
+ * **text:** remove extra styles from ruby/rt to display properly ([4c77c61](https://gitlab.kkinternal.com/playback/web-playcraft/commit/4c77c61436a28fbdcc69e2bde0cd670681f7fadb))
76
+ * add castMedia export with error handling added ([82aa0b6](https://gitlab.kkinternal.com/playback/web-playcraft/commit/82aa0b608aad2f2e5c638b20ca3254298ec77291))
77
+ * basic HLS on MSE ([b02c6f0](https://gitlab.kkinternal.com/playback/web-playcraft/commit/b02c6f0f44a89000aed9f279c1715bb4d0d115dc))
78
+ * enable Shaka player built-in text/subtitle display ([47375d6](https://gitlab.kkinternal.com/playback/web-playcraft/commit/47375d639a94df07e0919a79560f0202540f46fa))
79
+ * expose audio track info ([87426d7](https://gitlab.kkinternal.com/playback/web-playcraft/commit/87426d710262baaa347e07ef7c21cd129671d834))
80
+ * give subtitle a bottom magin while controller is hidden ([6444f6a](https://gitlab.kkinternal.com/playback/web-playcraft/commit/6444f6a5bfe9ed6a040c78e8317a67bcf136fa41))
81
+ * select preferred text track after switching video ([e380825](https://gitlab.kkinternal.com/playback/web-playcraft/commit/e3808255ced22c7bdbe3ace169e33b1c9b9b176b))
82
+ * **cast:** add CastSessionControl for non-context integration ([4749ec0](https://gitlab.kkinternal.com/playback/web-playcraft/commit/4749ec0d62771bc73abcf231fc6e58672508e1b5))
83
+ * **premium:** add cast prop for non-context integration ([7a3307f](https://gitlab.kkinternal.com/playback/web-playcraft/commit/7a3307f35c691b77d83b6181670fb76f21187476))
84
+ * upgrade shaka-player and limit version range to 4.15.x ([48c5ec8](https://gitlab.kkinternal.com/playback/web-playcraft/commit/48c5ec81bd8adec74b8415cf101e12617c1d1f07))
85
+
86
+
87
+ ### Bug Fixes
88
+
89
+ * cursh while using quilty setting ([2389954](https://gitlab.kkinternal.com/playback/web-playcraft/commit/2389954551de8fc1dde4a62b70c7075bebf929dd))
90
+ * detect Safari 18 ([981efde](https://gitlab.kkinternal.com/playback/web-playcraft/commit/981efde96791bd93b47b69ca9d4ede32be8bcc0e))
91
+ * format subtitle label only if it exists ([c88fb03](https://gitlab.kkinternal.com/playback/web-playcraft/commit/c88fb033a84126cfc86f6a6ba3b59ab5a745bd48))
92
+ * handle audio tracks with same language code ([d9de3fe](https://gitlab.kkinternal.com/playback/web-playcraft/commit/d9de3fefeda9fcaa7359bcc80ef94ea2dbfa65e0))
93
+ * inconsistent subtitle size on newer MacOS + Chrome ([49008dc](https://gitlab.kkinternal.com/playback/web-playcraft/commit/49008dcde8b1df2dc54f2ea0b0de60568e70151e))
94
+ * initial subtitle on safari ([564c9e5](https://gitlab.kkinternal.com/playback/web-playcraft/commit/564c9e59495f81829074031173e747ee056b39c1))
95
+ * listen to visibility change only in iOS device ([01e0e18](https://gitlab.kkinternal.com/playback/web-playcraft/commit/01e0e18ea011bb10abd6af0ac20e03385171a674))
96
+ * load sender framework only while the application id exists ([0b0caa9](https://gitlab.kkinternal.com/playback/web-playcraft/commit/0b0caa9e1546af4e2bb5ad6fbed1170dcfe460bd))
97
+ * maintain text track / subtitle setting after Safari quality switch ([74837cc](https://gitlab.kkinternal.com/playback/web-playcraft/commit/74837cc7ec3c7ec7d93f46d37e73e00810878985))
98
+ * match subtitle value as off while subtitle is undefined ([4f8ebd2](https://gitlab.kkinternal.com/playback/web-playcraft/commit/4f8ebd2bfbde374215ec08ff4e3594c78f382799))
99
+ * select DASH/HLS base on DRM key system availablity ([623e1e2](https://gitlab.kkinternal.com/playback/web-playcraft/commit/623e1e2ca77b7313e1ec845b391e4c92166686b8))
100
+ * turn off subtitles when starting playback in iOS browsers ([9afbbf1](https://gitlab.kkinternal.com/playback/web-playcraft/commit/9afbbf1516b0007435153311418c1afc2bcba3df))
101
+ * **core:** provide audio tracks without duplicate variantTracks ([799525d](https://gitlab.kkinternal.com/playback/web-playcraft/commit/799525d8b2e7af4417849ac6517ba194644dd720))
102
+ * should use track.label instead of .name ([249b606](https://gitlab.kkinternal.com/playback/web-playcraft/commit/249b6064d8ed444917aaa0d0465269f7610f111d))
103
+ * use text tracks only if have valid language ([b126b7c](https://gitlab.kkinternal.com/playback/web-playcraft/commit/b126b7c545a0782e19d91fa2a72030ab5acdb7f2))
104
+ * workaround for Safari text track on by default ([c4282d8](https://gitlab.kkinternal.com/playback/web-playcraft/commit/c4282d84dff31ad5a92ab58a195c9b77994064e7))
105
+
5
106
  ### [2.9.20](https://gitlab.kkinternal.com/playback/web-playcraft/compare/v2.9.19...v2.9.20) (2025-09-10)
6
107
 
7
108
 
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
- const isSafari = /^((?!chrome|android|X11|Linux).)*(safari|iPad|iPhone|Version)/i.test(navigator.userAgent); // ref: https://stackoverflow.com/a/12905122/4578017
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.9.333";
40
+ return "2.25.0-anary.15";
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
- ...(needNativeHls() && {
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 (needNativeHls()) {
1762
+ if (isSafari()) {
1771
1763
  setupKKFariplay(player, extensionOptions);
1772
1764
  }
1773
1765
 
@@ -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'
@@ -1912,7 +1867,7 @@ const getDrmOptions$1 = fallbackDrm => {
1912
1867
  * @typedef {{hls: string, dash: string}} SourceObjectAlt backward compatiable form
1913
1868
  *
1914
1869
  * @param {SourceObject[]|SourceObject|SourceObjectAlt|string} sourceOptions
1915
- * @param {{preferManifestType?: ('dash'|'hls')}} options
1870
+ * @param {{preferManifestType?: ('dash'|'hls'|'platform')}} options
1916
1871
  * @return {{src: string, type: string, drm: Object}}
1917
1872
  */
1918
1873
 
@@ -1955,7 +1910,8 @@ const getSource = (sourceOptions, {
1955
1910
  });
1956
1911
  }
1957
1912
 
1958
- const matched = sourceOptions.find(source => !preferManifestType || matchType(source, preferManifestType));
1913
+ const targetType = preferManifestType !== 'platform' ? preferManifestType : isSafari() ? 'hls' : 'dash';
1914
+ const matched = sourceOptions.find(source => matchType(source, targetType));
1959
1915
  const selected = matched || sourceOptions[0];
1960
1916
 
1961
1917
  if (!selected) {
@@ -2025,32 +1981,6 @@ const getDrmOptions = source => {
2025
1981
  }];
2026
1982
  };
2027
1983
 
2028
- const matchAll = (input, pattern) => {
2029
- const flags = [pattern.global && 'g', pattern.ignoreCase && 'i', pattern.multiline && 'm'].filter(Boolean).join('');
2030
- const clone = new RegExp(pattern, flags);
2031
- return Array.from(function* () {
2032
- let matched = true;
2033
-
2034
- while (1) {
2035
- matched = clone.exec(input);
2036
-
2037
- if (!matched) {
2038
- return;
2039
- }
2040
-
2041
- yield matched;
2042
- }
2043
- }());
2044
- };
2045
-
2046
- const getHlsQualityOptions = manifest => {
2047
- const resolutionList = matchAll(manifest, /RESOLUTION=\d+x(\d+)/g);
2048
- return Array.from(new Set(resolutionList.map(([, height]) => ({
2049
- height: +height
2050
- })))).sort((a, b) => b.height - a.height);
2051
- };
2052
- // for unit test
2053
-
2054
1984
  /* eslint-disable no-param-reassign */
2055
1985
  // when the gap is small enough, we consider it is on edge.
2056
1986
  // The magic number 10s comes from observation of YouTube
@@ -2064,7 +1994,7 @@ const isLiveDuration = duration => duration >= SHAKA_LIVE_DURATION;
2064
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.
2065
1995
 
2066
1996
 
2067
- const isBuffered = media => needNativeHls() || Array.from({
1997
+ const isBuffered = media => isSafari() || Array.from({
2068
1998
  length: media.buffered.length
2069
1999
  }, (_, index) => ({
2070
2000
  start: media.buffered.start(index),
@@ -2220,22 +2150,6 @@ const subscribePlaybackState = (media, updateState, {
2220
2150
  return () => registered.forEach(off => off());
2221
2151
  };
2222
2152
 
2223
- const tryPatchHlsVideoQualities = async (player, hlsUrl) => {
2224
- if (/(^data)|(mp4$)/.test(hlsUrl)) {
2225
- return;
2226
- } // filtered manifest comes with data URI and should be ignored
2227
-
2228
-
2229
- const manifest = await retryRequest(hlsUrl, {}, {
2230
- responseType: 'text'
2231
- }).catch(e => console.warn('Failed to get HLS video qualities', e));
2232
- const videoQualities = getHlsQualityOptions(manifest);
2233
-
2234
- if (videoQualities) {
2235
- player.getAvailableVideoQualities = () => videoQualities;
2236
- }
2237
- };
2238
-
2239
2153
  const seek = async (media, {
2240
2154
  player,
2241
2155
  plugins = []
@@ -2291,9 +2205,8 @@ const load = async (media, {
2291
2205
  startTime,
2292
2206
  plugins = []
2293
2207
  }, source) => {
2294
- const preferManifestType = needNativeHls() ? 'dash' : 'dash';
2295
2208
  const preferred = getSource(source, {
2296
- preferManifestType
2209
+ preferManifestType: 'platform'
2297
2210
  }); // There's no use case that changing DRM options without changing manifest URL, just skip
2298
2211
 
2299
2212
  if (player.lastSrc === (preferred === null || preferred === void 0 ? void 0 : preferred.src)) {
@@ -2313,7 +2226,7 @@ const load = async (media, {
2313
2226
  player,
2314
2227
  source: currentSource,
2315
2228
  startTime,
2316
- streamFormat: preferManifestType,
2229
+ streamFormat: source.type,
2317
2230
  reload: async () => {
2318
2231
  // Bitmovin unexpectedly restores muted state, so save to restore
2319
2232
  const restoreMuted = player.isMuted && {
@@ -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 (!isIOS()) {
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
- }); // TODO load built-in modules here
2403
+ });
2404
+ player.preferredSettings = {}; // TODO load built-in modules here
2495
2405
 
2496
2406
  player.modules = {};
2497
2407
  return player;