From cc801abe52243b2cf3dab500f15704e3f5b00553 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Eirik=20Jo=20Bj=C3=B6rnerstedt?= Date: Mon, 31 Jul 2023 12:00:19 +0100 Subject: [PATCH 01/17] chore: point bsp at v4.7 branch --- package-lock.json | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package-lock.json b/package-lock.json index 7a792f8c..8bf1b075 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,7 +10,7 @@ "hasInstallScript": true, "license": "Apache-2.0", "dependencies": { - "dashjs": "github:bbc/dash.js#smp-v3.2.0-8", + "dashjs": "github:bbc/dash.js#smp-v4.7", "smp-imsc": "github:bbc/imscJS#v1.0.3" }, "devDependencies": { diff --git a/package.json b/package.json index b712d464..c1b971a9 100644 --- a/package.json +++ b/package.json @@ -54,7 +54,7 @@ "rollup-plugin-visualizer": "^5.5.2" }, "dependencies": { - "dashjs": "github:bbc/dash.js#smp-v3.2.0-8", + "dashjs": "github:bbc/dash.js#smp-v4.7", "smp-imsc": "github:bbc/imscJS#v1.0.3" }, "repository": { From d0eacc626fefc4870c089ef16af99cf7515885e3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Eirik=20Jo=20Bj=C3=B6rnerstedt?= Date: Mon, 31 Jul 2023 12:01:04 +0100 Subject: [PATCH 02/17] feat!: restructure settings object --- src/playbackstrategy/msestrategy.js | 18 +++++++++++------- src/playbackstrategy/msestrategy.test.js | 14 ++++---------- 2 files changed, 15 insertions(+), 17 deletions(-) diff --git a/src/playbackstrategy/msestrategy.js b/src/playbackstrategy/msestrategy.js index 1d46943f..0db3d6a6 100644 --- a/src/playbackstrategy/msestrategy.js +++ b/src/playbackstrategy/msestrategy.js @@ -48,10 +48,14 @@ function MSEStrategy(mediaSources, windowType, mediaKind, playbackElement, isUHD logLevel: 2, }, streaming: { - liveDelay: 1.1, - bufferToKeep: 4, - bufferTimeAtTopQuality: 12, - bufferTimeAtTopQualityLongForm: 15, + buffer: { + bufferToKeep: 4, + bufferTimeAtTopQuality: 12, + bufferTimeAtTopQualityLongForm: 15, + }, + delay: { + liveDelay: 1.1, + }, }, }, customPlayerSettings @@ -341,7 +345,7 @@ function MSEStrategy(mediaSources, windowType, mediaKind, playbackElement, isUHD } function getClampedTime(time, range) { - return Math.min(Math.max(time, range.start), range.end - playerSettings.streaming.liveDelay) + return Math.min(Math.max(time, range.start), range.end - playerSettings.streaming.delay.liveDelay) } function load(mimeType, playbackTime) { @@ -408,7 +412,7 @@ function MSEStrategy(mediaSources, windowType, mediaKind, playbackElement, isUHD if (dvrInfo) { return { start: dvrInfo.range.start - timeCorrection, - end: dvrInfo.range.end - timeCorrection - playerSettings.streaming.liveDelay, + end: dvrInfo.range.end - timeCorrection - playerSettings.streaming.delay.liveDelay, } } } @@ -445,7 +449,7 @@ function MSEStrategy(mediaSources, windowType, mediaKind, playbackElement, isUHD function calculateSeekOffset(time) { function getClampedTimeForLive(time) { - return Math.min(Math.max(time, 0), mediaPlayer.getDVRWindowSize() - playerSettings.streaming.liveDelay) + return Math.min(Math.max(time, 0), mediaPlayer.getDVRWindowSize() - playerSettings.streaming.delay.liveDelay) } if (windowType === WindowTypes.SLIDING) { diff --git a/src/playbackstrategy/msestrategy.test.js b/src/playbackstrategy/msestrategy.test.js index 14eda0fe..b92e3436 100644 --- a/src/playbackstrategy/msestrategy.test.js +++ b/src/playbackstrategy/msestrategy.test.js @@ -518,11 +518,8 @@ describe("Media Source Extensions Playback Strategy", () => { }) it("returns the end time taking the live delay into account for a live stream", () => { - const customPlayerSettings = { - streaming: { - liveDelay: 20, - }, - } + const customPlayerSettings = { streaming: { delay: { liveDelay: 20 } } } + setUpMSE(0, WindowTypes.SLIDING, MediaKinds.VIDEO, 100, 1000, customPlayerSettings) mseStrategy.load(null, 45) @@ -530,11 +527,8 @@ describe("Media Source Extensions Playback Strategy", () => { }) it("returns the end time ignoring the live delay for an on demand stream", () => { - const customPlayerSettings = { - streaming: { - liveDelay: 20, - }, - } + const customPlayerSettings = { streaming: { delay: { liveDelay: 20 } } } + setUpMSE(0, WindowTypes.STATIC, MediaKinds.VIDEO, 100, 1000, customPlayerSettings) mseStrategy.load(null, 45) From 806e4fd4394ab0d600f0751d566500f96a845865 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Eirik=20Jo=20Bj=C3=B6rnerstedt?= Date: Wed, 2 Aug 2023 10:45:24 +0100 Subject: [PATCH 03/17] chore: bump dash.js commit hash --- package-lock.json | 503 ++++++++++++---------------------------------- 1 file changed, 131 insertions(+), 372 deletions(-) diff --git a/package-lock.json b/package-lock.json index 8bf1b075..c616ca86 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4055,6 +4055,7 @@ "version": "6.12.6", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", @@ -4069,7 +4070,8 @@ "node_modules/ajv/node_modules/fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true }, "node_modules/ansi-escapes": { "version": "4.3.2", @@ -4175,39 +4177,11 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/asn1": { - "version": "0.2.6", - "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.6.tgz", - "integrity": "sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==", - "dependencies": { - "safer-buffer": "~2.1.0" - } - }, - "node_modules/assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==", - "engines": { - "node": ">=0.8" - } - }, "node_modules/asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" - }, - "node_modules/aws-sign2": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", - "integrity": "sha512-08kcGqnYf/YmjoRhfxyu+CLxBjUtHLXLXX/vUfx9l2LYzG3c1m61nrpyFUZI6zeS+Li/wWMMidD9KgrqtGq3mA==", - "engines": { - "node": "*" - } - }, - "node_modules/aws4": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.11.0.tgz", - "integrity": "sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==" + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", + "dev": true }, "node_modules/babel-jest": { "version": "27.5.1", @@ -4425,12 +4399,40 @@ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", "dev": true }, - "node_modules/bcrypt-pbkdf": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", - "integrity": "sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w==", + "node_modules/bcp-47": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/bcp-47/-/bcp-47-1.0.8.tgz", + "integrity": "sha512-Y9y1QNBBtYtv7hcmoX0tR+tUNSFZGZ6OL6vKPObq8BbOhkCoyayF6ogfLTgAli/KuAEbsYHYUNq2AQuY6IuLag==", + "dependencies": { + "is-alphabetical": "^1.0.0", + "is-alphanumerical": "^1.0.0", + "is-decimal": "^1.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/bcp-47-match": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/bcp-47-match/-/bcp-47-match-1.0.3.tgz", + "integrity": "sha512-LggQ4YTdjWQSKELZF5JwchnBa1u0pIQSZf5lSdOHEdbVP55h0qICA/FUp3+W99q0xqxYa1ZQizTUH87gecII5w==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/bcp-47-normalize": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/bcp-47-normalize/-/bcp-47-normalize-1.1.1.tgz", + "integrity": "sha512-jWZ1Jdu3cs0EZdfCkS0UE9Gg01PtxnChjEBySeB+Zo6nkqtFfnvtoQQgP1qU1Oo4qgJgxhTI6Sf9y/pZIhPs0A==", "dependencies": { - "tweetnacl": "^0.14.3" + "bcp-47": "^1.0.0", + "bcp-47-match": "^1.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" } }, "node_modules/binary-extensions": { @@ -4445,7 +4447,8 @@ "node_modules/bluebird": { "version": "3.7.2", "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", - "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==" + "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", + "dev": true }, "node_modules/brace-expansion": { "version": "1.1.11", @@ -4581,11 +4584,6 @@ } ] }, - "node_modules/caseless": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", - "integrity": "sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==" - }, "node_modules/catharsis": { "version": "0.9.0", "resolved": "https://registry.npmjs.org/catharsis/-/catharsis-0.9.0.tgz", @@ -4736,9 +4734,9 @@ } }, "node_modules/codem-isoboxer": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/codem-isoboxer/-/codem-isoboxer-0.3.6.tgz", - "integrity": "sha512-LuO8/7LW6XuR5ERn1yavXAfodGRhuY2yP60JTZIw5yNYMCE5lUVbk3NFUCJxjnphQH+Xemp5hOGb1LgUXm00Xw==" + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/codem-isoboxer/-/codem-isoboxer-0.3.9.tgz", + "integrity": "sha512-4XOTqEzBWrGOZaMd+sTED2hLpzfBbiQCf1W6OBGkIHqk1D8uwy8WFLazVbdQwfDpQ+vf39lqTGPa9IhWW0roTA==" }, "node_modules/collect-v8-coverage": { "version": "1.0.1", @@ -4765,6 +4763,7 @@ "version": "1.0.8", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "dev": true, "dependencies": { "delayed-stream": "~1.0.0" }, @@ -4822,11 +4821,6 @@ "semver": "bin/semver.js" } }, - "node_modules/core-util-is": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==" - }, "node_modules/cross-spawn": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", @@ -4865,29 +4859,21 @@ "integrity": "sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==", "dev": true }, - "node_modules/dashdash": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", - "integrity": "sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g==", - "dependencies": { - "assert-plus": "^1.0.0" - }, - "engines": { - "node": ">=0.10" - } - }, "node_modules/dashjs": { - "version": "3.2.0", - "resolved": "git+ssh://git@github.com/bbc/dash.js.git#5b8b4de675485fcde20292a03ca48d1ec38c2c6b", + "version": "4.7.1", + "resolved": "git+ssh://git@github.com/bbc/dash.js.git#6a33af272db49f30a7a03b2db5b3b2a7a21777d7", "license": "BSD-3-Clause", "dependencies": { - "codem-isoboxer": "0.3.6", + "bcp-47-match": "^1.0.3", + "bcp-47-normalize": "^1.1.1", + "codem-isoboxer": "0.3.9", + "es6-promise": "^4.2.8", "fast-deep-equal": "2.0.1", "html-entities": "^1.2.1", - "imsc": "^1.0.2", + "imsc": "^1.1.3", "localforage": "^1.7.1", - "request": "^2.87.0", - "request-promise": "^4.2.2" + "path-browserify": "^1.0.1", + "ua-parser-js": "^1.0.2" } }, "node_modules/data-urls": { @@ -4977,6 +4963,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "dev": true, "engines": { "node": ">=0.4.0" } @@ -5035,15 +5022,6 @@ "node": ">=12" } }, - "node_modules/ecc-jsbn": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", - "integrity": "sha512-eh9O+hwRHNbG4BLTjEl3nw044CkGm5X6LoaCf7LPp7UU8Qrt47JYNi6nPX8xjW97TKGKm1ouctg0QSpZe9qrnw==", - "dependencies": { - "jsbn": "~0.1.0", - "safer-buffer": "^2.1.0" - } - }, "node_modules/electron-to-chromium": { "version": "1.4.184", "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.184.tgz", @@ -5150,6 +5128,11 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/es6-promise": { + "version": "4.2.8", + "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz", + "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==" + }, "node_modules/escalade": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", @@ -6043,19 +6026,6 @@ "node": ">=8" } }, - "node_modules/extend": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" - }, - "node_modules/extsprintf": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", - "integrity": "sha512-11Ndz7Nv+mvAC1j0ktTa7fAb0vLyGGX+rMHNBYQviQDGU0Hw7lhctJANqbPhu9nV9/izT/IntTgZ7Im/9LJs9g==", - "engines": [ - "node >=0.6.0" - ] - }, "node_modules/fast-deep-equal": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", @@ -6080,7 +6050,8 @@ "node_modules/fast-json-stable-stringify": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==" + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true }, "node_modules/fast-levenshtein": { "version": "2.0.6", @@ -6162,14 +6133,6 @@ "integrity": "sha512-0sQoMh9s0BYsm+12Huy/rkKxVu4R1+r96YX5cG44rHV0pQ6iC3Q+mkoMFaGWObMFYQxCVT+ssG1ksneA2MI9KQ==", "dev": true }, - "node_modules/forever-agent": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", - "integrity": "sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw==", - "engines": { - "node": "*" - } - }, "node_modules/form-data": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", @@ -6320,14 +6283,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/getpass": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", - "integrity": "sha512-0fzj9JxOLfJ+XGLhR8ze3unN0KZCgZwiSSDz168VERjK8Wl8kVSdcu2kspd4s4wtAa1y/qrVRiAA0WclVsu0ng==", - "dependencies": { - "assert-plus": "^1.0.0" - } - }, "node_modules/glob": { "version": "7.2.3", "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", @@ -6401,27 +6356,6 @@ "integrity": "sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==", "dev": true }, - "node_modules/har-schema": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", - "integrity": "sha512-Oqluz6zhGX8cyRaTQlFMPw80bSJVG2x/cFb8ZPhUILGgHka9SsokCCOQgpveePerqidZOrT14ipqfJb7ILcW5Q==", - "engines": { - "node": ">=4" - } - }, - "node_modules/har-validator": { - "version": "5.1.5", - "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz", - "integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==", - "deprecated": "this library is no longer supported", - "dependencies": { - "ajv": "^6.12.3", - "har-schema": "^2.0.0" - }, - "engines": { - "node": ">=6" - } - }, "node_modules/has": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", @@ -6564,20 +6498,6 @@ "node": ">= 6" } }, - "node_modules/http-signature": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", - "integrity": "sha512-CAbnr6Rz4CYQkLYUtSNXxQPUH2gK8f3iWexVlsnMeD+GjlsQ0Xsy1cOX+mN3dtxYomRy21CiOzU8Uhw6OwncEQ==", - "dependencies": { - "assert-plus": "^1.0.0", - "jsprim": "^1.2.2", - "sshpk": "^1.7.0" - }, - "engines": { - "node": ">=0.8", - "npm": ">=1.3.7" - } - }, "node_modules/https-proxy-agent": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", @@ -6741,6 +6661,28 @@ "node": ">= 0.4" } }, + "node_modules/is-alphabetical": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-1.0.4.tgz", + "integrity": "sha512-DwzsA04LQ10FHTZuL0/grVDk4rFoVH1pjAToYwBrHSxcrBIGQuXrQMtD5U1b0U2XVgKZCTLLP8u2Qxqhy3l2Vg==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/is-alphanumerical": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-1.0.4.tgz", + "integrity": "sha512-UzoZUr+XfVz3t3v4KyGEniVL9BDRoQtY7tOyrRybkVNjDFWyo1yhXNGrrBTQxp3ib9BLAWs7k2YKBQsFRkZG9A==", + "dependencies": { + "is-alphabetical": "^1.0.0", + "is-decimal": "^1.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/is-arrayish": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", @@ -6841,6 +6783,15 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-decimal": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-decimal/-/is-decimal-1.0.4.tgz", + "integrity": "sha512-RGdriMmQQvZ2aqaQq3awNA6dCGtKpiDFcOzrTWrDAT2MiWrKQVPmxLGHl7Y2nNu6led0kEyoX0enY0qXYsv9zw==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/is-docker": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", @@ -7034,7 +6985,8 @@ "node_modules/is-typedarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==" + "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==", + "dev": true }, "node_modules/is-weakref": { "version": "1.0.2", @@ -7066,11 +7018,6 @@ "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", "dev": true }, - "node_modules/isstream": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", - "integrity": "sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==" - }, "node_modules/istanbul-lib-coverage": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz", @@ -10284,11 +10231,6 @@ "xmlcreate": "^2.0.4" } }, - "node_modules/jsbn": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", - "integrity": "sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==" - }, "node_modules/jsdoc": { "version": "3.6.10", "resolved": "https://registry.npmjs.org/jsdoc/-/jsdoc-3.6.10.tgz", @@ -10411,15 +10353,11 @@ "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", "dev": true }, - "node_modules/json-schema": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz", - "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==" - }, "node_modules/json-schema-traverse": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true }, "node_modules/json-stable-stringify-without-jsonify": { "version": "1.0.1", @@ -10427,11 +10365,6 @@ "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", "dev": true }, - "node_modules/json-stringify-safe": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==" - }, "node_modules/json5": { "version": "2.2.3", "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", @@ -10462,20 +10395,6 @@ "graceful-fs": "^4.1.6" } }, - "node_modules/jsprim": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.2.tgz", - "integrity": "sha512-P2bSOMAc/ciLz6DzgjVlGJP9+BrJWu5UDGK70C2iweC5QBIeFf0ZXRvGjEj2uYgrY2MkAAhsSWHDWlFtEroZWw==", - "dependencies": { - "assert-plus": "1.0.0", - "extsprintf": "1.3.0", - "json-schema": "0.4.0", - "verror": "1.10.0" - }, - "engines": { - "node": ">=0.6.0" - } - }, "node_modules/klaw": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/klaw/-/klaw-4.0.1.tgz", @@ -10595,7 +10514,8 @@ "node_modules/lodash": { "version": "4.17.21", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "dev": true }, "node_modules/lodash.debounce": { "version": "4.0.8", @@ -10754,6 +10674,7 @@ "version": "1.52.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "dev": true, "engines": { "node": ">= 0.6" } @@ -10762,6 +10683,7 @@ "version": "2.1.35", "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dev": true, "dependencies": { "mime-db": "1.52.0" }, @@ -10913,14 +10835,6 @@ "integrity": "sha512-6xpotnECFy/og7tKSBVmUNft7J3jyXAka4XvG6AUhFWRz+Q/Ljus7znJAA3bxColfQLdS+XsjoodtJfCgeTEFQ==", "dev": true }, - "node_modules/oauth-sign": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", - "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", - "engines": { - "node": "*" - } - }, "node_modules/object-inspect": { "version": "1.12.2", "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.2.tgz", @@ -11146,6 +11060,11 @@ "url": "https://github.com/fb55/entities?sponsor=1" } }, + "node_modules/path-browserify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-1.0.1.tgz", + "integrity": "sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==" + }, "node_modules/path-exists": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", @@ -11188,11 +11107,6 @@ "node": ">=8" } }, - "node_modules/performance-now": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", - "integrity": "sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==" - }, "node_modules/picocolors": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", @@ -11307,12 +11221,14 @@ "node_modules/psl": { "version": "1.9.0", "resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz", - "integrity": "sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==" + "integrity": "sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==", + "dev": true }, "node_modules/punycode": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "dev": true, "engines": { "node": ">=6" } @@ -11333,14 +11249,6 @@ } ] }, - "node_modules/qs": { - "version": "6.5.3", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.3.tgz", - "integrity": "sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA==", - "engines": { - "node": ">=0.6" - } - }, "node_modules/querystringify": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz", @@ -11568,106 +11476,6 @@ "node": ">= 0.10" } }, - "node_modules/request": { - "version": "2.88.2", - "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", - "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==", - "deprecated": "request has been deprecated, see https://github.com/request/request/issues/3142", - "dependencies": { - "aws-sign2": "~0.7.0", - "aws4": "^1.8.0", - "caseless": "~0.12.0", - "combined-stream": "~1.0.6", - "extend": "~3.0.2", - "forever-agent": "~0.6.1", - "form-data": "~2.3.2", - "har-validator": "~5.1.3", - "http-signature": "~1.2.0", - "is-typedarray": "~1.0.0", - "isstream": "~0.1.2", - "json-stringify-safe": "~5.0.1", - "mime-types": "~2.1.19", - "oauth-sign": "~0.9.0", - "performance-now": "^2.1.0", - "qs": "~6.5.2", - "safe-buffer": "^5.1.2", - "tough-cookie": "~2.5.0", - "tunnel-agent": "^0.6.0", - "uuid": "^3.3.2" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/request-promise": { - "version": "4.2.6", - "resolved": "https://registry.npmjs.org/request-promise/-/request-promise-4.2.6.tgz", - "integrity": "sha512-HCHI3DJJUakkOr8fNoCc73E5nU5bqITjOYFMDrKHYOXWXrgD/SBaC7LjwuPymUprRyuF06UK7hd/lMHkmUXglQ==", - "deprecated": "request-promise has been deprecated because it extends the now deprecated request package, see https://github.com/request/request/issues/3142", - "dependencies": { - "bluebird": "^3.5.0", - "request-promise-core": "1.1.4", - "stealthy-require": "^1.1.1", - "tough-cookie": "^2.3.3" - }, - "engines": { - "node": ">=0.10.0" - }, - "peerDependencies": { - "request": "^2.34" - } - }, - "node_modules/request-promise-core": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/request-promise-core/-/request-promise-core-1.1.4.tgz", - "integrity": "sha512-TTbAfBBRdWD7aNNOoVOBH4pN/KigV6LyapYNNlAPA8JwbovRti1E88m3sYAwsLi5ryhPKsE9APwnjFTgdUjTpw==", - "dependencies": { - "lodash": "^4.17.19" - }, - "engines": { - "node": ">=0.10.0" - }, - "peerDependencies": { - "request": "^2.34" - } - }, - "node_modules/request-promise/node_modules/tough-cookie": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", - "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", - "dependencies": { - "psl": "^1.1.28", - "punycode": "^2.1.1" - }, - "engines": { - "node": ">=0.8" - } - }, - "node_modules/request/node_modules/form-data": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", - "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", - "dependencies": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.6", - "mime-types": "^2.1.12" - }, - "engines": { - "node": ">= 0.12" - } - }, - "node_modules/request/node_modules/tough-cookie": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", - "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", - "dependencies": { - "psl": "^1.1.28", - "punycode": "^2.1.1" - }, - "engines": { - "node": ">=0.8" - } - }, "node_modules/require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", @@ -11916,7 +11724,8 @@ "node_modules/safe-buffer": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true }, "node_modules/safe-regex": { "version": "2.1.1", @@ -11944,7 +11753,8 @@ "node_modules/safer-buffer": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "dev": true }, "node_modules/sax": { "version": "1.2.1", @@ -12133,30 +11943,6 @@ "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", "dev": true }, - "node_modules/sshpk": { - "version": "1.17.0", - "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.17.0.tgz", - "integrity": "sha512-/9HIEs1ZXGhSPE8X6Ccm7Nam1z8KcoCqPdI7ecm1N33EzAetWahvQWVqLZtaZQ+IDKX4IyA2o0gBzqIMkAagHQ==", - "dependencies": { - "asn1": "~0.2.3", - "assert-plus": "^1.0.0", - "bcrypt-pbkdf": "^1.0.0", - "dashdash": "^1.12.0", - "ecc-jsbn": "~0.1.1", - "getpass": "^0.1.1", - "jsbn": "~0.1.0", - "safer-buffer": "^2.0.2", - "tweetnacl": "~0.14.0" - }, - "bin": { - "sshpk-conv": "bin/sshpk-conv", - "sshpk-sign": "bin/sshpk-sign", - "sshpk-verify": "bin/sshpk-verify" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/stack-utils": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.6.tgz", @@ -12178,14 +11964,6 @@ "node": ">=8" } }, - "node_modules/stealthy-require": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/stealthy-require/-/stealthy-require-1.1.1.tgz", - "integrity": "sha512-ZnWpYnYugiOVEY5GkcuJK1io5V8QmNYChG62gSit9pQVGErXtrKuPC55ITaVSukmMta5qpMU7vqLt2Lnni4f/g==", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/string-length": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz", @@ -12486,22 +12264,6 @@ "typescript": ">=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta" } }, - "node_modules/tunnel-agent": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", - "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==", - "dependencies": { - "safe-buffer": "^5.0.1" - }, - "engines": { - "node": "*" - } - }, - "node_modules/tweetnacl": { - "version": "0.14.5", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==" - }, "node_modules/type-check": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", @@ -12558,6 +12320,24 @@ "node": ">=4.2.0" } }, + "node_modules/ua-parser-js": { + "version": "1.0.35", + "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-1.0.35.tgz", + "integrity": "sha512-fKnGuqmTBnIE+/KXSzCn4db8RTigUzw1AN0DmdU6hJovUTbYJKyqj+8Mt1c4VfRDnOVJnENmfYkIPZ946UrSAA==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/ua-parser-js" + }, + { + "type": "paypal", + "url": "https://paypal.me/faisalman" + } + ], + "engines": { + "node": "*" + } + }, "node_modules/uc.micro": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.6.tgz", @@ -12682,6 +12462,7 @@ "version": "4.4.1", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, "dependencies": { "punycode": "^2.1.0" } @@ -12696,15 +12477,6 @@ "requires-port": "^1.0.0" } }, - "node_modules/uuid": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", - "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", - "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.", - "bin": { - "uuid": "bin/uuid" - } - }, "node_modules/v8-to-istanbul": { "version": "9.1.0", "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.1.0.tgz", @@ -12729,19 +12501,6 @@ "spdx-expression-parse": "^3.0.0" } }, - "node_modules/verror": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", - "integrity": "sha512-ZZKSmDAEFOijERBLkmYfJ+vmk3w+7hOLYDNkRCuRuMJGEmqYNCNLyBBFwWKVMhfwaEF3WOd0Zlw86U/WC/+nYw==", - "engines": [ - "node >=0.6.0" - ], - "dependencies": { - "assert-plus": "^1.0.0", - "core-util-is": "1.0.2", - "extsprintf": "^1.2.0" - } - }, "node_modules/vscode-json-languageservice": { "version": "4.2.1", "resolved": "https://registry.npmjs.org/vscode-json-languageservice/-/vscode-json-languageservice-4.2.1.tgz", From 20089e3c19850417c68d981ec414a7d83748ba17 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Eirik=20Jo=20Bj=C3=B6rnerstedt?= Date: Wed, 2 Aug 2023 10:57:34 +0100 Subject: [PATCH 04/17] fix: change dash.js entrypoint --- src/playbackstrategy/msestrategy.js | 2 +- src/playbackstrategy/msestrategy.test.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/playbackstrategy/msestrategy.js b/src/playbackstrategy/msestrategy.js index 0db3d6a6..3247b96b 100644 --- a/src/playbackstrategy/msestrategy.js +++ b/src/playbackstrategy/msestrategy.js @@ -1,3 +1,4 @@ +import { MediaPlayer } from "dashjs/dist/dash.mediaplayer.min.js" import MediaState from "../models/mediastate" import WindowTypes from "../models/windowtypes" import DebugTool from "../debugger/debugtool" @@ -9,7 +10,6 @@ import DynamicWindowUtils from "../dynamicwindowutils" import TimeUtils from "../utils/timeutils" import DOMHelpers from "../domhelpers" import Utils from "../utils/playbackutils" -import { MediaPlayer } from "dashjs/index_mediaplayerOnly" import buildSourceAnchor, { TimelineZeroPoints } from "../utils/mse/build-source-anchor" function MSEStrategy(mediaSources, windowType, mediaKind, playbackElement, isUHD, customPlayerSettings) { diff --git a/src/playbackstrategy/msestrategy.test.js b/src/playbackstrategy/msestrategy.test.js index b92e3436..361a30e9 100644 --- a/src/playbackstrategy/msestrategy.test.js +++ b/src/playbackstrategy/msestrategy.test.js @@ -40,7 +40,7 @@ const mockDashMediaPlayer = { create: jest.fn(() => mockDashInstance), } -jest.mock("dashjs/index_mediaplayerOnly", () => ({ MediaPlayer: jest.fn(() => mockDashMediaPlayer) })) +jest.mock("dashjs/dist/dash.mediaplayer.min.js", () => ({ MediaPlayer: jest.fn(() => mockDashMediaPlayer) })) jest.mock("../dynamicwindowutils") describe("Media Source Extensions Playback Strategy", () => { From 503a23e49b20e6b9fa29c7632de7164336a90857 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Eirik=20Jo=20Bj=C3=B6rnerstedt?= Date: Wed, 2 Aug 2023 14:02:26 +0100 Subject: [PATCH 05/17] chore: bump dash.js commit hash --- package-lock.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package-lock.json b/package-lock.json index c616ca86..eebac47b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4861,7 +4861,7 @@ }, "node_modules/dashjs": { "version": "4.7.1", - "resolved": "git+ssh://git@github.com/bbc/dash.js.git#6a33af272db49f30a7a03b2db5b3b2a7a21777d7", + "resolved": "git+ssh://git@github.com/bbc/dash.js.git#c2ebaea1309219d69e20cc99bb7d8d375b0457f5", "license": "BSD-3-Clause", "dependencies": { "bcp-47-match": "^1.0.3", From a88199ec4e45f1fe0f333e801844d1e3ab4bdb23 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Eirik=20Jo=20Bj=C3=B6rnerstedt?= Date: Wed, 2 Aug 2023 15:17:12 +0100 Subject: [PATCH 06/17] chore: bump dash.js commit hash --- package-lock.json | 2 +- src/playbackstrategy/msestrategy.js | 2 +- src/playbackstrategy/msestrategy.test.js | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index eebac47b..6c37a119 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4861,7 +4861,7 @@ }, "node_modules/dashjs": { "version": "4.7.1", - "resolved": "git+ssh://git@github.com/bbc/dash.js.git#c2ebaea1309219d69e20cc99bb7d8d375b0457f5", + "resolved": "git+ssh://git@github.com/bbc/dash.js.git#f0c2fdc2dff904b9c17bf69e184b46509098b012", "license": "BSD-3-Clause", "dependencies": { "bcp-47-match": "^1.0.3", diff --git a/src/playbackstrategy/msestrategy.js b/src/playbackstrategy/msestrategy.js index 3247b96b..535caf20 100644 --- a/src/playbackstrategy/msestrategy.js +++ b/src/playbackstrategy/msestrategy.js @@ -1,4 +1,4 @@ -import { MediaPlayer } from "dashjs/dist/dash.mediaplayer.min.js" +import { MediaPlayer } from "dashjs/index_mediaplayerOnly" import MediaState from "../models/mediastate" import WindowTypes from "../models/windowtypes" import DebugTool from "../debugger/debugtool" diff --git a/src/playbackstrategy/msestrategy.test.js b/src/playbackstrategy/msestrategy.test.js index 361a30e9..b92e3436 100644 --- a/src/playbackstrategy/msestrategy.test.js +++ b/src/playbackstrategy/msestrategy.test.js @@ -40,7 +40,7 @@ const mockDashMediaPlayer = { create: jest.fn(() => mockDashInstance), } -jest.mock("dashjs/dist/dash.mediaplayer.min.js", () => ({ MediaPlayer: jest.fn(() => mockDashMediaPlayer) })) +jest.mock("dashjs/index_mediaplayerOnly", () => ({ MediaPlayer: jest.fn(() => mockDashMediaPlayer) })) jest.mock("../dynamicwindowutils") describe("Media Source Extensions Playback Strategy", () => { From 2d04fae8099c7f8e6ca39deaf721165f39ca5134 Mon Sep 17 00:00:00 2001 From: Peter Clay Holden Morris-Hind Date: Thu, 17 Aug 2023 15:11:49 +0100 Subject: [PATCH 07/17] setDuration is now setMediaDuration --- src/playbackstrategy/msestrategy.js | 2 +- src/playbackstrategy/msestrategy.test.js | 16 ++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/playbackstrategy/msestrategy.js b/src/playbackstrategy/msestrategy.js index 535caf20..b22b511a 100644 --- a/src/playbackstrategy/msestrategy.js +++ b/src/playbackstrategy/msestrategy.js @@ -207,7 +207,7 @@ function MSEStrategy(mediaSources, windowType, mediaKind, playbackElement, isUHD const setMseDuration = window.bigscreenPlayer.overrides && window.bigscreenPlayer.overrides.mseDurationOverride if (setMseDuration && (windowType === WindowTypes.SLIDING || windowType === WindowTypes.GROWING)) { // Workaround for no setLiveSeekableRange/clearLiveSeekableRange - mediaPlayer.setDuration(Number.MAX_SAFE_INTEGER) + mediaPlayer.setMediaDuration(Number.MAX_SAFE_INTEGER) } mediaPlayer.setBlacklistExpiryTime(mediaSources.failoverResetTime()) diff --git a/src/playbackstrategy/msestrategy.test.js b/src/playbackstrategy/msestrategy.test.js index b92e3436..fbbcde1e 100644 --- a/src/playbackstrategy/msestrategy.test.js +++ b/src/playbackstrategy/msestrategy.test.js @@ -30,7 +30,7 @@ const mockDashInstance = { getAverageThroughput: jest.fn(), getDVRWindowSize: jest.fn(), updateSettings: jest.fn(), - setDuration: jest.fn(), + setMediaDuration: jest.fn(), setPlaybackRate: jest.fn(), getPlaybackRate: jest.fn(), setBlacklistExpiryTime: jest.fn(), @@ -908,7 +908,7 @@ describe("Media Source Extensions Playback Strategy", () => { }) afterEach(() => { - mockDashInstance.setDuration.mockReset() + mockDashInstance.setMediaDuration.mockReset() }) describe("overrides dynamic stream duration", () => { @@ -922,7 +922,7 @@ describe("Media Source Extensions Playback Strategy", () => { eventHandlers.streamInitialized() - expect(mockDashInstance.setDuration).toHaveBeenCalledWith(Number.MAX_SAFE_INTEGER) + expect(mockDashInstance.setMediaDuration).toHaveBeenCalledWith(Number.MAX_SAFE_INTEGER) }) it("when mseDurationOverride configration property is true and window type is growing", () => { @@ -935,7 +935,7 @@ describe("Media Source Extensions Playback Strategy", () => { eventHandlers.streamInitialized() - expect(mockDashInstance.setDuration).toHaveBeenCalledWith(Number.MAX_SAFE_INTEGER) + expect(mockDashInstance.setMediaDuration).toHaveBeenCalledWith(Number.MAX_SAFE_INTEGER) }) }) @@ -950,7 +950,7 @@ describe("Media Source Extensions Playback Strategy", () => { eventHandlers.streamInitialized() - expect(mockDashInstance.setDuration).not.toHaveBeenCalledWith(Number.MAX_SAFE_INTEGER) + expect(mockDashInstance.setMediaDuration).not.toHaveBeenCalledWith(Number.MAX_SAFE_INTEGER) }) it("when mseDurationOverride configration property is false and window type is static", () => { @@ -963,7 +963,7 @@ describe("Media Source Extensions Playback Strategy", () => { eventHandlers.streamInitialized() - expect(mockDashInstance.setDuration).not.toHaveBeenCalledWith(Number.MAX_SAFE_INTEGER) + expect(mockDashInstance.setMediaDuration).not.toHaveBeenCalledWith(Number.MAX_SAFE_INTEGER) }) it("when mseDurationOverride configration property is false and window type is sliding", () => { @@ -976,7 +976,7 @@ describe("Media Source Extensions Playback Strategy", () => { eventHandlers.streamInitialized() - expect(mockDashInstance.setDuration).not.toHaveBeenCalledWith(Number.MAX_SAFE_INTEGER) + expect(mockDashInstance.setMediaDuration).not.toHaveBeenCalledWith(Number.MAX_SAFE_INTEGER) }) it("when mseDurationOverride configration property is false and window type is growing", () => { @@ -989,7 +989,7 @@ describe("Media Source Extensions Playback Strategy", () => { eventHandlers.streamInitialized() - expect(mockDashInstance.setDuration).not.toHaveBeenCalledWith(Number.MAX_SAFE_INTEGER) + expect(mockDashInstance.setMediaDuration).not.toHaveBeenCalledWith(Number.MAX_SAFE_INTEGER) }) }) }) From 53346979a48b8f47ee01d43acb7124cc02bd3a30 Mon Sep 17 00:00:00 2001 From: Peter Clay Holden Morris-Hind Date: Thu, 17 Aug 2023 15:16:22 +0100 Subject: [PATCH 08/17] Update Dash Version --- package-lock.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package-lock.json b/package-lock.json index 6c37a119..c7a1147c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4861,7 +4861,7 @@ }, "node_modules/dashjs": { "version": "4.7.1", - "resolved": "git+ssh://git@github.com/bbc/dash.js.git#f0c2fdc2dff904b9c17bf69e184b46509098b012", + "resolved": "git+ssh://git@github.com/bbc/dash.js.git#bff2359de9cbc96fe31378f48fff5e4418359f4c", "license": "BSD-3-Clause", "dependencies": { "bcp-47-match": "^1.0.3", From 5e955b39567287a09e9170f295d61d68542a4020 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Eirik=20Jo=20Bj=C3=B6rnerstedt?= Date: Mon, 21 Aug 2023 11:08:24 +0100 Subject: [PATCH 09/17] chore: bump dash --- package-lock.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package-lock.json b/package-lock.json index c7a1147c..db2e9908 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4861,7 +4861,7 @@ }, "node_modules/dashjs": { "version": "4.7.1", - "resolved": "git+ssh://git@github.com/bbc/dash.js.git#bff2359de9cbc96fe31378f48fff5e4418359f4c", + "resolved": "git+ssh://git@github.com/bbc/dash.js.git#3b7a484a629f64c18b127f5891f11c8f7287d063", "license": "BSD-3-Clause", "dependencies": { "bcp-47-match": "^1.0.3", From 9c3801d48fed28ed9468a5e4d3132d89e0d8a00a Mon Sep 17 00:00:00 2001 From: Luke-Chatburn Date: Tue, 22 Aug 2023 15:21:14 +0100 Subject: [PATCH 10/17] Added black list changes --- package-lock.json | 2 +- src/playbackstrategy/msestrategy.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package-lock.json b/package-lock.json index db2e9908..9d8ee95e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4861,7 +4861,7 @@ }, "node_modules/dashjs": { "version": "4.7.1", - "resolved": "git+ssh://git@github.com/bbc/dash.js.git#3b7a484a629f64c18b127f5891f11c8f7287d063", + "resolved": "git+ssh://git@github.com/bbc/dash.js.git#0ed032e0d14d5cbac720762c333236ced633caf8", "license": "BSD-3-Clause", "dependencies": { "bcp-47-match": "^1.0.3", diff --git a/src/playbackstrategy/msestrategy.js b/src/playbackstrategy/msestrategy.js index b22b511a..8a15aacc 100644 --- a/src/playbackstrategy/msestrategy.js +++ b/src/playbackstrategy/msestrategy.js @@ -48,6 +48,7 @@ function MSEStrategy(mediaSources, windowType, mediaKind, playbackElement, isUHD logLevel: 2, }, streaming: { + blacklistExpiryTime: mediaSources.failoverResetTime(), buffer: { bufferToKeep: 4, bufferTimeAtTopQuality: 12, @@ -210,7 +211,6 @@ function MSEStrategy(mediaSources, windowType, mediaKind, playbackElement, isUHD mediaPlayer.setMediaDuration(Number.MAX_SAFE_INTEGER) } - mediaPlayer.setBlacklistExpiryTime(mediaSources.failoverResetTime()) emitPlayerInfo() } From d4bd0d3a0db2a46b37328127996308d454cda86b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Eirik=20Jo=20Bj=C3=B6rnerstedt?= Date: Thu, 31 Aug 2023 16:13:27 +0100 Subject: [PATCH 11/17] chore: bump dash.js hash --- package-lock.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package-lock.json b/package-lock.json index 9d8ee95e..a02e6650 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4861,7 +4861,7 @@ }, "node_modules/dashjs": { "version": "4.7.1", - "resolved": "git+ssh://git@github.com/bbc/dash.js.git#0ed032e0d14d5cbac720762c333236ced633caf8", + "resolved": "git+ssh://git@github.com/bbc/dash.js.git#bda0ac892e349747f15d79600b796f3bbfbed843", "license": "BSD-3-Clause", "dependencies": { "bcp-47-match": "^1.0.3", From 4696d75a037a6cbcfa6a72d9d71446650ab0a904 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Eirik=20Jo=20Bj=C3=B6rnerstedt?= Date: Tue, 12 Sep 2023 10:58:28 +0100 Subject: [PATCH 12/17] fix: remove default live delay --- src/playbackstrategy/msestrategy.js | 44 +++++++++++------------- src/playbackstrategy/msestrategy.test.js | 22 +++++++++--- 2 files changed, 39 insertions(+), 27 deletions(-) diff --git a/src/playbackstrategy/msestrategy.js b/src/playbackstrategy/msestrategy.js index 8a15aacc..99fb6995 100644 --- a/src/playbackstrategy/msestrategy.js +++ b/src/playbackstrategy/msestrategy.js @@ -16,11 +16,29 @@ function MSEStrategy(mediaSources, windowType, mediaKind, playbackElement, isUHD let mediaPlayer let mediaElement + const playerSettings = Utils.merge( + { + debug: { + logLevel: 2, + }, + streaming: { + blacklistExpiryTime: mediaSources.failoverResetTime(), + buffer: { + bufferToKeep: 4, + bufferTimeAtTopQuality: 12, + bufferTimeAtTopQualityLongForm: 15, + }, + }, + }, + customPlayerSettings + ) + let eventCallbacks = [] let errorCallback let timeUpdateCallback let timeCorrection = mediaSources.time()?.timeCorrectionSeconds || 0 + const liveDelay = isNaN(playerSettings.streaming?.delay?.liveDelay) ? 0 : playerSettings.streaming?.delay?.liveDelay let failoverTime let failoverZeroPoint let refreshFailoverTime @@ -42,26 +60,6 @@ function MSEStrategy(mediaSources, windowType, mediaKind, playbackElement, isUHD }, } - const playerSettings = Utils.merge( - { - debug: { - logLevel: 2, - }, - streaming: { - blacklistExpiryTime: mediaSources.failoverResetTime(), - buffer: { - bufferToKeep: 4, - bufferTimeAtTopQuality: 12, - bufferTimeAtTopQualityLongForm: 15, - }, - delay: { - liveDelay: 1.1, - }, - }, - }, - customPlayerSettings - ) - const DashJSEvents = { LOG: "log", ERROR: "error", @@ -345,7 +343,7 @@ function MSEStrategy(mediaSources, windowType, mediaKind, playbackElement, isUHD } function getClampedTime(time, range) { - return Math.min(Math.max(time, range.start), range.end - playerSettings.streaming.delay.liveDelay) + return Math.min(Math.max(time, range.start), range.end - liveDelay) } function load(mimeType, playbackTime) { @@ -412,7 +410,7 @@ function MSEStrategy(mediaSources, windowType, mediaKind, playbackElement, isUHD if (dvrInfo) { return { start: dvrInfo.range.start - timeCorrection, - end: dvrInfo.range.end - timeCorrection - playerSettings.streaming.delay.liveDelay, + end: dvrInfo.range.end - timeCorrection - liveDelay, } } } @@ -449,7 +447,7 @@ function MSEStrategy(mediaSources, windowType, mediaKind, playbackElement, isUHD function calculateSeekOffset(time) { function getClampedTimeForLive(time) { - return Math.min(Math.max(time, 0), mediaPlayer.getDVRWindowSize() - playerSettings.streaming.delay.liveDelay) + return Math.min(Math.max(time, 0), mediaPlayer.getDVRWindowSize() - liveDelay) } if (windowType === WindowTypes.SLIDING) { diff --git a/src/playbackstrategy/msestrategy.test.js b/src/playbackstrategy/msestrategy.test.js index fbbcde1e..b1e6da85 100644 --- a/src/playbackstrategy/msestrategy.test.js +++ b/src/playbackstrategy/msestrategy.test.js @@ -762,8 +762,11 @@ describe("Media Source Extensions Playback Strategy", () => { expect(mockDashInstance.seek).toHaveBeenCalledWith(0) }) - it("should clamp the seek to 1.1s before the end of the seekable range", () => { - setUpMSE() + it("should clamp the seek to before the end of the seekable range", () => { + const liveDelay = 1.1 + + setUpMSE(undefined, undefined, undefined, undefined, undefined, { streaming: { delay: { liveDelay } } }) + mseStrategy.load(null, 0) mseStrategy.setCurrentTime(101) @@ -771,9 +774,19 @@ describe("Media Source Extensions Playback Strategy", () => { expect(mockDashInstance.seek).toHaveBeenCalledWith(99.9) }) + it("does not clamp the seek when live delay isn't set", () => { + setUpMSE() + + mseStrategy.load(null, 0) + + mseStrategy.setCurrentTime(101) + + expect(mockDashInstance.seek).toHaveBeenCalledWith(101) + }) + describe("sliding window", () => { beforeEach(() => { - setUpMSE(0, WindowTypes.SLIDING, MediaKinds.VIDEO, 100, 1000) + setUpMSE(0, WindowTypes.SLIDING, MediaKinds.VIDEO, 100, 1000, { streaming: { delay: { liveDelay: 1.1 } } }) mseStrategy.load(null, 0) mockDashInstance.play.mockReset() }) @@ -843,7 +856,8 @@ describe("Media Source Extensions Playback Strategy", () => { describe("growing window", () => { beforeEach(() => { - setUpMSE(0, WindowTypes.GROWING) + setUpMSE(0, WindowTypes.GROWING, undefined, undefined, undefined, { streaming: { delay: { liveDelay: 1.1 } } }) + mseStrategy.load(null, 0) mediaElement.currentTime = 50 mockDashInstance.refreshManifest.mockReset() From f33a53718a5f001f289b9a1f2a92d9d39e4cd79d Mon Sep 17 00:00:00 2001 From: Peter Morris-Hind Date: Tue, 19 Sep 2023 10:56:34 +0100 Subject: [PATCH 13/17] `onFragmentContentLengthMismatch` plugin (#309) --- docs/tutorials/Configuration.md | 8 ++++---- docs/tutorials/Plugins.md | 13 +++++++++++- src/playbackstrategy/msestrategy.js | 9 ++++++++ src/playbackstrategy/msestrategy.test.js | 26 ++++++++++++++++++++++++ src/plugins.js | 13 ++++++------ 5 files changed, 58 insertions(+), 11 deletions(-) diff --git a/docs/tutorials/Configuration.md b/docs/tutorials/Configuration.md index 5142d7fc..4dd459e6 100644 --- a/docs/tutorials/Configuration.md +++ b/docs/tutorials/Configuration.md @@ -17,18 +17,18 @@ window.bigscreenPlayer.playbackStrategy = 'msestrategy' // OR 'nativestrategy' O This library works across a multitude of different devices. But in order to do so, different configuration options are available to ensure the experience is good on those devices. -In order to add an override, simply add an `overiddes` object to the object above. +In order to add an override, simply add an `overiddes` object to the object above. | Name | Description | Values | | ------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------- | -| `disableSeekSentinel` | Does what it says on the tin, if we are about to fire a seekSentinel it will just return early if this flag is true. Roku device doesn't get timeupdates quick enough and fires a seek sentinel returning to beginning of playback | boolean | +| `disableSeekSentinel` | Does what it says on the tin, if we are about to fire a seekSentinel it will just return early if this flag is true. Some devices don't get timeupdates quickly enough and fire a seek sentinel, returning to beginning of playback | boolean | | `showLiveCurtain` | This is a black html div element placed on top of the video, this is used to hide seeking issues such as the `forceBeginPlaybackToEndOfWindow` | boolean | | `forceBeginPlaybackToEndOfWindow` | This is a an override that happens in the restartable/seekable players, whenever we start a stream without a start time and this override is true it will give the player a start time of infinity to force it to the end of the window. It is also used in conjunction with the showLiveCurtain for seeking as some devices will play from the wrong point for a few frames before jumping to the correct time. | boolean | | `pauseOnExitSeek` | This is a workaround for devices which will error if you try to pause straight after seeking. This is a business decision that if you are paused before you seek you should remain paused on exiting seek. This is done by waiting for a time update event to make sure we are playing after the seek before we attempt to pause the player. | boolean | -| `deferedPlayback` | Currently a workaround for an issue on a Sony 2012 device. The device will call play before seek on a deferedPlayFrom instead of calls to seek then play. | boolean | +| `deferedPlayback` | Currently a workaround for devices that will call play before seek on a deferedPlayFrom, instead of calling seek then play. | boolean | | `mseDurationOverride` | dash.js v3.0 update caused issues for certain devices when playing from the live point. This will force set the duration when playing live content and stop any issues. | boolean | | `restartTimeout` | This is used after a seek attempted to ensure that a seek has happened correctly. | number | | `disableMediaSourceUnload` | When tearing down in HTML5 we unload the source as part of the html5 spec. This prevents this from happening as it was causing issues on devices. | boolean | | `legacySubtitles` | This can be used to render subtitles using our legacy method, rather than the new method which utilises the third party imscJS library. | boolean | | `liveUhdDisableSentinels` | Disables any sentinels when consuming live UHD content | boolean | -| `cacheSeekableRange` | Caches the seekable range so it can't be requested more than every 250ms for devices that struggle. | boolean | \ No newline at end of file +| `cacheSeekableRange` | Caches the seekable range so it can't be requested more than every 250ms for devices that struggle. | boolean | diff --git a/docs/tutorials/Plugins.md b/docs/tutorials/Plugins.md index 073574c6..c2476ad5 100644 --- a/docs/tutorials/Plugins.md +++ b/docs/tutorials/Plugins.md @@ -8,6 +8,17 @@ The full interface is as follows: - `onBuffering` - `onBufferingCleared` - `onScreenCapabilityDetermined` +- `onPlayerInfoUpdated` +- `onManifestLoaded` +- `onManifestParseError` +- `onQualityChangedRendered` +- `onSubtitlesLoadError` +- `onSubtitlesTimeout` +- `onSubtitlesXMLError` +- `onSubtitlesTransformError` +- `onSubtitlesRenderError` +- `onSubtitlesDynamicLoadError` +- `onFragmentContentLengthMismatch` An example plugin may look like: @@ -45,4 +56,4 @@ bigscreenPlayer.registerPlugin(examplePlugin); // calling with no argument will unregister all plugins bigscreenPlayer.unregisterPlugin(examplePlugin); -``` \ No newline at end of file +``` diff --git a/src/playbackstrategy/msestrategy.js b/src/playbackstrategy/msestrategy.js index 99fb6995..e6e7ec1a 100644 --- a/src/playbackstrategy/msestrategy.js +++ b/src/playbackstrategy/msestrategy.js @@ -76,6 +76,7 @@ function MSEStrategy(mediaSources, windowType, mediaKind, playbackElement, isUHD METRIC_ADDED: "metricAdded", METRIC_CHANGED: "metricChanged", STREAM_INITIALIZED: "streamInitialized", + FRAGMENT_CONTENT_LENGTH_MISMATCH: "fragmentContentLengthMismatch", } function onPlaying() { @@ -320,6 +321,13 @@ function MSEStrategy(mediaSources, windowType, mediaKind, playbackElement, isUHD DebugTool.verbose(event.message) } + function onFragmentContentLengthMismatch(event) { + DebugTool.info(`Fragment Content Length Mismatch: ${event.responseUrl} (${event.mediaType})`) + DebugTool.info(`Header Length ${event.headerLength}`) + DebugTool.info(`Body Length ${event.bodyLength})`) + Plugins.interface.onFragmentContentLengthMismatch(event) + } + function publishMediaState(mediaState) { for (let index = 0; index < eventCallbacks.length; index++) { eventCallbacks[index](mediaState) @@ -402,6 +410,7 @@ function MSEStrategy(mediaSources, windowType, mediaKind, playbackElement, isUHD mediaPlayer.on(DashJSEvents.LOG, onDebugLog) mediaPlayer.on(DashJSEvents.SERVICE_LOCATION_AVAILABLE, onServiceLocationAvailable) mediaPlayer.on(DashJSEvents.URL_RESOLUTION_FAILED, onURLResolutionFailed) + mediaPlayer.on(DashJSEvents.FRAGMENT_CONTENT_LENGTH_MISMATCH, onFragmentContentLengthMismatch) } function getSeekableRange() { diff --git a/src/playbackstrategy/msestrategy.test.js b/src/playbackstrategy/msestrategy.test.js index b1e6da85..c64d974f 100644 --- a/src/playbackstrategy/msestrategy.test.js +++ b/src/playbackstrategy/msestrategy.test.js @@ -52,6 +52,7 @@ describe("Media Source Extensions Playback Strategy", () => { BASE_URL_SELECTED: "baseUrlSelected", METRIC_ADDED: "metricAdded", METRIC_CHANGED: "metricChanged", + FRAGMENT_CONTENT_LENGTH_MISMATCH: "fragmentContentLengthMismatch", } let mseStrategy @@ -1321,4 +1322,29 @@ describe("Media Source Extensions Playback Strategy", () => { expect(eventCallbackSpy).toHaveBeenCalledTimes(2) }) }) + + describe("plugins", () => { + it("fires onFragmentContentLengthMismatch when dash.js fires FRAGMENT_CONTENT_LENGTH_MISMATCH", () => { + const mockFragmentContentLengthMismatchEvent = { + responseUrl: "example.com", + mediaType: "video/mp4", + headerLength: 12, + bodyLength: 13, + } + + jest.spyOn(Plugins.interface, "onFragmentContentLengthMismatch") + + setUpMSE() + mseStrategy.load(null, 0) + + dashEventCallback( + dashjsMediaPlayerEvents.FRAGMENT_CONTENT_LENGTH_MISMATCH, + mockFragmentContentLengthMismatchEvent + ) + + expect(Plugins.interface.onFragmentContentLengthMismatch).toHaveBeenCalledWith( + mockFragmentContentLengthMismatchEvent + ) + }) + }) }) diff --git a/src/plugins.js b/src/plugins.js index e63dfa4f..80a8fcc1 100644 --- a/src/plugins.js +++ b/src/plugins.js @@ -5,9 +5,9 @@ let plugins = [] function callOnAllPlugins(funcKey, evt) { const clonedEvent = PlaybackUtils.deepClone(evt) - for (const i in plugins) { - if (plugins[i][funcKey]) { - plugins[i][funcKey](clonedEvent) + for (const plugin in plugins) { + if (plugins[plugin][funcKey]) { + plugins[plugin][funcKey](clonedEvent) } } } @@ -21,9 +21,9 @@ export default { if (!plugin && plugins.length > 0) { plugins = [] } else { - for (let i = plugins.length - 1; i >= 0; i--) { - if (plugins[i] === plugin) { - plugins.splice(i, 1) + for (let pluginsIndex = plugins.length - 1; pluginsIndex >= 0; pluginsIndex--) { + if (plugins[pluginsIndex] === plugin) { + plugins.splice(pluginsIndex, 1) } } } @@ -47,5 +47,6 @@ export default { onSubtitlesTransformError: (evt) => callOnAllPlugins("onSubtitlesTransformError", evt), onSubtitlesRenderError: (evt) => callOnAllPlugins("onSubtitlesRenderError", evt), onSubtitlesDynamicLoadError: (evt) => callOnAllPlugins("onSubtitlesDynamicLoadError", evt), + onFragmentContentLengthMismatch: (evt) => callOnAllPlugins("onFragmentContentLengthMismatch", evt), }, } From d73066dfb001e16bf877c3814b498f72c230c46d Mon Sep 17 00:00:00 2001 From: Peter Clay Holden Morris-Hind Date: Thu, 5 Oct 2023 11:21:00 +0100 Subject: [PATCH 14/17] Update to latest version of smp-v4 --- package-lock.json | 56 +++++++++++++++++++++++------------------------ 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/package-lock.json b/package-lock.json index a02e6650..a344fc7d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4400,13 +4400,13 @@ "dev": true }, "node_modules/bcp-47": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/bcp-47/-/bcp-47-1.0.8.tgz", - "integrity": "sha512-Y9y1QNBBtYtv7hcmoX0tR+tUNSFZGZ6OL6vKPObq8BbOhkCoyayF6ogfLTgAli/KuAEbsYHYUNq2AQuY6IuLag==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/bcp-47/-/bcp-47-2.1.0.tgz", + "integrity": "sha512-9IIS3UPrvIa1Ej+lVDdDwO7zLehjqsaByECw0bu2RRGP73jALm6FYbzI5gWbgHLvNdkvfXB5YrSbocZdOS0c0w==", "dependencies": { - "is-alphabetical": "^1.0.0", - "is-alphanumerical": "^1.0.0", - "is-decimal": "^1.0.0" + "is-alphabetical": "^2.0.0", + "is-alphanumerical": "^2.0.0", + "is-decimal": "^2.0.0" }, "funding": { "type": "github", @@ -4414,21 +4414,21 @@ } }, "node_modules/bcp-47-match": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/bcp-47-match/-/bcp-47-match-1.0.3.tgz", - "integrity": "sha512-LggQ4YTdjWQSKELZF5JwchnBa1u0pIQSZf5lSdOHEdbVP55h0qICA/FUp3+W99q0xqxYa1ZQizTUH87gecII5w==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/bcp-47-match/-/bcp-47-match-2.0.3.tgz", + "integrity": "sha512-JtTezzbAibu8G0R9op9zb3vcWZd9JF6M0xOYGPn0fNCd7wOpRB1mU2mH9T8gaBGbAAyIIVgB2G7xG0GP98zMAQ==", "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" } }, "node_modules/bcp-47-normalize": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/bcp-47-normalize/-/bcp-47-normalize-1.1.1.tgz", - "integrity": "sha512-jWZ1Jdu3cs0EZdfCkS0UE9Gg01PtxnChjEBySeB+Zo6nkqtFfnvtoQQgP1qU1Oo4qgJgxhTI6Sf9y/pZIhPs0A==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/bcp-47-normalize/-/bcp-47-normalize-2.3.0.tgz", + "integrity": "sha512-8I/wfzqQvttUFz7HVJgIZ7+dj3vUaIyIxYXaTRP1YWoSDfzt6TUmxaKZeuXR62qBmYr+nvuWINFRl6pZ5DlN4Q==", "dependencies": { - "bcp-47": "^1.0.0", - "bcp-47-match": "^1.0.0" + "bcp-47": "^2.0.0", + "bcp-47-match": "^2.0.0" }, "funding": { "type": "github", @@ -4861,11 +4861,11 @@ }, "node_modules/dashjs": { "version": "4.7.1", - "resolved": "git+ssh://git@github.com/bbc/dash.js.git#bda0ac892e349747f15d79600b796f3bbfbed843", + "resolved": "git+ssh://git@github.com/bbc/dash.js.git#5537d301c8c461f4560c4166f8478c8ce8ff5929", "license": "BSD-3-Clause", "dependencies": { - "bcp-47-match": "^1.0.3", - "bcp-47-normalize": "^1.1.1", + "bcp-47-match": "^2.0.3", + "bcp-47-normalize": "^2.3.0", "codem-isoboxer": "0.3.9", "es6-promise": "^4.2.8", "fast-deep-equal": "2.0.1", @@ -6662,21 +6662,21 @@ } }, "node_modules/is-alphabetical": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-1.0.4.tgz", - "integrity": "sha512-DwzsA04LQ10FHTZuL0/grVDk4rFoVH1pjAToYwBrHSxcrBIGQuXrQMtD5U1b0U2XVgKZCTLLP8u2Qxqhy3l2Vg==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-2.0.1.tgz", + "integrity": "sha512-FWyyY60MeTNyeSRpkM2Iry0G9hpr7/9kD40mD/cGQEuilcZYS4okz8SN2Q6rLCJ8gbCt6fN+rC+6tMGS99LaxQ==", "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" } }, "node_modules/is-alphanumerical": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-1.0.4.tgz", - "integrity": "sha512-UzoZUr+XfVz3t3v4KyGEniVL9BDRoQtY7tOyrRybkVNjDFWyo1yhXNGrrBTQxp3ib9BLAWs7k2YKBQsFRkZG9A==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-2.0.1.tgz", + "integrity": "sha512-hmbYhX/9MUMF5uh7tOXyK/n0ZvWpad5caBA17GsC6vyuCqaWliRG5K1qS9inmUhEMaOBIW7/whAnSwveW/LtZw==", "dependencies": { - "is-alphabetical": "^1.0.0", - "is-decimal": "^1.0.0" + "is-alphabetical": "^2.0.0", + "is-decimal": "^2.0.0" }, "funding": { "type": "github", @@ -6784,9 +6784,9 @@ } }, "node_modules/is-decimal": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-decimal/-/is-decimal-1.0.4.tgz", - "integrity": "sha512-RGdriMmQQvZ2aqaQq3awNA6dCGtKpiDFcOzrTWrDAT2MiWrKQVPmxLGHl7Y2nNu6led0kEyoX0enY0qXYsv9zw==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-decimal/-/is-decimal-2.0.1.tgz", + "integrity": "sha512-AAB9hiomQs5DXWcRB1rqsxGUstbRroFOPPVAomNk/3XHR5JyEZChOyTWe2oayKnsSsr/kcGqF+z6yuH6HHpN0A==", "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" From 8de710f8c5ad6ce1b893427fe881a5f98b038ca2 Mon Sep 17 00:00:00 2001 From: James Bungay <113347443+jamesbungay-bbc@users.noreply.github.com> Date: Mon, 16 Oct 2023 12:02:02 +0100 Subject: [PATCH 15/17] fix(mse-dash): prevent seek to end (#310) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * test: clamp seek by end padding * fix: clamp seek by end padding * test: use seek padding config * style: rename to seekDurationPadding * feat: make seek duration padding configurable * docs: explain seekDurationPadding * docs: clarify settings path * docs: add other settings * docs: update player settings structure * docs: introduce global settings object * docs: clarify terms * style: rename --------- Co-authored-by: Eirik Jo Björnerstedt --- docs/tutorials/00-getting-started.md | 15 ++++-- ...trategies.md => 01-playback-strategies.md} | 0 ...ration.md => 02-settings-and-overrides.md} | 52 +++++++++++++------ .../{CDN Failover.md => cdn-failover.md} | 0 docs/tutorials/tutorials.json | 12 +++-- src/playbackstrategy/msestrategy.js | 17 ++++-- src/playbackstrategy/msestrategy.test.js | 33 ++++++++++-- 7 files changed, 101 insertions(+), 28 deletions(-) rename docs/tutorials/{playback-strategies.md => 01-playback-strategies.md} (100%) rename docs/tutorials/{Configuration.md => 02-settings-and-overrides.md} (64%) rename docs/tutorials/{CDN Failover.md => cdn-failover.md} (100%) diff --git a/docs/tutorials/00-getting-started.md b/docs/tutorials/00-getting-started.md index 1244c0fd..4fbf9c38 100644 --- a/docs/tutorials/00-getting-started.md +++ b/docs/tutorials/00-getting-started.md @@ -16,13 +16,19 @@ To start a playback session you must minimally provide: ### Configuration +Configuration for bigscreen-player can be set using an object on the window: + +```javascript +window.bigscreenPlayer +``` + You must provide a *playback strategy* to use BigscreenPlayer: ```javascript window.bigscreenPlayer.playbackStrategy = 'msestrategy' // OR 'nativestrategy' OR 'basicstrategy' ``` -The MSEStrategy uses DASH. It is most likely what you want. More detail in the [documentation on playback strategies](). +The MSEStrategy uses DASH. It is most likely what you want. More detail in the [documentation on playback strategies](). You should also have a peek at the [documentation on settings and overrides](https://bbc.github.io/bigscreen-player/api/tutorial-02-settings-and-overrides.html) ### Minimal Data @@ -104,11 +110,12 @@ const optionalData = { fontFamily: 'Arial', backgroundColour: 'black' // (css colour, hex) }, - playerSettings: { // This currently can be used to customise settings for the msestrategy. It is a pass through of all the dash.js player settings. - failoverSort: failoverSort, // Post failover custom sorting algorithm + playerSettings: { // See settings documentation for more details failoverResetTime: 60000, streaming: { - bufferToKeep: 8 + buffer: { + bufferToKeep: 8 + } } } } diff --git a/docs/tutorials/playback-strategies.md b/docs/tutorials/01-playback-strategies.md similarity index 100% rename from docs/tutorials/playback-strategies.md rename to docs/tutorials/01-playback-strategies.md diff --git a/docs/tutorials/Configuration.md b/docs/tutorials/02-settings-and-overrides.md similarity index 64% rename from docs/tutorials/Configuration.md rename to docs/tutorials/02-settings-and-overrides.md index 4dd459e6..f12f55ed 100644 --- a/docs/tutorials/Configuration.md +++ b/docs/tutorials/02-settings-and-overrides.md @@ -1,23 +1,10 @@ -# Configuration - -Configuration for bigscreen-player can be set using an object on the window: -``` -window.bigscreenPlayer -``` - -## Playback Strategy - -As mentioned in the "Getting Started" guide, bigscreen-player requires a `playbackStrategy` to be set: - -```javascript -window.bigscreenPlayer.playbackStrategy = 'msestrategy' // OR 'nativestrategy' OR 'hybridstrategy' OR 'basicstrategy' -``` +BigscreenPlayer can be configured past playback strategy and live support. You can also provide [player settings](#player-settings) and [playback overrides](#overrides). ## Overrides This library works across a multitude of different devices. But in order to do so, different configuration options are available to ensure the experience is good on those devices. -In order to add an override, simply add an `overiddes` object to the object above. +In order to add an override, simply add an override object to the `window.bigscreenPlayer.overrides` object. | Name | Description | Values | | ------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------- | @@ -32,3 +19,38 @@ In order to add an override, simply add an `overiddes` object to the object abov | `legacySubtitles` | This can be used to render subtitles using our legacy method, rather than the new method which utilises the third party imscJS library. | boolean | | `liveUhdDisableSentinels` | Disables any sentinels when consuming live UHD content | boolean | | `cacheSeekableRange` | Caches the seekable range so it can't be requested more than every 250ms for devices that struggle. | boolean | + +## Player Settings + +Player settings are provided to BigscreenPlayer during initialisation through the `.init()` function. They extend the player settings provided by Dash.js: (). + +In the case where a setting is called out as alleviating a known device issue, we picked the default value to do so across all devices we test. + +### `failoverResetTime` + +Specify the time (in milliseconds) til a media source is added back to the list of available media sources after it has been failed over. What is a failover? See [the failover documentation](https://bbc.github.io/bigscreen-player/api/tutorial-cdn-failover.html) + +```ts +type failoverResetTime = number is FiniteNumber +``` + +### `failoverSort` + +Provide a sorting algorithm to reorder the available media sources after a failover. + +```ts +type failoverSort = (...sources: [...string]) => [...string] +``` + +### `streaming.seekDurationPadding` + +Add a padding to prevent seeking too close to the duration of the media. + +```ts +type seekDurationPadding = number is FiniteNumber +``` + +Fixes: + +- Media element seeking back to start when end of stream is signalled during a seek to duration. +- Media element failing to complete a seek to a time close to the duration when end of stream is signalled during the seek because of media tracks with unequal length. The padding prevents seeking into the time range up to the duration where only some tracks have data. diff --git a/docs/tutorials/CDN Failover.md b/docs/tutorials/cdn-failover.md similarity index 100% rename from docs/tutorials/CDN Failover.md rename to docs/tutorials/cdn-failover.md diff --git a/docs/tutorials/tutorials.json b/docs/tutorials/tutorials.json index ff852340..e1a7eae7 100644 --- a/docs/tutorials/tutorials.json +++ b/docs/tutorials/tutorials.json @@ -2,10 +2,16 @@ "00-getting-started": { "title": "Getting Started" }, + "01-playback-strategies": { + "title": "Playback Strategies" + }, + "02-settings-and-overrides": { + "title": "Settings And Overrides" + }, + "cdn-failover": { + "title": "CDN Failover" + }, "live-streaming": { "title": "Live" - }, - "playback-strategies": { - "title": "Playback Strategies" } } \ No newline at end of file diff --git a/src/playbackstrategy/msestrategy.js b/src/playbackstrategy/msestrategy.js index e6e7ec1a..81939a2d 100644 --- a/src/playbackstrategy/msestrategy.js +++ b/src/playbackstrategy/msestrategy.js @@ -12,6 +12,11 @@ import DOMHelpers from "../domhelpers" import Utils from "../utils/playbackutils" import buildSourceAnchor, { TimelineZeroPoints } from "../utils/mse/build-source-anchor" +const DEFAULT_SETTINGS = { + liveDelay: 0, + seekDurationPadding: 1.1, +} + function MSEStrategy(mediaSources, windowType, mediaKind, playbackElement, isUHD, customPlayerSettings) { let mediaPlayer let mediaElement @@ -38,7 +43,13 @@ function MSEStrategy(mediaSources, windowType, mediaKind, playbackElement, isUHD let timeUpdateCallback let timeCorrection = mediaSources.time()?.timeCorrectionSeconds || 0 - const liveDelay = isNaN(playerSettings.streaming?.delay?.liveDelay) ? 0 : playerSettings.streaming?.delay?.liveDelay + + const seekDurationPadding = isNaN(playerSettings.streaming?.seekDurationPadding) + ? DEFAULT_SETTINGS.seekDurationPadding + : playerSettings.streaming?.seekDurationPadding + const liveDelay = isNaN(playerSettings.streaming?.delay?.liveDelay) + ? DEFAULT_SETTINGS.liveDelay + : playerSettings.streaming?.delay?.liveDelay let failoverTime let failoverZeroPoint let refreshFailoverTime @@ -351,7 +362,7 @@ function MSEStrategy(mediaSources, windowType, mediaKind, playbackElement, isUHD } function getClampedTime(time, range) { - return Math.min(Math.max(time, range.start), range.end - liveDelay) + return Math.min(Math.max(time, range.start), range.end - Math.max(liveDelay, seekDurationPadding)) } function load(mimeType, playbackTime) { @@ -456,7 +467,7 @@ function MSEStrategy(mediaSources, windowType, mediaKind, playbackElement, isUHD function calculateSeekOffset(time) { function getClampedTimeForLive(time) { - return Math.min(Math.max(time, 0), mediaPlayer.getDVRWindowSize() - liveDelay) + return Math.min(Math.max(time, 0), mediaPlayer.getDVRWindowSize() - Math.max(liveDelay, seekDurationPadding)) } if (windowType === WindowTypes.SLIDING) { diff --git a/src/playbackstrategy/msestrategy.test.js b/src/playbackstrategy/msestrategy.test.js index c64d974f..87374ae4 100644 --- a/src/playbackstrategy/msestrategy.test.js +++ b/src/playbackstrategy/msestrategy.test.js @@ -763,7 +763,19 @@ describe("Media Source Extensions Playback Strategy", () => { expect(mockDashInstance.seek).toHaveBeenCalledWith(0) }) - it("should clamp the seek to before the end of the seekable range", () => { + it("clamps a seek to the end of the seekable range by seek duration padding", () => { + const seekDurationPadding = 0.1 + + setUpMSE(undefined, undefined, undefined, undefined, undefined, { streaming: { seekDurationPadding } }) + + mseStrategy.load(null, 0) + + mseStrategy.setCurrentTime(101) + + expect(mockDashInstance.seek).toHaveBeenCalledWith(100.9) + }) + + it("clamps a seek to the end of the seekable range by live delay", () => { const liveDelay = 1.1 setUpMSE(undefined, undefined, undefined, undefined, undefined, { streaming: { delay: { liveDelay } } }) @@ -775,14 +787,29 @@ describe("Media Source Extensions Playback Strategy", () => { expect(mockDashInstance.seek).toHaveBeenCalledWith(99.9) }) - it("does not clamp the seek when live delay isn't set", () => { + it("clamps a seek to end by the greatest value of seek duration padding and live delay", () => { + const seekDurationPadding = 0.1 + const liveDelay = seekDurationPadding - 0.01 + + setUpMSE(undefined, undefined, undefined, undefined, undefined, { + streaming: { seekDurationPadding, delay: { liveDelay } }, + }) + + mseStrategy.load(null, 0) + + mseStrategy.setCurrentTime(101) + + expect(mockDashInstance.seek).toHaveBeenCalledWith(100.9) + }) + + it("clamps a seek to end using the default seek duration padding when not passed in", () => { setUpMSE() mseStrategy.load(null, 0) mseStrategy.setCurrentTime(101) - expect(mockDashInstance.seek).toHaveBeenCalledWith(101) + expect(mockDashInstance.seek).toHaveBeenCalledWith(99.9) }) describe("sliding window", () => { From a183f381276d16cff0677adef71fcf26bd0353b0 Mon Sep 17 00:00:00 2001 From: Joel Keers Date: Thu, 9 Nov 2023 12:37:32 +0000 Subject: [PATCH 16/17] use dashjs smp-v4.7.1-0 release --- package-lock.json | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package-lock.json b/package-lock.json index bfc09297..b9416d1c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,7 +10,7 @@ "hasInstallScript": true, "license": "Apache-2.0", "dependencies": { - "dashjs": "github:bbc/dash.js#smp-v4.7", + "dashjs": "github:bbc/dash.js#smp-v4.7.1-0", "smp-imsc": "github:bbc/imscJS#v1.0.3" }, "devDependencies": { diff --git a/package.json b/package.json index 10d0e323..ab776538 100644 --- a/package.json +++ b/package.json @@ -54,7 +54,7 @@ "rollup-plugin-visualizer": "^5.5.2" }, "dependencies": { - "dashjs": "github:bbc/dash.js#smp-v4.7", + "dashjs": "github:bbc/dash.js#smp-v4.7.1-0", "smp-imsc": "github:bbc/imscJS#v1.0.3" }, "repository": { From e278f784cedd46ae0efe3a60330a83eef74de93c Mon Sep 17 00:00:00 2001 From: Joel Keers Date: Thu, 9 Nov 2023 12:42:03 +0000 Subject: [PATCH 17/17] fix lint errors blocking the PR --- src/playbackstrategy/msestrategy.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/playbackstrategy/msestrategy.js b/src/playbackstrategy/msestrategy.js index 81939a2d..6a9ad251 100644 --- a/src/playbackstrategy/msestrategy.js +++ b/src/playbackstrategy/msestrategy.js @@ -366,13 +366,13 @@ function MSEStrategy(mediaSources, windowType, mediaKind, playbackElement, isUHD } function load(mimeType, playbackTime) { - if (!mediaPlayer) { + if (mediaPlayer) { + modifySource(refreshFailoverTime || failoverTime, failoverZeroPoint) + } else { failoverTime = playbackTime setUpMediaElement(playbackElement) setUpMediaPlayer(playbackTime) setUpMediaListeners() - } else { - modifySource(refreshFailoverTime || failoverTime, failoverZeroPoint) } } @@ -454,13 +454,13 @@ function MSEStrategy(mediaSources, windowType, mediaKind, playbackElement, isUHD mediaPlayer.refreshManifest((manifest) => { const mediaPresentationDuration = manifest && manifest.mediaPresentationDuration - if (!isNaN(mediaPresentationDuration)) { + if (isNaN(mediaPresentationDuration)) { + mediaPlayer.seek(seekToTime) + } else { DebugTool.info("Stream ended. Clamping seek point to end of stream") mediaPlayer.seek( getClampedTime(seekToTime, { start: getSeekableRange().start, end: mediaPresentationDuration }) ) - } else { - mediaPlayer.seek(seekToTime) } }) }