rx-player 3.30.0-dev.2023020100 → 3.30.0-dev.2023030200
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/.eslintrc.js +8 -0
- package/CHANGELOG.md +5 -1
- package/VERSION +1 -1
- package/dist/_esm5.processed/compat/browser_detection.d.ts +23 -12
- package/dist/_esm5.processed/compat/browser_detection.js +80 -38
- package/dist/_esm5.processed/compat/can_reuse_media_keys.js +2 -2
- package/dist/_esm5.processed/compat/eme/close_session.js +2 -2
- package/dist/_esm5.processed/compat/event_listeners.js +1 -1
- package/dist/_esm5.processed/config.d.ts +2 -0
- package/dist/_esm5.processed/core/adaptive/adaptive_representation_selector.js +4 -2
- package/dist/_esm5.processed/core/api/debug/buffer_graph.d.ts +28 -0
- package/dist/_esm5.processed/core/api/debug/buffer_graph.js +175 -0
- package/dist/_esm5.processed/core/api/debug/buffer_size_graph.d.ts +10 -0
- package/dist/_esm5.processed/core/api/debug/buffer_size_graph.js +104 -0
- package/dist/_esm5.processed/core/api/debug/constants.d.ts +2 -0
- package/dist/_esm5.processed/core/api/debug/constants.js +2 -0
- package/dist/_esm5.processed/core/api/debug/index.d.ts +2 -0
- package/dist/_esm5.processed/core/api/debug/index.js +2 -0
- package/dist/_esm5.processed/core/api/debug/modules/general_info.d.ts +3 -0
- package/dist/_esm5.processed/core/api/debug/modules/general_info.js +199 -0
- package/dist/_esm5.processed/core/api/debug/modules/segment_buffer_content.d.ts +4 -0
- package/dist/_esm5.processed/core/api/debug/modules/segment_buffer_content.js +121 -0
- package/dist/_esm5.processed/core/api/debug/modules/segment_buffer_size.d.ts +3 -0
- package/dist/_esm5.processed/core/api/debug/modules/segment_buffer_size.js +35 -0
- package/dist/_esm5.processed/core/api/debug/render.d.ts +3 -0
- package/dist/_esm5.processed/core/api/debug/render.js +32 -0
- package/dist/_esm5.processed/core/api/debug/utils.d.ts +39 -0
- package/dist/_esm5.processed/core/api/debug/utils.js +57 -0
- package/dist/_esm5.processed/core/api/playback_observer.js +3 -2
- package/dist/_esm5.processed/core/api/public_api.d.ts +3 -0
- package/dist/_esm5.processed/core/api/public_api.js +25 -14
- package/dist/_esm5.processed/core/api/utils.js +3 -3
- package/dist/_esm5.processed/core/decrypt/__tests__/__global__/utils.d.ts +32 -13
- package/dist/_esm5.processed/core/decrypt/__tests__/__global__/utils.js +28 -7
- package/dist/_esm5.processed/core/decrypt/attach_media_keys.js +1 -1
- package/dist/_esm5.processed/core/decrypt/content_decryptor.js +1 -1
- package/dist/_esm5.processed/core/decrypt/find_key_system.js +33 -24
- package/dist/_esm5.processed/core/decrypt/session_events_listener.js +54 -50
- package/dist/_esm5.processed/core/decrypt/utils/check_key_statuses.js +4 -0
- package/dist/_esm5.processed/core/fetchers/cdn_prioritizer.d.ts +17 -8
- package/dist/_esm5.processed/core/fetchers/cdn_prioritizer.js +10 -6
- package/dist/_esm5.processed/core/fetchers/manifest/manifest_fetcher.js +5 -4
- package/dist/_esm5.processed/core/fetchers/segment/segment_fetcher.d.ts +22 -5
- package/dist/_esm5.processed/core/fetchers/segment/segment_fetcher.js +37 -21
- package/dist/_esm5.processed/core/fetchers/segment/task_prioritizer.js +21 -23
- package/dist/_esm5.processed/core/fetchers/utils/schedule_request.js +17 -7
- package/dist/_esm5.processed/core/init/directfile_content_initializer.js +1 -1
- package/dist/_esm5.processed/core/init/media_source_content_initializer.js +27 -31
- package/dist/_esm5.processed/core/init/utils/content_time_boundaries_observer.js +2 -2
- package/dist/_esm5.processed/core/init/utils/create_media_source.js +3 -12
- package/dist/_esm5.processed/core/init/utils/end_of_stream.js +6 -3
- package/dist/_esm5.processed/core/init/utils/get_loaded_reference.js +2 -1
- package/dist/_esm5.processed/core/init/utils/initial_seek_and_play.js +9 -5
- package/dist/_esm5.processed/core/init/utils/initialize_content_decryption.js +2 -1
- package/dist/_esm5.processed/core/init/utils/media_duration_updater.js +23 -19
- package/dist/_esm5.processed/core/init/utils/rebuffering_controller.js +1 -1
- package/dist/_esm5.processed/core/init/utils/stream_events_emitter/stream_events_emitter.js +6 -4
- package/dist/_esm5.processed/core/init/utils/throw_on_media_error.js +1 -1
- package/dist/_esm5.processed/core/segment_buffers/implementations/audio_video/audio_video_segment_buffer.js +7 -10
- package/dist/_esm5.processed/core/segment_buffers/implementations/text/html/html_text_segment_buffer.js +4 -2
- package/dist/_esm5.processed/core/segment_buffers/segment_buffers_store.js +13 -9
- package/dist/_esm5.processed/core/stream/adaptation/adaptation_stream.js +25 -16
- package/dist/_esm5.processed/core/stream/orchestrator/stream_orchestrator.js +26 -12
- package/dist/_esm5.processed/core/stream/period/period_stream.js +11 -10
- package/dist/_esm5.processed/core/stream/representation/representation_stream.js +15 -15
- package/dist/_esm5.processed/core/stream/representation/utils/append_segment_to_buffer.js +1 -1
- package/dist/_esm5.processed/core/stream/representation/utils/downloading_queue.js +16 -6
- package/dist/_esm5.processed/default_config.d.ts +16 -0
- package/dist/_esm5.processed/default_config.js +19 -0
- package/dist/_esm5.processed/experimental/features/debug_element.d.ts +8 -0
- package/dist/_esm5.processed/experimental/features/debug_element.js +10 -0
- package/dist/_esm5.processed/experimental/features/index.d.ts +1 -0
- package/dist/_esm5.processed/experimental/features/index.js +1 -0
- package/dist/_esm5.processed/experimental/tools/VideoThumbnailLoader/prepare_source_buffer.js +7 -4
- package/dist/_esm5.processed/experimental/tools/VideoThumbnailLoader/video_thumbnail_loader.js +8 -4
- package/dist/_esm5.processed/features/features_object.js +1 -0
- package/dist/_esm5.processed/features/initialize_features.js +13 -10
- package/dist/_esm5.processed/features/types.d.ts +3 -0
- package/dist/_esm5.processed/manifest/adaptation.js +4 -0
- package/dist/_esm5.processed/manifest/manifest.js +2 -0
- package/dist/_esm5.processed/manifest/representation.js +11 -4
- package/dist/_esm5.processed/parsers/manifest/dash/common/parse_adaptation_sets.js +105 -137
- package/dist/_esm5.processed/parsers/manifest/dash/common/parse_representations.js +25 -5
- package/dist/_esm5.processed/public_types.d.ts +1 -0
- package/dist/_esm5.processed/transports/dash/add_segment_integrity_checks_to_loader.js +15 -11
- package/dist/_esm5.processed/transports/dash/low_latency_segment_loader.js +2 -2
- package/dist/_esm5.processed/transports/dash/manifest_parser.js +1 -1
- package/dist/_esm5.processed/transports/dash/segment_loader.js +4 -4
- package/dist/_esm5.processed/transports/local/segment_loader.js +13 -26
- package/dist/_esm5.processed/transports/smooth/segment_loader.js +4 -4
- package/dist/_esm5.processed/transports/utils/call_custom_manifest_loader.js +3 -3
- package/dist/_esm5.processed/utils/cancellable_sleep.js +4 -10
- package/dist/_esm5.processed/utils/create_cancellable_promise.d.ts +26 -0
- package/dist/_esm5.processed/utils/create_cancellable_promise.js +52 -0
- package/dist/_esm5.processed/utils/reference.js +6 -0
- package/dist/_esm5.processed/utils/request/xhr.js +1 -1
- package/dist/_esm5.processed/utils/task_canceller.d.ts +34 -15
- package/dist/_esm5.processed/utils/task_canceller.js +55 -22
- package/dist/rx-player.js +880 -677
- package/dist/rx-player.min.js +1 -1
- package/jest.config.js +1 -0
- package/package.json +19 -18
- package/scripts/build/constants.d.ts +1 -0
- package/scripts/report_build_sizes +4 -0
- package/sonar-project.properties +1 -1
- package/src/compat/browser_detection.ts +99 -52
- package/src/compat/can_reuse_media_keys.ts +5 -2
- package/src/compat/eme/close_session.ts +2 -2
- package/src/compat/event_listeners.ts +1 -1
- package/src/core/adaptive/adaptive_representation_selector.ts +4 -2
- package/src/core/api/debug/buffer_graph.ts +247 -0
- package/src/core/api/debug/buffer_size_graph.ts +130 -0
- package/src/core/api/debug/constants.ts +2 -0
- package/src/core/api/debug/index.ts +3 -0
- package/src/core/api/debug/modules/general_info.ts +204 -0
- package/src/core/api/debug/modules/segment_buffer_content.ts +155 -0
- package/src/core/api/debug/modules/segment_buffer_size.ts +48 -0
- package/src/core/api/debug/render.ts +40 -0
- package/src/core/api/debug/utils.ts +103 -0
- package/src/core/api/playback_observer.ts +4 -2
- package/src/core/api/public_api.ts +28 -14
- package/src/core/api/utils.ts +3 -3
- package/src/core/decrypt/__tests__/__global__/utils.ts +61 -40
- package/src/core/decrypt/attach_media_keys.ts +1 -1
- package/src/core/decrypt/content_decryptor.ts +1 -1
- package/src/core/decrypt/find_key_system.ts +36 -35
- package/src/core/decrypt/session_events_listener.ts +57 -56
- package/src/core/decrypt/utils/check_key_statuses.ts +6 -0
- package/src/core/fetchers/cdn_prioritizer.ts +18 -9
- package/src/core/fetchers/manifest/manifest_fetcher.ts +5 -4
- package/src/core/fetchers/segment/segment_fetcher.ts +36 -14
- package/src/core/fetchers/segment/task_prioritizer.ts +25 -30
- package/src/core/fetchers/utils/schedule_request.ts +18 -7
- package/src/core/init/directfile_content_initializer.ts +1 -1
- package/src/core/init/media_source_content_initializer.ts +37 -41
- package/src/core/init/utils/content_time_boundaries_observer.ts +2 -2
- package/src/core/init/utils/create_media_source.ts +4 -16
- package/src/core/init/utils/end_of_stream.ts +6 -3
- package/src/core/init/utils/get_loaded_reference.ts +2 -1
- package/src/core/init/utils/initial_seek_and_play.ts +9 -5
- package/src/core/init/utils/initialize_content_decryption.ts +2 -1
- package/src/core/init/utils/media_duration_updater.ts +25 -20
- package/src/core/init/utils/rebuffering_controller.ts +1 -1
- package/src/core/init/utils/stream_events_emitter/stream_events_emitter.ts +6 -4
- package/src/core/init/utils/throw_on_media_error.ts +1 -1
- package/src/core/segment_buffers/implementations/audio_video/audio_video_segment_buffer.ts +7 -11
- package/src/core/segment_buffers/implementations/text/html/html_text_segment_buffer.ts +4 -2
- package/src/core/segment_buffers/segment_buffers_store.ts +16 -13
- package/src/core/stream/adaptation/adaptation_stream.ts +28 -19
- package/src/core/stream/orchestrator/stream_orchestrator.ts +26 -12
- package/src/core/stream/period/period_stream.ts +11 -10
- package/src/core/stream/representation/representation_stream.ts +15 -15
- package/src/core/stream/representation/utils/append_segment_to_buffer.ts +1 -1
- package/src/core/stream/representation/utils/downloading_queue.ts +16 -4
- package/src/default_config.ts +30 -9
- package/src/experimental/features/__tests__/debug_element.test.ts +26 -0
- package/src/experimental/features/debug_element.ts +13 -0
- package/src/experimental/features/index.ts +1 -0
- package/src/experimental/tools/VideoThumbnailLoader/prepare_source_buffer.ts +7 -4
- package/src/experimental/tools/VideoThumbnailLoader/video_thumbnail_loader.ts +8 -4
- package/src/features/__tests__/initialize_features.test.ts +11 -0
- package/src/features/features_object.ts +1 -0
- package/src/features/initialize_features.ts +15 -10
- package/src/features/types.ts +9 -0
- package/src/manifest/adaptation.ts +7 -0
- package/src/manifest/manifest.ts +4 -0
- package/src/manifest/representation.ts +10 -4
- package/src/parsers/manifest/dash/common/parse_adaptation_sets.ts +116 -151
- package/src/parsers/manifest/dash/common/parse_representations.ts +21 -4
- package/src/public_types.ts +1 -0
- package/src/transports/dash/add_segment_integrity_checks_to_loader.ts +31 -22
- package/src/transports/dash/low_latency_segment_loader.ts +2 -2
- package/src/transports/dash/manifest_parser.ts +1 -1
- package/src/transports/dash/segment_loader.ts +4 -4
- package/src/transports/local/segment_loader.ts +14 -30
- package/src/transports/smooth/segment_loader.ts +4 -4
- package/src/transports/utils/call_custom_manifest_loader.ts +3 -3
- package/src/typings/globals.d.ts +2 -0
- package/src/utils/cancellable_sleep.ts +5 -14
- package/src/utils/create_cancellable_promise.ts +69 -0
- package/src/utils/reference.ts +6 -0
- package/src/utils/request/xhr.ts +1 -1
- package/src/utils/task_canceller.ts +63 -34
package/jest.config.js
CHANGED
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "rx-player",
|
|
3
3
|
"author": "Canal+",
|
|
4
|
-
"version": "3.30.0-dev.
|
|
4
|
+
"version": "3.30.0-dev.2023030200",
|
|
5
5
|
"description": "Canal+ HTML5 Video Player",
|
|
6
6
|
"main": "./dist/rx-player.js",
|
|
7
7
|
"keywords": [
|
|
@@ -78,34 +78,35 @@
|
|
|
78
78
|
"next-tick": "1.1.0"
|
|
79
79
|
},
|
|
80
80
|
"devDependencies": {
|
|
81
|
-
"@babel/core": "7.
|
|
82
|
-
"@babel/plugin-transform-runtime": "7.
|
|
81
|
+
"@babel/core": "7.21.0",
|
|
82
|
+
"@babel/plugin-transform-runtime": "7.21.0",
|
|
83
83
|
"@babel/preset-env": "7.20.2",
|
|
84
84
|
"@babel/preset-react": "7.18.6",
|
|
85
85
|
"@types/chai": "4.3.4",
|
|
86
|
-
"@types/jest": "29.
|
|
86
|
+
"@types/jest": "29.4.0",
|
|
87
87
|
"@types/mocha": "10.0.1",
|
|
88
|
-
"@types/node": "18.
|
|
88
|
+
"@types/node": "18.14.0",
|
|
89
89
|
"@types/sinon": "10.0.13",
|
|
90
|
-
"@typescript-eslint/eslint-plugin": "5.
|
|
91
|
-
"@typescript-eslint/eslint-plugin-tslint": "5.
|
|
92
|
-
"@typescript-eslint/parser": "5.
|
|
90
|
+
"@typescript-eslint/eslint-plugin": "5.53.0",
|
|
91
|
+
"@typescript-eslint/eslint-plugin-tslint": "5.53.0",
|
|
92
|
+
"@typescript-eslint/parser": "5.53.0",
|
|
93
93
|
"arraybuffer-loader": "1.0.8",
|
|
94
94
|
"babel-loader": "9.1.2",
|
|
95
95
|
"chai": "4.3.7",
|
|
96
96
|
"cheerio": "1.0.0-rc.12",
|
|
97
|
-
"core-js": "3.
|
|
98
|
-
"esbuild": "0.17.
|
|
99
|
-
"eslint": "8.
|
|
97
|
+
"core-js": "3.28.0",
|
|
98
|
+
"esbuild": "0.17.10",
|
|
99
|
+
"eslint": "8.34.0",
|
|
100
|
+
"eslint-plugin-ban": "1.6.0",
|
|
100
101
|
"eslint-plugin-import": "2.27.5",
|
|
101
|
-
"eslint-plugin-jsdoc": "
|
|
102
|
-
"eslint-plugin-react": "7.32.
|
|
102
|
+
"eslint-plugin-jsdoc": "40.0.0",
|
|
103
|
+
"eslint-plugin-react": "7.32.2",
|
|
103
104
|
"esm": "3.2.25",
|
|
104
105
|
"express": "4.18.2",
|
|
105
106
|
"highlight.js": "11.7.0",
|
|
106
107
|
"html-entities": "2.3.3",
|
|
107
|
-
"jest": "29.3
|
|
108
|
-
"jest-environment-jsdom": "29.3
|
|
108
|
+
"jest": "29.4.3",
|
|
109
|
+
"jest-environment-jsdom": "29.4.3",
|
|
109
110
|
"karma": "6.4.1",
|
|
110
111
|
"karma-chrome-launcher": "3.1.1",
|
|
111
112
|
"karma-firefox-launcher": "2.1.2",
|
|
@@ -118,16 +119,16 @@
|
|
|
118
119
|
"react": "18.2.0",
|
|
119
120
|
"react-dom": "18.2.0",
|
|
120
121
|
"regenerator-runtime": "0.13.11",
|
|
121
|
-
"rimraf": "4.1.
|
|
122
|
+
"rimraf": "4.1.2",
|
|
122
123
|
"semver": "7.3.8",
|
|
123
124
|
"sinon": "15.0.1",
|
|
124
125
|
"terser-webpack-plugin": "5.3.6",
|
|
125
126
|
"ts-jest": "29.0.5",
|
|
126
127
|
"ts-loader": "9.4.2",
|
|
127
128
|
"tslint": "6.1.3",
|
|
128
|
-
"typescript": "4.9.
|
|
129
|
+
"typescript": "4.9.5",
|
|
129
130
|
"webpack": "5.75.0",
|
|
130
|
-
"webpack-bundle-analyzer": "4.
|
|
131
|
+
"webpack-bundle-analyzer": "4.8.0",
|
|
131
132
|
"webpack-cli": "5.0.1"
|
|
132
133
|
},
|
|
133
134
|
"scripts-list": {
|
|
@@ -87,6 +87,10 @@ RXP_METAPLAYLIST=true npm run build:min
|
|
|
87
87
|
echo -n "with METAPLAYLIST: " >> sizes
|
|
88
88
|
stat -c %s dist/rx-player.min.js >> sizes
|
|
89
89
|
|
|
90
|
+
RXP_DEBUG_ELEMENT=true npm run build:min
|
|
91
|
+
echo -n "with DEBUG_ELEMENT: " >> sizes
|
|
92
|
+
stat -c %s dist/rx-player.min.js >> sizes
|
|
93
|
+
|
|
90
94
|
RXP_LOCAL_MANIFEST=true npm run build:min
|
|
91
95
|
echo -n "with LOCAL_MANIFEST: " >> sizes
|
|
92
96
|
stat -c %s dist/rx-player.min.js >> sizes
|
package/sonar-project.properties
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
sonar.projectKey=rx-player
|
|
2
2
|
sonar.organization=rx-player
|
|
3
3
|
sonar.projectName=rx-player
|
|
4
|
-
sonar.projectVersion=3.30.0-dev.
|
|
4
|
+
sonar.projectVersion=3.30.0-dev.2023030200
|
|
5
5
|
sonar.sources=./src,./demo,./tests
|
|
6
6
|
sonar.exclusions=demo/full/bundle.js,demo/standalone/lib.js,demo/bundle.js
|
|
7
7
|
sonar.host.url=https://sonarcloud.io
|
|
@@ -24,71 +24,118 @@ interface IIE11Document extends Document {
|
|
|
24
24
|
documentMode? : unknown;
|
|
25
25
|
}
|
|
26
26
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
const isIE11 : boolean =
|
|
30
|
-
!isNode &&
|
|
31
|
-
typeof (window as IIE11WindowObject).MSInputMethodContext !== "undefined" &&
|
|
32
|
-
typeof (document as IIE11Document).documentMode !== "undefined";
|
|
33
|
-
|
|
34
|
-
// true for IE / Edge
|
|
35
|
-
const isIEOrEdge : boolean = isNode ?
|
|
36
|
-
false :
|
|
37
|
-
navigator.appName === "Microsoft Internet Explorer" ||
|
|
38
|
-
navigator.appName === "Netscape" &&
|
|
39
|
-
/(Trident|Edge)\//.test(navigator.userAgent);
|
|
40
|
-
|
|
41
|
-
const isEdgeChromium: boolean = !isNode &&
|
|
42
|
-
navigator.userAgent.toLowerCase().indexOf("edg/") !== -1;
|
|
43
|
-
|
|
44
|
-
const isFirefox : boolean = !isNode &&
|
|
45
|
-
navigator.userAgent.toLowerCase().indexOf("firefox") !== -1;
|
|
46
|
-
|
|
47
|
-
const isSamsungBrowser : boolean = !isNode &&
|
|
48
|
-
/SamsungBrowser/.test(navigator.userAgent);
|
|
49
|
-
|
|
50
|
-
const isTizen : boolean = !isNode &&
|
|
51
|
-
/Tizen/.test(navigator.userAgent);
|
|
52
|
-
|
|
53
|
-
const isWebOs : boolean = !isNode &&
|
|
54
|
-
navigator.userAgent.indexOf("Web0S") >= 0;
|
|
55
|
-
|
|
56
|
-
// Inspired form: http://webostv.developer.lge.com/discover/specifications/web-engine/
|
|
57
|
-
// Note: even that page doesn't correspond to what we've actually seen in the
|
|
58
|
-
// wild
|
|
59
|
-
const isWebOs2021 : boolean = isWebOs &&
|
|
60
|
-
(
|
|
61
|
-
/[Ww]eb[O0]S.TV-2021/.test(navigator.userAgent) ||
|
|
62
|
-
/[Cc]hr[o0]me\/79/.test(navigator.userAgent)
|
|
63
|
-
);
|
|
64
|
-
const isWebOs2022 : boolean = isWebOs &&
|
|
65
|
-
(
|
|
66
|
-
/[Ww]eb[O0]S.TV-2022/.test(navigator.userAgent) ||
|
|
67
|
-
/[Cc]hr[o0]me\/87/.test(navigator.userAgent)
|
|
68
|
-
);
|
|
27
|
+
/** Edge Chromium, regardless of the device */
|
|
28
|
+
let isEdgeChromium = false;
|
|
69
29
|
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
30
|
+
/** IE11, regardless of the device */
|
|
31
|
+
let isIE11 = false;
|
|
32
|
+
|
|
33
|
+
/** IE11 or Edge __Legacy__ (not Edge Chromium), regardless of the device */
|
|
34
|
+
let isIEOrEdge = false;
|
|
35
|
+
|
|
36
|
+
/** Firefox, regardless of the device */
|
|
37
|
+
let isFirefox = false;
|
|
73
38
|
|
|
74
39
|
/** `true` on Safari on a PC platform (i.e. not iPhone / iPad etc.) */
|
|
75
|
-
|
|
76
|
-
|
|
40
|
+
let isSafariDesktop = false;
|
|
41
|
+
|
|
42
|
+
/** `true` on Safari on an iPhone, iPad & iPod platform */
|
|
43
|
+
let isSafariMobile = false;
|
|
44
|
+
|
|
45
|
+
/** Samsung's own browser application */
|
|
46
|
+
let isSamsungBrowser = false;
|
|
47
|
+
|
|
48
|
+
/** `true` on devices where Tizen is the OS (e.g. Samsung TVs). */
|
|
49
|
+
let isTizen = false;
|
|
50
|
+
|
|
51
|
+
/** `true` on devices where WebOS is the OS (e.g. LG TVs). */
|
|
52
|
+
let isWebOs = false;
|
|
53
|
+
|
|
54
|
+
/** `true` specifically for WebOS 2021 version. */
|
|
55
|
+
let isWebOs2021 = false;
|
|
56
|
+
|
|
57
|
+
/** `true` specifically for WebOS 2022 version. */
|
|
58
|
+
let isWebOs2022 = false;
|
|
59
|
+
|
|
60
|
+
/** `true` for Panasonic devices. */
|
|
61
|
+
let isPanasonic = false;
|
|
62
|
+
|
|
63
|
+
((function findCurrentBrowser() : void {
|
|
64
|
+
if (isNode) {
|
|
65
|
+
return ;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// 1 - Find out browser between IE/Edge Legacy/Edge Chromium/Firefox/Safari
|
|
69
|
+
|
|
70
|
+
if (typeof (window as IIE11WindowObject).MSInputMethodContext !== "undefined" &&
|
|
71
|
+
typeof (document as IIE11Document).documentMode !== "undefined")
|
|
72
|
+
{
|
|
73
|
+
isIE11 = true;
|
|
74
|
+
isIEOrEdge = true;
|
|
75
|
+
} else if (
|
|
76
|
+
navigator.appName === "Microsoft Internet Explorer" ||
|
|
77
|
+
navigator.appName === "Netscape" &&
|
|
78
|
+
/(Trident|Edge)\//.test(navigator.userAgent)
|
|
79
|
+
) {
|
|
80
|
+
isIEOrEdge = true;
|
|
81
|
+
} else if (navigator.userAgent.toLowerCase().indexOf("edg/") !== -1) {
|
|
82
|
+
isEdgeChromium = true;
|
|
83
|
+
} else if (navigator.userAgent.toLowerCase().indexOf("firefox") !== -1) {
|
|
84
|
+
isFirefox = true;
|
|
85
|
+
} else if (typeof navigator.platform === "string" &&
|
|
86
|
+
/iPad|iPhone|iPod/.test(navigator.platform))
|
|
87
|
+
{
|
|
88
|
+
isSafariMobile = true;
|
|
89
|
+
} else if (
|
|
77
90
|
Object.prototype.toString.call(window.HTMLElement).indexOf("Constructor") >= 0 ||
|
|
78
91
|
(window as ISafariWindowObject).safari?.pushNotification?.toString() ===
|
|
79
92
|
"[object SafariRemoteNotification]"
|
|
80
|
-
)
|
|
93
|
+
) {
|
|
94
|
+
isSafariDesktop = true;
|
|
95
|
+
}
|
|
81
96
|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
97
|
+
// 2 - Find out specific device/platform information
|
|
98
|
+
|
|
99
|
+
// Samsung browser e.g. on Android
|
|
100
|
+
if (/SamsungBrowser/.test(navigator.userAgent)) {
|
|
101
|
+
isSamsungBrowser = true;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
if (/Tizen/.test(navigator.userAgent)) {
|
|
105
|
+
isTizen = true;
|
|
106
|
+
|
|
107
|
+
// Inspired form: http://webostv.developer.lge.com/discover/specifications/web-engine/
|
|
108
|
+
// Note: even that page doesn't correspond to what we've actually seen in the
|
|
109
|
+
// wild
|
|
110
|
+
} else if (/[Ww]eb[O0]S/.test(navigator.userAgent)) {
|
|
111
|
+
isWebOs = true;
|
|
112
|
+
|
|
113
|
+
if (
|
|
114
|
+
/[Ww]eb[O0]S.TV-2022/.test(navigator.userAgent) ||
|
|
115
|
+
/[Cc]hr[o0]me\/87/.test(navigator.userAgent)
|
|
116
|
+
) {
|
|
117
|
+
isWebOs2022 = true;
|
|
118
|
+
} else if (
|
|
119
|
+
/[Ww]eb[O0]S.TV-2021/.test(navigator.userAgent) ||
|
|
120
|
+
/[Cc]hr[o0]me\/79/.test(navigator.userAgent)
|
|
121
|
+
) {
|
|
122
|
+
isWebOs2021 = true;
|
|
123
|
+
}
|
|
124
|
+
} else if (/[Pp]anasonic/.test(navigator.userAgent)) {
|
|
125
|
+
isPanasonic = true;
|
|
126
|
+
}
|
|
127
|
+
})());
|
|
128
|
+
|
|
129
|
+
interface ISafariWindowObject extends Window {
|
|
130
|
+
safari? : { pushNotification? : { toString() : string } };
|
|
131
|
+
}
|
|
86
132
|
|
|
87
133
|
export {
|
|
88
134
|
isEdgeChromium,
|
|
89
135
|
isIE11,
|
|
90
136
|
isIEOrEdge,
|
|
91
137
|
isFirefox,
|
|
138
|
+
isPanasonic,
|
|
92
139
|
isSafariDesktop,
|
|
93
140
|
isSafariMobile,
|
|
94
141
|
isSamsungBrowser,
|
|
@@ -1,4 +1,7 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
isPanasonic,
|
|
3
|
+
isWebOs,
|
|
4
|
+
} from "./browser_detection";
|
|
2
5
|
|
|
3
6
|
/**
|
|
4
7
|
* Returns `true` if a `MediaKeys` instance (the `Encrypted Media Extension`
|
|
@@ -13,5 +16,5 @@ import { isWebOs } from "./browser_detection";
|
|
|
13
16
|
* @returns {boolean}
|
|
14
17
|
*/
|
|
15
18
|
export default function canReuseMediaKeys() : boolean {
|
|
16
|
-
return !isWebOs;
|
|
19
|
+
return !isWebOs && !isPanasonic;
|
|
17
20
|
}
|
|
@@ -86,7 +86,7 @@ export default function closeSession(
|
|
|
86
86
|
try {
|
|
87
87
|
await session.update(new Uint8Array(1));
|
|
88
88
|
} catch (err) {
|
|
89
|
-
if (timeoutCanceller.isUsed) { // Reminder: cancelled == session closed
|
|
89
|
+
if (timeoutCanceller.isUsed()) { // Reminder: cancelled == session closed
|
|
90
90
|
return;
|
|
91
91
|
}
|
|
92
92
|
|
|
@@ -102,7 +102,7 @@ export default function closeSession(
|
|
|
102
102
|
await cancellableSleep(1000, timeoutCanceller.signal);
|
|
103
103
|
}
|
|
104
104
|
|
|
105
|
-
if (timeoutCanceller.isUsed) { // Reminder: cancelled == session closed
|
|
105
|
+
if (timeoutCanceller.isUsed()) { // Reminder: cancelled == session closed
|
|
106
106
|
return;
|
|
107
107
|
}
|
|
108
108
|
|
|
@@ -215,7 +215,8 @@ function getEstimateReference(
|
|
|
215
215
|
* This TaskCanceller is used both for restarting estimates with a new
|
|
216
216
|
* configuration and to cancel them altogether.
|
|
217
217
|
*/
|
|
218
|
-
let currentEstimatesCanceller = new TaskCanceller(
|
|
218
|
+
let currentEstimatesCanceller = new TaskCanceller();
|
|
219
|
+
currentEstimatesCanceller.linkToSignal(stopAllEstimates);
|
|
219
220
|
|
|
220
221
|
// Create `ISharedReference` on which estimates will be emitted.
|
|
221
222
|
const estimateRef = createEstimateReference(manualBitrate.getValue(),
|
|
@@ -491,7 +492,8 @@ function getEstimateReference(
|
|
|
491
492
|
const manualBitrateVal = manualBitrate.getValue();
|
|
492
493
|
const representations = representationsRef.getValue();
|
|
493
494
|
currentEstimatesCanceller.cancel();
|
|
494
|
-
currentEstimatesCanceller = new TaskCanceller(
|
|
495
|
+
currentEstimatesCanceller = new TaskCanceller();
|
|
496
|
+
currentEstimatesCanceller.linkToSignal(stopAllEstimates);
|
|
495
497
|
const newRef = createEstimateReference(
|
|
496
498
|
manualBitrateVal,
|
|
497
499
|
representations,
|
|
@@ -0,0 +1,247 @@
|
|
|
1
|
+
import { Representation } from "../../../manifest";
|
|
2
|
+
import { IBufferedChunk } from "../../segment_buffers";
|
|
3
|
+
|
|
4
|
+
const BUFFER_WIDTH_IN_SECONDS = 10000;
|
|
5
|
+
|
|
6
|
+
const COLORS = [
|
|
7
|
+
"#2ab7ca",
|
|
8
|
+
"#fed766",
|
|
9
|
+
"#4dd248",
|
|
10
|
+
"#a22c28",
|
|
11
|
+
"#556b2f", // darkolivegreen
|
|
12
|
+
"#add8e6", // lightblue
|
|
13
|
+
"#90ee90", // lightgreen
|
|
14
|
+
"#444444",
|
|
15
|
+
"#40bfc1",
|
|
16
|
+
"#57557e",
|
|
17
|
+
"#fbe555",
|
|
18
|
+
];
|
|
19
|
+
|
|
20
|
+
export interface ISegmentBufferGrapUpdateData {
|
|
21
|
+
currentTime : number;
|
|
22
|
+
inventory : IBufferedChunk[];
|
|
23
|
+
width : number;
|
|
24
|
+
height : number;
|
|
25
|
+
minimumPosition : number | undefined;
|
|
26
|
+
maximumPosition : number | undefined;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export default class SegmentBufferGraph {
|
|
30
|
+
/** Link buffered Representation to their corresponding color. */
|
|
31
|
+
private readonly _colorMap : WeakMap<Representation, string>;
|
|
32
|
+
|
|
33
|
+
/** Current amount of colors chosen to represent the various Representation. */
|
|
34
|
+
private _currNbColors : number;
|
|
35
|
+
|
|
36
|
+
/** Canvas that will contain the buffer graph itself. */
|
|
37
|
+
private readonly _canvasElt : HTMLCanvasElement;
|
|
38
|
+
|
|
39
|
+
private readonly _canvasCtxt : CanvasRenderingContext2D | null;
|
|
40
|
+
|
|
41
|
+
constructor(canvasElt : HTMLCanvasElement) {
|
|
42
|
+
this._colorMap = new WeakMap();
|
|
43
|
+
this._currNbColors = 0;
|
|
44
|
+
this._canvasElt = canvasElt;
|
|
45
|
+
this._canvasCtxt = this._canvasElt.getContext("2d");
|
|
46
|
+
this.clear();
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
public clear() {
|
|
50
|
+
if (this._canvasCtxt !== null) {
|
|
51
|
+
this._canvasCtxt.clearRect(0, 0, this._canvasElt.width, this._canvasElt.height);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
public update(data : ISegmentBufferGrapUpdateData) : void {
|
|
56
|
+
if (this._canvasCtxt === null) {
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
const {
|
|
60
|
+
inventory,
|
|
61
|
+
currentTime,
|
|
62
|
+
width,
|
|
63
|
+
height,
|
|
64
|
+
} = data;
|
|
65
|
+
this._canvasElt.style.width = `${width}px`;
|
|
66
|
+
this._canvasElt.style.height = `${height}px`;
|
|
67
|
+
this._canvasElt.width = width;
|
|
68
|
+
this._canvasElt.height = height;
|
|
69
|
+
this.clear();
|
|
70
|
+
let minimumPoint : number;
|
|
71
|
+
if (data.minimumPosition !== undefined) {
|
|
72
|
+
if (inventory.length > 0) {
|
|
73
|
+
minimumPoint = Math.min(data.minimumPosition, inventory[0].start);
|
|
74
|
+
} else {
|
|
75
|
+
minimumPoint = data.minimumPosition;
|
|
76
|
+
}
|
|
77
|
+
} else {
|
|
78
|
+
minimumPoint = inventory[0]?.start ?? 0;
|
|
79
|
+
}
|
|
80
|
+
let maximumPoint : number;
|
|
81
|
+
if (data.maximumPosition !== undefined) {
|
|
82
|
+
if (inventory.length > 0) {
|
|
83
|
+
maximumPoint = Math.max(data.maximumPosition,
|
|
84
|
+
inventory[inventory.length - 1].end);
|
|
85
|
+
} else {
|
|
86
|
+
maximumPoint = data.maximumPosition;
|
|
87
|
+
}
|
|
88
|
+
} else {
|
|
89
|
+
maximumPoint = inventory[inventory.length - 1]?.end ??
|
|
90
|
+
1000;
|
|
91
|
+
}
|
|
92
|
+
minimumPoint = Math.min(currentTime, minimumPoint);
|
|
93
|
+
maximumPoint = Math.max(currentTime, maximumPoint);
|
|
94
|
+
|
|
95
|
+
let minimumPosition;
|
|
96
|
+
let maximumPosition;
|
|
97
|
+
if (maximumPoint - minimumPoint > BUFFER_WIDTH_IN_SECONDS) {
|
|
98
|
+
if (currentTime === undefined) {
|
|
99
|
+
minimumPosition = minimumPoint;
|
|
100
|
+
maximumPosition = maximumPoint;
|
|
101
|
+
} else if (maximumPoint - currentTime < BUFFER_WIDTH_IN_SECONDS / 2) {
|
|
102
|
+
maximumPosition = maximumPoint;
|
|
103
|
+
minimumPosition = maximumPoint - BUFFER_WIDTH_IN_SECONDS;
|
|
104
|
+
} else if (currentTime - minimumPoint < BUFFER_WIDTH_IN_SECONDS / 2) {
|
|
105
|
+
minimumPosition = minimumPoint;
|
|
106
|
+
maximumPosition = minimumPoint + BUFFER_WIDTH_IN_SECONDS;
|
|
107
|
+
} else {
|
|
108
|
+
minimumPosition = currentTime - BUFFER_WIDTH_IN_SECONDS / 2;
|
|
109
|
+
maximumPosition = currentTime + BUFFER_WIDTH_IN_SECONDS / 2;
|
|
110
|
+
}
|
|
111
|
+
} else {
|
|
112
|
+
minimumPosition = minimumPoint;
|
|
113
|
+
maximumPosition = maximumPoint;
|
|
114
|
+
}
|
|
115
|
+
if (minimumPosition >= maximumPosition) {
|
|
116
|
+
this.clear();
|
|
117
|
+
return;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
const currentRangesScaled = scaleSegments(inventory,
|
|
121
|
+
minimumPosition,
|
|
122
|
+
maximumPosition);
|
|
123
|
+
|
|
124
|
+
for (let i = 0; i < currentRangesScaled.length; i++) {
|
|
125
|
+
this._paintRange(currentRangesScaled[i], width, height);
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
if (currentTime !== undefined) {
|
|
129
|
+
paintCurrentPosition(currentTime,
|
|
130
|
+
minimumPosition,
|
|
131
|
+
maximumPosition,
|
|
132
|
+
this._canvasCtxt,
|
|
133
|
+
width,
|
|
134
|
+
height);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
* Paint a given range in the canvas
|
|
140
|
+
* @param {Object} rangeScaled - Buffered segment information with added
|
|
141
|
+
* "scaling" information to know where it fits in the canvas.
|
|
142
|
+
*/
|
|
143
|
+
private _paintRange(
|
|
144
|
+
rangeScaled : IScaledChunk,
|
|
145
|
+
width : number,
|
|
146
|
+
height : number
|
|
147
|
+
) : void {
|
|
148
|
+
if (this._canvasCtxt === null) {
|
|
149
|
+
return;
|
|
150
|
+
}
|
|
151
|
+
const startX = rangeScaled.scaledStart * width;
|
|
152
|
+
const endX = rangeScaled.scaledEnd * width;
|
|
153
|
+
this._canvasCtxt.fillStyle = this._getColorForRepresentation(
|
|
154
|
+
rangeScaled.info.infos.representation
|
|
155
|
+
);
|
|
156
|
+
this._canvasCtxt.fillRect(
|
|
157
|
+
Math.ceil(startX),
|
|
158
|
+
0,
|
|
159
|
+
Math.ceil(endX - startX),
|
|
160
|
+
height
|
|
161
|
+
);
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
private _getColorForRepresentation(
|
|
165
|
+
representation : Representation
|
|
166
|
+
) : string {
|
|
167
|
+
const color = this._colorMap.get(representation);
|
|
168
|
+
if (color !== undefined) {
|
|
169
|
+
return color;
|
|
170
|
+
}
|
|
171
|
+
const newColor = COLORS[this._currNbColors % COLORS.length];
|
|
172
|
+
this._currNbColors++;
|
|
173
|
+
this._colorMap.set(representation, newColor);
|
|
174
|
+
return newColor;
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
/**
|
|
179
|
+
* Represent the current position in the canvas.
|
|
180
|
+
* @param {number|undefined} position - The current position
|
|
181
|
+
* @param {number} minimumPosition - minimum possible position represented in
|
|
182
|
+
* the canvas.
|
|
183
|
+
* @param {number} maximumPosition - maximum possible position represented in
|
|
184
|
+
* the canvas.
|
|
185
|
+
* @param {Object} canvasCtx - The canvas' 2D context
|
|
186
|
+
*/
|
|
187
|
+
function paintCurrentPosition(
|
|
188
|
+
position : number,
|
|
189
|
+
minimumPosition : number,
|
|
190
|
+
maximumPosition : number,
|
|
191
|
+
canvasCtx : CanvasRenderingContext2D,
|
|
192
|
+
width : number,
|
|
193
|
+
height : number
|
|
194
|
+
) {
|
|
195
|
+
if (typeof position === "number" &&
|
|
196
|
+
position >= minimumPosition &&
|
|
197
|
+
position < maximumPosition)
|
|
198
|
+
{
|
|
199
|
+
const lengthCanvas = maximumPosition - minimumPosition;
|
|
200
|
+
canvasCtx.fillStyle = "#FF0000";
|
|
201
|
+
canvasCtx.fillRect(Math.ceil((position - minimumPosition) /
|
|
202
|
+
lengthCanvas * width) - 1,
|
|
203
|
+
5,
|
|
204
|
+
5,
|
|
205
|
+
height);
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
/**
|
|
210
|
+
* Scale given bufferedData in terms of percentage between the minimum and
|
|
211
|
+
* maximum position. Filter out ranges which are not part of it.
|
|
212
|
+
* @param {Array.<Object>} bufferedData
|
|
213
|
+
* @param {number} minimumPosition
|
|
214
|
+
* @param {number} maximumPosition
|
|
215
|
+
* @returns {Array.<Object>}
|
|
216
|
+
*/
|
|
217
|
+
function scaleSegments(
|
|
218
|
+
bufferedData : IBufferedChunk[],
|
|
219
|
+
minimumPosition : number,
|
|
220
|
+
maximumPosition : number
|
|
221
|
+
) : IScaledChunk[] {
|
|
222
|
+
const scaledSegments = [];
|
|
223
|
+
const wholeDuration = maximumPosition - minimumPosition;
|
|
224
|
+
for (let i = 0; i < bufferedData.length; i++) {
|
|
225
|
+
const info = bufferedData[i];
|
|
226
|
+
const start = info.bufferedStart === undefined ?
|
|
227
|
+
info.start :
|
|
228
|
+
info.bufferedStart;
|
|
229
|
+
const end = info.bufferedEnd === undefined ?
|
|
230
|
+
info.end :
|
|
231
|
+
info.bufferedEnd;
|
|
232
|
+
if (end > minimumPosition && start < maximumPosition) {
|
|
233
|
+
const startPoint = Math.max(start - minimumPosition, 0);
|
|
234
|
+
const endPoint = Math.min(end - minimumPosition, maximumPosition);
|
|
235
|
+
const scaledStart = startPoint / wholeDuration;
|
|
236
|
+
const scaledEnd = endPoint / wholeDuration;
|
|
237
|
+
scaledSegments.push({ scaledStart, scaledEnd, info });
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
return scaledSegments;
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
interface IScaledChunk {
|
|
244
|
+
scaledStart: number;
|
|
245
|
+
scaledEnd: number;
|
|
246
|
+
info: IBufferedChunk;
|
|
247
|
+
}
|