rx-player 3.30.1-dev.2023032800 → 3.31.0-dev.2023052200
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 +14 -2
- package/CONTRIBUTING.md +48 -168
- package/FILES.md +40 -92
- package/VERSION +1 -1
- package/dist/_esm5.processed/compat/browser_detection.d.ts +3 -1
- package/dist/_esm5.processed/compat/browser_detection.js +7 -2
- package/dist/_esm5.processed/compat/has_issues_with_high_media_source_duration.d.ts +21 -0
- package/dist/_esm5.processed/compat/has_issues_with_high_media_source_duration.js +26 -0
- package/dist/_esm5.processed/core/adaptive/adaptive_representation_selector.js +1 -2
- package/dist/_esm5.processed/core/adaptive/buffer_based_chooser.d.ts +18 -1
- package/dist/_esm5.processed/core/adaptive/buffer_based_chooser.js +105 -24
- package/dist/_esm5.processed/core/adaptive/guess_based_chooser.js +6 -6
- package/dist/_esm5.processed/core/adaptive/utils/representation_score_calculator.d.ts +19 -1
- package/dist/_esm5.processed/core/adaptive/utils/representation_score_calculator.js +1 -1
- package/dist/_esm5.processed/core/api/debug/render.js +1 -1
- package/dist/_esm5.processed/core/api/public_api.js +2 -2
- package/dist/_esm5.processed/core/api/tracks_management/media_element_track_choice_manager.js +10 -1
- package/dist/_esm5.processed/core/api/tracks_management/track_choice_manager.js +20 -117
- package/dist/_esm5.processed/core/init/media_source_content_initializer.js +28 -3
- package/dist/_esm5.processed/core/init/utils/media_source_duration_updater.d.ts +2 -2
- package/dist/_esm5.processed/core/init/utils/media_source_duration_updater.js +29 -18
- package/dist/_esm5.processed/core/segment_buffers/index.d.ts +2 -2
- package/dist/_esm5.processed/core/stream/adaptation/utils/create_representation_estimator.js +1 -1
- package/dist/_esm5.processed/core/stream/period/period_stream.js +1 -1
- package/dist/_esm5.processed/core/stream/representation/utils/append_segment_to_buffer.d.ts +4 -2
- package/dist/_esm5.processed/core/stream/representation/utils/append_segment_to_buffer.js +2 -2
- package/dist/_esm5.processed/core/stream/representation/utils/push_init_segment.js +6 -2
- package/dist/_esm5.processed/errors/index.d.ts +2 -2
- package/dist/_esm5.processed/errors/media_error.d.ts +23 -1
- package/dist/_esm5.processed/errors/media_error.js +18 -5
- package/dist/_esm5.processed/manifest/adaptation.d.ts +17 -2
- package/dist/_esm5.processed/manifest/adaptation.js +67 -1
- package/dist/_esm5.processed/manifest/manifest.d.ts +1 -1
- package/dist/_esm5.processed/manifest/manifest.js +3 -3
- package/dist/_esm5.processed/manifest/period.js +1 -1
- package/dist/_esm5.processed/manifest/representation.d.ts +11 -1
- package/dist/_esm5.processed/manifest/representation.js +16 -0
- package/dist/_esm5.processed/parsers/manifest/dash/js-parser/parse_from_document.d.ts +1 -1
- package/dist/_esm5.processed/parsers/manifest/dash/js-parser/parse_from_document.js +1 -1
- package/dist/_esm5.processed/parsers/manifest/dash/wasm-parser/ts/dash-wasm-parser.js +1 -0
- package/dist/_esm5.processed/public_types.d.ts +6 -5
- package/dist/_esm5.processed/transports/smooth/isobmff/create_boxes.d.ts +4 -6
- package/dist/_esm5.processed/transports/smooth/isobmff/create_boxes.js +4 -6
- package/dist/rx-player.js +3086 -3024
- package/dist/rx-player.min.js +1 -1
- package/package.json +25 -26
- package/sonar-project.properties +1 -1
- package/src/compat/browser_detection.ts +7 -1
- package/src/compat/has_issues_with_high_media_source_duration.ts +27 -0
- package/src/core/adaptive/__tests__/buffer_based_chooser.test.ts +147 -48
- package/src/core/adaptive/adaptive_representation_selector.ts +1 -2
- package/src/core/adaptive/buffer_based_chooser.ts +143 -25
- package/src/core/adaptive/guess_based_chooser.ts +9 -8
- package/src/core/adaptive/utils/representation_score_calculator.ts +22 -2
- package/src/core/api/debug/render.ts +1 -1
- package/src/core/api/public_api.ts +2 -2
- package/src/core/api/tracks_management/media_element_track_choice_manager.ts +17 -8
- package/src/core/api/tracks_management/track_choice_manager.ts +20 -132
- package/src/core/init/media_source_content_initializer.ts +32 -4
- package/src/core/init/utils/media_source_duration_updater.ts +31 -19
- package/src/core/segment_buffers/index.ts +2 -0
- package/src/core/stream/adaptation/utils/create_representation_estimator.ts +2 -1
- package/src/core/stream/period/period_stream.ts +2 -1
- package/src/core/stream/representation/utils/append_segment_to_buffer.ts +8 -3
- package/src/core/stream/representation/utils/push_init_segment.ts +7 -1
- package/src/errors/__tests__/media_error.test.ts +6 -6
- package/src/errors/index.ts +4 -1
- package/src/errors/media_error.ts +67 -1
- package/src/manifest/__tests__/period.test.ts +90 -45
- package/src/manifest/adaptation.ts +77 -2
- package/src/manifest/manifest.ts +5 -3
- package/src/manifest/period.ts +2 -1
- package/src/manifest/representation.ts +23 -1
- package/src/parsers/manifest/dash/js-parser/parse_from_document.ts +1 -1
- package/src/parsers/manifest/dash/wasm-parser/ts/dash-wasm-parser.ts +1 -0
- package/src/parsers/texttracks/ttml/parse_ttml.ts +1 -1
- package/src/public_types.ts +8 -3
- package/src/transports/smooth/isobmff/create_boxes.ts +4 -6
- package/src/typings/globals.d.ts +21 -21
- package/scripts/doc-generator/construct_table_of_contents.js +0 -76
- package/scripts/doc-generator/convert_MD_to_HMTL.js +0 -26
- package/scripts/doc-generator/create_documentation.js +0 -331
- package/scripts/doc-generator/create_documentation_page.js +0 -209
- package/scripts/doc-generator/create_page.js +0 -210
- package/scripts/doc-generator/generate_header_html.js +0 -147
- package/scripts/doc-generator/generate_page_html.js +0 -115
- package/scripts/doc-generator/generate_page_list_html.js +0 -92
- package/scripts/doc-generator/generate_sidebar_html.js +0 -85
- package/scripts/doc-generator/get_search_data_for_content.js +0 -137
- package/scripts/doc-generator/index.js +0 -34
- package/scripts/doc-generator/parse_doc_configs.js +0 -327
- package/scripts/doc-generator/scripts/lunr.js +0 -10
- package/scripts/doc-generator/scripts/script.js +0 -451
- package/scripts/doc-generator/styles/code.css +0 -99
- package/scripts/doc-generator/styles/style.css +0 -835
- package/scripts/doc-generator/utils.js +0 -74
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "rx-player",
|
|
3
3
|
"author": "Canal+",
|
|
4
|
-
"version": "3.
|
|
4
|
+
"version": "3.31.0-dev.2023052200",
|
|
5
5
|
"description": "Canal+ HTML5 Video Player",
|
|
6
6
|
"main": "./dist/rx-player.js",
|
|
7
7
|
"keywords": [
|
|
@@ -45,7 +45,7 @@
|
|
|
45
45
|
"demo": "node ./scripts/generate_full_demo.js --production-mode",
|
|
46
46
|
"demo:min": "node ./scripts/generate_full_demo.js --production-mode --minify",
|
|
47
47
|
"demo:watch": "node ./scripts/generate_full_demo.js --watch --production-mode",
|
|
48
|
-
"doc": "
|
|
48
|
+
"doc": "docgen.ico doc/ doc/generated \"$(cat VERSION)\"",
|
|
49
49
|
"lint": "eslint src -c .eslintrc.js",
|
|
50
50
|
"lint:demo": "eslint -c demo/full/.eslintrc.js demo/full/scripts",
|
|
51
51
|
"lint:tests": "eslint tests/**/*.js --ignore-pattern '/tests/performance/bundle*'",
|
|
@@ -80,58 +80,57 @@
|
|
|
80
80
|
"next-tick": "1.1.0"
|
|
81
81
|
},
|
|
82
82
|
"devDependencies": {
|
|
83
|
-
"@babel/core": "7.21.
|
|
84
|
-
"@babel/plugin-transform-runtime": "7.21.
|
|
85
|
-
"@babel/preset-env": "7.
|
|
83
|
+
"@babel/core": "7.21.4",
|
|
84
|
+
"@babel/plugin-transform-runtime": "7.21.4",
|
|
85
|
+
"@babel/preset-env": "7.21.4",
|
|
86
86
|
"@babel/preset-react": "7.18.6",
|
|
87
87
|
"@types/chai": "4.3.4",
|
|
88
|
-
"@types/jest": "29.
|
|
88
|
+
"@types/jest": "29.5.0",
|
|
89
89
|
"@types/mocha": "10.0.1",
|
|
90
|
-
"@types/node": "18.
|
|
91
|
-
"@types/react": "18.0.
|
|
90
|
+
"@types/node": "18.15.11",
|
|
91
|
+
"@types/react": "18.0.33",
|
|
92
92
|
"@types/react-dom": "18.0.11",
|
|
93
93
|
"@types/sinon": "10.0.13",
|
|
94
|
-
"@typescript-eslint/eslint-plugin": "5.
|
|
95
|
-
"@typescript-eslint/eslint-plugin-tslint": "5.
|
|
96
|
-
"@typescript-eslint/parser": "5.
|
|
94
|
+
"@typescript-eslint/eslint-plugin": "5.57.1",
|
|
95
|
+
"@typescript-eslint/eslint-plugin-tslint": "5.57.1",
|
|
96
|
+
"@typescript-eslint/parser": "5.57.1",
|
|
97
97
|
"arraybuffer-loader": "1.0.8",
|
|
98
98
|
"babel-loader": "9.1.2",
|
|
99
99
|
"chai": "4.3.7",
|
|
100
|
-
"
|
|
101
|
-
"
|
|
102
|
-
"esbuild": "0.17.
|
|
103
|
-
"eslint": "8.
|
|
100
|
+
"core-js": "3.30.0",
|
|
101
|
+
"docgen.ico": "^0.2.2",
|
|
102
|
+
"esbuild": "0.17.15",
|
|
103
|
+
"eslint": "8.37.0",
|
|
104
104
|
"eslint-plugin-ban": "1.6.0",
|
|
105
105
|
"eslint-plugin-import": "2.27.5",
|
|
106
|
-
"eslint-plugin-jsdoc": "40.
|
|
106
|
+
"eslint-plugin-jsdoc": "40.1.1",
|
|
107
107
|
"eslint-plugin-react": "7.32.2",
|
|
108
108
|
"esm": "3.2.25",
|
|
109
109
|
"express": "4.18.2",
|
|
110
|
-
"
|
|
110
|
+
"github-buttons": "2.27.0",
|
|
111
111
|
"html-entities": "2.3.3",
|
|
112
|
-
"jest": "29.
|
|
113
|
-
"jest-environment-jsdom": "29.
|
|
112
|
+
"jest": "29.5.0",
|
|
113
|
+
"jest-environment-jsdom": "29.5.0",
|
|
114
114
|
"karma": "6.4.1",
|
|
115
115
|
"karma-chrome-launcher": "3.1.1",
|
|
116
116
|
"karma-firefox-launcher": "2.1.2",
|
|
117
117
|
"karma-mocha": "2.0.1",
|
|
118
118
|
"karma-webpack": "5.0.0",
|
|
119
|
-
"markdown-it": "13.0.1",
|
|
120
119
|
"mocha": "10.2.0",
|
|
121
120
|
"mocha-loader": "5.1.5",
|
|
122
121
|
"raw-loader": "4.0.2",
|
|
123
122
|
"react": "18.2.0",
|
|
124
123
|
"react-dom": "18.2.0",
|
|
125
124
|
"regenerator-runtime": "0.13.11",
|
|
126
|
-
"rimraf": "4.1
|
|
125
|
+
"rimraf": "4.4.1",
|
|
127
126
|
"semver": "7.3.8",
|
|
128
|
-
"sinon": "15.0.
|
|
129
|
-
"terser-webpack-plugin": "5.3.
|
|
130
|
-
"ts-jest": "29.0
|
|
127
|
+
"sinon": "15.0.3",
|
|
128
|
+
"terser-webpack-plugin": "5.3.7",
|
|
129
|
+
"ts-jest": "29.1.0",
|
|
131
130
|
"ts-loader": "9.4.2",
|
|
132
131
|
"tslint": "6.1.3",
|
|
133
|
-
"typescript": "
|
|
134
|
-
"webpack": "5.
|
|
132
|
+
"typescript": "5.0.3",
|
|
133
|
+
"webpack": "5.77.0",
|
|
135
134
|
"webpack-bundle-analyzer": "4.8.0",
|
|
136
135
|
"webpack-cli": "5.0.1"
|
|
137
136
|
},
|
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.
|
|
4
|
+
sonar.projectVersion=3.31.0-dev.2023052200
|
|
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
|
|
@@ -60,6 +60,9 @@ let isWebOs2022 = false;
|
|
|
60
60
|
/** `true` for Panasonic devices. */
|
|
61
61
|
let isPanasonic = false;
|
|
62
62
|
|
|
63
|
+
/** `true` for the PlayStation 5 game console. */
|
|
64
|
+
let isPlayStation5 = false;
|
|
65
|
+
|
|
63
66
|
((function findCurrentBrowser() : void {
|
|
64
67
|
if (isNode) {
|
|
65
68
|
return ;
|
|
@@ -101,7 +104,9 @@ let isPanasonic = false;
|
|
|
101
104
|
isSamsungBrowser = true;
|
|
102
105
|
}
|
|
103
106
|
|
|
104
|
-
if (
|
|
107
|
+
if (navigator.userAgent.indexOf("PlayStation 5") !== -1) {
|
|
108
|
+
isPlayStation5 = true;
|
|
109
|
+
} else if (/Tizen/.test(navigator.userAgent)) {
|
|
105
110
|
isTizen = true;
|
|
106
111
|
|
|
107
112
|
// Inspired form: http://webostv.developer.lge.com/discover/specifications/web-engine/
|
|
@@ -136,6 +141,7 @@ export {
|
|
|
136
141
|
isIEOrEdge,
|
|
137
142
|
isFirefox,
|
|
138
143
|
isPanasonic,
|
|
144
|
+
isPlayStation5,
|
|
139
145
|
isSafariDesktop,
|
|
140
146
|
isSafariMobile,
|
|
141
147
|
isSamsungBrowser,
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { isPlayStation5 } from "./browser_detection";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Some platforms have issues when the `MediaSource`'s `duration` property
|
|
5
|
+
* is set to a very high value (playback freezes) but not when setting it
|
|
6
|
+
* to `Infinity`, which is what the HTML spec as of now (2023-05-15) recommends
|
|
7
|
+
* for live contents.
|
|
8
|
+
*
|
|
9
|
+
* However setting the `MediaSource`'s `duration` property to `Infinity` seems
|
|
10
|
+
* more risky, considering all platforms we now support, than setting it at a
|
|
11
|
+
* relatively high ~2**32 value which is what we do generally.
|
|
12
|
+
*
|
|
13
|
+
* Moreover, setting it to `Infinity` require us to use another MSE API,
|
|
14
|
+
* `setLiveSeekableRange` to properly allow seeking. We're used to MSE issues so
|
|
15
|
+
* I'm not too confident of using another MSE API for all platforms directly.
|
|
16
|
+
*
|
|
17
|
+
* So this methods just return `true` based on a whitelist of platform for which
|
|
18
|
+
* it has been detected that high `duration` values cause issues but setting it
|
|
19
|
+
* to Infinity AND playing with `setLiveSeekableRange` does not.
|
|
20
|
+
*
|
|
21
|
+
* @returns {boolean}
|
|
22
|
+
*/
|
|
23
|
+
export default function hasIssuesWithHighMediaSourceDuration(): boolean {
|
|
24
|
+
// For now only seen on the Webkit present in the PlayStation 5, for which the
|
|
25
|
+
// alternative is known to work.
|
|
26
|
+
return isPlayStation5;
|
|
27
|
+
}
|
|
@@ -14,6 +14,8 @@
|
|
|
14
14
|
* limitations under the License.
|
|
15
15
|
*/
|
|
16
16
|
|
|
17
|
+
import { ScoreConfidenceLevel } from "../utils/representation_score_calculator";
|
|
18
|
+
|
|
17
19
|
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
|
|
18
20
|
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
|
|
19
21
|
/* eslint-disable @typescript-eslint/no-var-requires */
|
|
@@ -47,12 +49,25 @@ describe("BufferBasedChooser", () => {
|
|
|
47
49
|
bufferGap: 0,
|
|
48
50
|
speed: 1,
|
|
49
51
|
currentBitrate: undefined,
|
|
50
|
-
currentScore: 4,
|
|
52
|
+
currentScore: { score: 4, confidenceLevel: ScoreConfidenceLevel.LOW },
|
|
53
|
+
})).toEqual(1);
|
|
54
|
+
expect(new BufferBasedChooser([1, 2, 3]).getEstimate({
|
|
55
|
+
bufferGap: 0,
|
|
56
|
+
speed: 1,
|
|
57
|
+
currentBitrate: undefined,
|
|
58
|
+
currentScore: { score: 4, confidenceLevel: ScoreConfidenceLevel.HIGH },
|
|
59
|
+
})).toEqual(1);
|
|
60
|
+
expect(new BufferBasedChooser([1, 2, 3]).getEstimate({
|
|
61
|
+
bufferGap: 0,
|
|
62
|
+
speed: 1,
|
|
63
|
+
currentBitrate: undefined,
|
|
64
|
+
currentScore: { score: 1, confidenceLevel: ScoreConfidenceLevel.LOW },
|
|
51
65
|
})).toEqual(1);
|
|
52
66
|
expect(new BufferBasedChooser([1, 2, 3]).getEstimate({
|
|
53
67
|
bufferGap: 0,
|
|
54
68
|
speed: 1,
|
|
55
|
-
|
|
69
|
+
currentBitrate: undefined,
|
|
70
|
+
currentScore: { score: 1, confidenceLevel: ScoreConfidenceLevel.HIGH },
|
|
56
71
|
})).toEqual(1);
|
|
57
72
|
});
|
|
58
73
|
|
|
@@ -76,7 +91,7 @@ describe("BufferBasedChooser", () => {
|
|
|
76
91
|
});
|
|
77
92
|
|
|
78
93
|
/* eslint-disable max-len */
|
|
79
|
-
it("should go to the next bitrate if
|
|
94
|
+
it("should not go to the next bitrate if we don't have a high enough maintainability score", () => {
|
|
80
95
|
/* eslint-enable max-len */
|
|
81
96
|
const logger = { debug: jest.fn() };
|
|
82
97
|
jest.mock("../../../log", () => ({ __esModule: true as const,
|
|
@@ -86,82 +101,82 @@ describe("BufferBasedChooser", () => {
|
|
|
86
101
|
bufferGap: 16,
|
|
87
102
|
speed: 1,
|
|
88
103
|
currentBitrate: 10,
|
|
89
|
-
currentScore: 1.
|
|
90
|
-
})).toEqual(
|
|
104
|
+
currentScore: { score: 1.15, confidenceLevel: ScoreConfidenceLevel.LOW },
|
|
105
|
+
})).toEqual(10);
|
|
91
106
|
expect(new BufferBasedChooser([10, 20, 40]).getEstimate({
|
|
92
107
|
bufferGap: 30,
|
|
93
108
|
speed: 1,
|
|
94
109
|
currentBitrate: 20,
|
|
95
|
-
currentScore: 1.
|
|
96
|
-
})).toEqual(
|
|
110
|
+
currentScore: { score: 1.15, confidenceLevel: ScoreConfidenceLevel.LOW },
|
|
111
|
+
})).toEqual(20);
|
|
97
112
|
expect(new BufferBasedChooser([10, 20, 40]).getEstimate({
|
|
98
113
|
bufferGap: 30,
|
|
99
114
|
speed: 1,
|
|
100
115
|
currentBitrate: 20,
|
|
101
|
-
currentScore: 100,
|
|
102
|
-
})).toEqual(
|
|
116
|
+
currentScore: { score: 100, confidenceLevel: ScoreConfidenceLevel.LOW },
|
|
117
|
+
})).toEqual(20);
|
|
103
118
|
expect(new BufferBasedChooser([10, 20, 40]).getEstimate({
|
|
104
119
|
bufferGap: 30,
|
|
105
120
|
speed: 2,
|
|
106
121
|
currentBitrate: 20,
|
|
107
|
-
currentScore: 2.
|
|
108
|
-
})).toEqual(
|
|
122
|
+
currentScore: { score: 2.30, confidenceLevel: ScoreConfidenceLevel.LOW },
|
|
123
|
+
})).toEqual(20);
|
|
109
124
|
expect(new BufferBasedChooser([10, 20, 20, 40]).getEstimate({
|
|
110
125
|
bufferGap: 30,
|
|
111
126
|
speed: 2,
|
|
112
127
|
currentBitrate: 20,
|
|
113
|
-
currentScore: 2.
|
|
114
|
-
})).toEqual(
|
|
128
|
+
currentScore: { score: 2.30, confidenceLevel: ScoreConfidenceLevel.LOW },
|
|
129
|
+
})).toEqual(20);
|
|
115
130
|
expect(new BufferBasedChooser([10, 20, 40]).getEstimate({
|
|
116
131
|
bufferGap: 30,
|
|
117
132
|
speed: 0, // 0 is a special case
|
|
118
133
|
currentBitrate: 20,
|
|
119
|
-
currentScore: 100,
|
|
120
|
-
})).toEqual(
|
|
134
|
+
currentScore: { score: 100, confidenceLevel: ScoreConfidenceLevel.LOW },
|
|
135
|
+
})).toEqual(20);
|
|
121
136
|
});
|
|
122
137
|
|
|
123
138
|
/* eslint-disable max-len */
|
|
124
|
-
it("should go to the next bitrate if the current one is maintainable and we have
|
|
139
|
+
it("should go to the next bitrate if the current one is maintainable and we have more buffer than the next level", () => {
|
|
125
140
|
/* eslint-enable max-len */
|
|
126
141
|
const logger = { debug: jest.fn() };
|
|
127
142
|
jest.mock("../../../log", () => ({ __esModule: true as const,
|
|
128
143
|
default: logger }));
|
|
129
144
|
const BufferBasedChooser = jest.requireActual("../buffer_based_chooser").default;
|
|
130
145
|
expect(new BufferBasedChooser([10, 20, 40]).getEstimate({
|
|
131
|
-
bufferGap:
|
|
146
|
+
bufferGap: 16,
|
|
132
147
|
speed: 1,
|
|
133
148
|
currentBitrate: 10,
|
|
134
|
-
currentScore: 1.
|
|
149
|
+
currentScore: { score: 1.15, confidenceLevel: ScoreConfidenceLevel.HIGH },
|
|
135
150
|
})).toEqual(20);
|
|
136
151
|
expect(new BufferBasedChooser([10, 20, 40]).getEstimate({
|
|
137
|
-
bufferGap:
|
|
152
|
+
bufferGap: 30,
|
|
138
153
|
speed: 1,
|
|
139
154
|
currentBitrate: 20,
|
|
140
|
-
currentScore: 1.
|
|
155
|
+
currentScore: { score: 1.15, confidenceLevel: ScoreConfidenceLevel.HIGH },
|
|
141
156
|
})).toEqual(40);
|
|
142
157
|
expect(new BufferBasedChooser([10, 20, 40]).getEstimate({
|
|
143
|
-
bufferGap:
|
|
158
|
+
bufferGap: 30,
|
|
144
159
|
speed: 1,
|
|
145
160
|
currentBitrate: 20,
|
|
146
|
-
currentScore: 100,
|
|
161
|
+
currentScore: { score: 100, confidenceLevel: ScoreConfidenceLevel.HIGH },
|
|
147
162
|
})).toEqual(40);
|
|
148
163
|
expect(new BufferBasedChooser([10, 20, 40]).getEstimate({
|
|
149
|
-
bufferGap:
|
|
164
|
+
bufferGap: 30,
|
|
150
165
|
speed: 2,
|
|
151
166
|
currentBitrate: 20,
|
|
152
|
-
currentScore: 2.
|
|
167
|
+
currentScore: { score: 2.30, confidenceLevel: ScoreConfidenceLevel.HIGH },
|
|
153
168
|
})).toEqual(40);
|
|
154
169
|
expect(new BufferBasedChooser([10, 20, 20, 40]).getEstimate({
|
|
155
|
-
bufferGap:
|
|
170
|
+
bufferGap: 30,
|
|
156
171
|
speed: 2,
|
|
157
172
|
currentBitrate: 20,
|
|
158
|
-
currentScore: 2.
|
|
173
|
+
currentScore: { score: 2.30, confidenceLevel: ScoreConfidenceLevel.HIGH },
|
|
159
174
|
})).toEqual(40);
|
|
160
175
|
expect(new BufferBasedChooser([10, 20, 40]).getEstimate({
|
|
161
|
-
bufferGap:
|
|
176
|
+
bufferGap: 30,
|
|
162
177
|
speed: 0, // 0 is a special case
|
|
163
178
|
currentBitrate: 20,
|
|
164
|
-
currentScore: 100,
|
|
179
|
+
currentScore: { score: 100, confidenceLevel: ScoreConfidenceLevel.HIGH },
|
|
165
180
|
})).toEqual(40);
|
|
166
181
|
});
|
|
167
182
|
|
|
@@ -176,31 +191,31 @@ describe("BufferBasedChooser", () => {
|
|
|
176
191
|
bufferGap: 6,
|
|
177
192
|
speed: 1,
|
|
178
193
|
currentBitrate: 10,
|
|
179
|
-
currentScore: 1.
|
|
194
|
+
currentScore: { score: 1.15, confidenceLevel: ScoreConfidenceLevel.HIGH },
|
|
180
195
|
})).toEqual(10);
|
|
181
196
|
expect(new BufferBasedChooser([10, 20, 40]).getEstimate({
|
|
182
|
-
bufferGap:
|
|
197
|
+
bufferGap: 13,
|
|
183
198
|
speed: 1,
|
|
184
199
|
currentBitrate: 20,
|
|
185
|
-
currentScore: 1.
|
|
200
|
+
currentScore: { score: 1.15, confidenceLevel: ScoreConfidenceLevel.HIGH },
|
|
186
201
|
})).toEqual(20);
|
|
187
202
|
expect(new BufferBasedChooser([10, 20, 40]).getEstimate({
|
|
188
|
-
bufferGap:
|
|
203
|
+
bufferGap: 13,
|
|
189
204
|
speed: 1,
|
|
190
205
|
currentBitrate: 20,
|
|
191
|
-
currentScore: 100,
|
|
206
|
+
currentScore: { score: 100, confidenceLevel: ScoreConfidenceLevel.HIGH },
|
|
192
207
|
})).toEqual(20);
|
|
193
208
|
expect(new BufferBasedChooser([10, 20, 20, 40]).getEstimate({
|
|
194
|
-
bufferGap:
|
|
209
|
+
bufferGap: 13,
|
|
195
210
|
speed: 1,
|
|
196
211
|
currentBitrate: 20,
|
|
197
|
-
currentScore: 100,
|
|
212
|
+
currentScore: { score: 100, confidenceLevel: ScoreConfidenceLevel.HIGH },
|
|
198
213
|
})).toEqual(20);
|
|
199
214
|
expect(new BufferBasedChooser([10, 20, 40]).getEstimate({
|
|
200
|
-
bufferGap:
|
|
215
|
+
bufferGap: 13,
|
|
201
216
|
speed: 2,
|
|
202
217
|
currentBitrate: 20,
|
|
203
|
-
currentScore: 2.
|
|
218
|
+
currentScore: { score: 2.30, confidenceLevel: ScoreConfidenceLevel.HIGH },
|
|
204
219
|
})).toEqual(20);
|
|
205
220
|
});
|
|
206
221
|
|
|
@@ -216,13 +231,13 @@ describe("BufferBasedChooser", () => {
|
|
|
216
231
|
bufferGap: 100000000000,
|
|
217
232
|
speed: 1,
|
|
218
233
|
currentBitrate: 40,
|
|
219
|
-
currentScore: 1000000,
|
|
234
|
+
currentScore: { score: 1000000, confidenceLevel: ScoreConfidenceLevel.HIGH },
|
|
220
235
|
})).toEqual(40);
|
|
221
236
|
expect(new BufferBasedChooser([10, 20, 40, 40]).getEstimate({
|
|
222
237
|
bufferGap: 100000000000,
|
|
223
238
|
speed: 1,
|
|
224
239
|
currentBitrate: 40,
|
|
225
|
-
currentScore: 1000000,
|
|
240
|
+
currentScore: { score: 1000000, confidenceLevel: ScoreConfidenceLevel.HIGH },
|
|
226
241
|
})).toEqual(40);
|
|
227
242
|
});
|
|
228
243
|
|
|
@@ -237,31 +252,115 @@ describe("BufferBasedChooser", () => {
|
|
|
237
252
|
bufferGap: 15,
|
|
238
253
|
speed: 2,
|
|
239
254
|
currentBitrate: 10,
|
|
240
|
-
currentScore:
|
|
255
|
+
currentScore: { score: 2, confidenceLevel: ScoreConfidenceLevel.HIGH },
|
|
241
256
|
})).toEqual(10);
|
|
242
257
|
expect(new BufferBasedChooser([10, 20, 40]).getEstimate({
|
|
243
|
-
bufferGap:
|
|
258
|
+
bufferGap: 22,
|
|
244
259
|
speed: 2,
|
|
245
260
|
currentBitrate: 20,
|
|
246
|
-
currentScore:
|
|
261
|
+
currentScore: { score: 2, confidenceLevel: ScoreConfidenceLevel.HIGH },
|
|
247
262
|
})).toEqual(20);
|
|
248
263
|
expect(new BufferBasedChooser([10, 20, 40]).getEstimate({
|
|
249
|
-
bufferGap:
|
|
264
|
+
bufferGap: 22,
|
|
250
265
|
speed: 100,
|
|
251
266
|
currentBitrate: 20,
|
|
252
|
-
currentScore: 100,
|
|
267
|
+
currentScore: { score: 100, confidenceLevel: ScoreConfidenceLevel.HIGH },
|
|
253
268
|
})).toEqual(20);
|
|
254
269
|
expect(new BufferBasedChooser([10, 20, 20, 40]).getEstimate({
|
|
255
|
-
bufferGap:
|
|
270
|
+
bufferGap: 22,
|
|
256
271
|
speed: 100,
|
|
257
272
|
currentBitrate: 20,
|
|
258
|
-
currentScore: 100,
|
|
273
|
+
currentScore: { score: 100, confidenceLevel: ScoreConfidenceLevel.HIGH },
|
|
259
274
|
})).toEqual(20);
|
|
260
275
|
expect(new BufferBasedChooser([10, 20, 40]).getEstimate({
|
|
261
|
-
bufferGap:
|
|
276
|
+
bufferGap: 22,
|
|
277
|
+
speed: 3,
|
|
278
|
+
currentBitrate: 20,
|
|
279
|
+
currentScore: { score: 3, confidenceLevel: ScoreConfidenceLevel.HIGH },
|
|
280
|
+
})).toEqual(20);
|
|
281
|
+
});
|
|
282
|
+
|
|
283
|
+
/* eslint-disable max-len */
|
|
284
|
+
it("should lower bitrate if the current one is not maintainable due to the speed", () => {
|
|
285
|
+
/* eslint-enable max-len */
|
|
286
|
+
const logger = { debug: jest.fn() };
|
|
287
|
+
jest.mock("../../../log", () => ({ __esModule: true as const,
|
|
288
|
+
default: logger }));
|
|
289
|
+
const BufferBasedChooser = jest.requireActual("../buffer_based_chooser").default;
|
|
290
|
+
expect(new BufferBasedChooser([10, 20, 40]).getEstimate({
|
|
291
|
+
bufferGap: 15,
|
|
292
|
+
speed: 2,
|
|
293
|
+
currentBitrate: 10,
|
|
294
|
+
currentScore: { score: 1.9, confidenceLevel: ScoreConfidenceLevel.HIGH },
|
|
295
|
+
})).toEqual(10);
|
|
296
|
+
expect(new BufferBasedChooser([10, 20, 40]).getEstimate({
|
|
297
|
+
bufferGap: 22,
|
|
298
|
+
speed: 2,
|
|
299
|
+
currentBitrate: 20,
|
|
300
|
+
currentScore: { score: 1.9, confidenceLevel: ScoreConfidenceLevel.HIGH },
|
|
301
|
+
})).toEqual(10);
|
|
302
|
+
expect(new BufferBasedChooser([10, 20, 40]).getEstimate({
|
|
303
|
+
bufferGap: 22,
|
|
304
|
+
speed: 100,
|
|
305
|
+
currentBitrate: 20,
|
|
306
|
+
currentScore: { score: 99, confidenceLevel: ScoreConfidenceLevel.HIGH },
|
|
307
|
+
})).toEqual(10);
|
|
308
|
+
expect(new BufferBasedChooser([10, 20, 20, 40]).getEstimate({
|
|
309
|
+
bufferGap: 22,
|
|
310
|
+
speed: 100,
|
|
311
|
+
currentBitrate: 20,
|
|
312
|
+
currentScore: { score: 99, confidenceLevel: ScoreConfidenceLevel.HIGH },
|
|
313
|
+
})).toEqual(10);
|
|
314
|
+
expect(new BufferBasedChooser([10, 20, 40]).getEstimate({
|
|
315
|
+
bufferGap: 22,
|
|
316
|
+
speed: 3,
|
|
317
|
+
currentBitrate: 20,
|
|
318
|
+
currentScore: { score: 2.5, confidenceLevel: ScoreConfidenceLevel.HIGH },
|
|
319
|
+
})).toEqual(10);
|
|
320
|
+
});
|
|
321
|
+
|
|
322
|
+
/* eslint-disable max-len */
|
|
323
|
+
it("should not lower bitrate if the current one is not maintainable due to the speed but confidence on the score is low", () => {
|
|
324
|
+
/* eslint-enable max-len */
|
|
325
|
+
const logger = { debug: jest.fn() };
|
|
326
|
+
jest.mock("../../../log", () => ({ __esModule: true as const,
|
|
327
|
+
default: logger }));
|
|
328
|
+
const BufferBasedChooser = jest.requireActual("../buffer_based_chooser").default;
|
|
329
|
+
expect(new BufferBasedChooser([10, 20, 40]).getEstimate({
|
|
330
|
+
bufferGap: 15,
|
|
331
|
+
speed: 2,
|
|
332
|
+
currentBitrate: 10,
|
|
333
|
+
currentScore: { score: 1.9, confidenceLevel: ScoreConfidenceLevel.LOW },
|
|
334
|
+
})).toEqual(10);
|
|
335
|
+
expect(new BufferBasedChooser([10, 20, 40]).getEstimate({
|
|
336
|
+
bufferGap: 22,
|
|
337
|
+
speed: 2,
|
|
338
|
+
currentBitrate: 20,
|
|
339
|
+
currentScore: undefined,
|
|
340
|
+
})).toEqual(20);
|
|
341
|
+
expect(new BufferBasedChooser([10, 20, 40]).getEstimate({
|
|
342
|
+
bufferGap: 22,
|
|
343
|
+
speed: 2,
|
|
344
|
+
currentBitrate: 20,
|
|
345
|
+
currentScore: { score: 1.9, confidenceLevel: ScoreConfidenceLevel.LOW },
|
|
346
|
+
})).toEqual(20);
|
|
347
|
+
expect(new BufferBasedChooser([10, 20, 40]).getEstimate({
|
|
348
|
+
bufferGap: 22,
|
|
349
|
+
speed: 100,
|
|
350
|
+
currentBitrate: 20,
|
|
351
|
+
currentScore: { score: 99, confidenceLevel: ScoreConfidenceLevel.LOW },
|
|
352
|
+
})).toEqual(20);
|
|
353
|
+
expect(new BufferBasedChooser([10, 20, 20, 40]).getEstimate({
|
|
354
|
+
bufferGap: 22,
|
|
355
|
+
speed: 100,
|
|
356
|
+
currentBitrate: 20,
|
|
357
|
+
currentScore: { score: 99, confidenceLevel: ScoreConfidenceLevel.LOW },
|
|
358
|
+
})).toEqual(20);
|
|
359
|
+
expect(new BufferBasedChooser([10, 20, 40]).getEstimate({
|
|
360
|
+
bufferGap: 22,
|
|
262
361
|
speed: 3,
|
|
263
362
|
currentBitrate: 20,
|
|
264
|
-
currentScore: 2.
|
|
363
|
+
currentScore: { score: 2.5, confidenceLevel: ScoreConfidenceLevel.LOW },
|
|
265
364
|
})).toEqual(20);
|
|
266
365
|
});
|
|
267
366
|
|
|
@@ -317,8 +317,7 @@ function getEstimateReference(
|
|
|
317
317
|
const timeRanges = val.buffered;
|
|
318
318
|
const bufferGap = getLeftSizeOfRange(timeRanges, position.last);
|
|
319
319
|
const { representation } = val.content;
|
|
320
|
-
const
|
|
321
|
-
const currentScore = scoreData?.[0];
|
|
320
|
+
const currentScore = scoreCalculator.getEstimate(representation);
|
|
322
321
|
const currentBitrate = representation.bitrate;
|
|
323
322
|
const observation = { bufferGap, currentBitrate, currentScore, speed };
|
|
324
323
|
currentBufferBasedEstimate = bufferBasedChooser.getEstimate(observation);
|