diff --git a/package-lock.json b/package-lock.json index 6ba1d652a4..cd104e0f34 100644 --- a/package-lock.json +++ b/package-lock.json @@ -45,6 +45,7 @@ "jquery": "3.7.1", "jstree": "3.3.16", "libarchive.js": "2.0.2", + "libpgs": "0.2.0", "lodash-es": "4.17.21", "markdown-it": "14.1.0", "material-design-icons-iconfont": "6.7.0", @@ -138,6 +139,22 @@ "sass-embedded": "1.77.8" } }, + "../libpgs-js": { + "name": "libpgs", + "version": "0.2.0", + "license": "MIT", + "devDependencies": { + "@tsconfig/recommended": "^1.0.6", + "@types/jest": "^29.5.12", + "jest": "^29.7.0", + "ts-jest": "^29.1.4", + "ts-loader": "^9.5.1", + "ts-node": "^10.9.2", + "typescript": "^5.4.5", + "webpack": "^5.91.0", + "webpack-cli": "^5.1.4" + } + }, "node_modules/@aashutoshrathi/word-wrap": { "version": "1.2.6", "resolved": "https://registry.npmjs.org/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz", @@ -14971,6 +14988,10 @@ "comlink": "^4.4.1" } }, + "node_modules/libpgs": { + "resolved": "../libpgs-js", + "link": true + }, "node_modules/lie": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/lie/-/lie-3.1.1.tgz", @@ -36529,6 +36550,20 @@ "comlink": "^4.4.1" } }, + "libpgs": { + "version": "file:../libpgs-js", + "requires": { + "@tsconfig/recommended": "^1.0.6", + "@types/jest": "^29.5.12", + "jest": "^29.7.0", + "ts-jest": "^29.1.4", + "ts-loader": "^9.5.1", + "ts-node": "^10.9.2", + "typescript": "^5.4.5", + "webpack": "^5.91.0", + "webpack-cli": "^5.1.4" + } + }, "lie": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/lie/-/lie-3.1.1.tgz", diff --git a/package.json b/package.json index d98a9e98d8..15fb8288a8 100644 --- a/package.json +++ b/package.json @@ -123,7 +123,8 @@ "swiper": "11.1.12", "usehooks-ts": "3.1.0", "webcomponents.js": "0.7.24", - "whatwg-fetch": "3.6.20" + "whatwg-fetch": "3.6.20", + "libpgs": "0.2.0" }, "optionalDependencies": { "sass-embedded": "1.77.8" diff --git a/src/plugins/htmlVideoPlayer/plugin.js b/src/plugins/htmlVideoPlayer/plugin.js index 83e247eb83..3aa7873702 100644 --- a/src/plugins/htmlVideoPlayer/plugin.js +++ b/src/plugins/htmlVideoPlayer/plugin.js @@ -100,7 +100,7 @@ function enableNativeTrackSupport(mediaSource, track) { if (track) { const format = (track.Codec || '').toLowerCase(); - if (format === 'ssa' || format === 'ass') { + if (format === 'ssa' || format === 'ass' || format === 'pgssub') { return false; } } @@ -213,6 +213,10 @@ export class HtmlVideoPlayer { * @type {any | null | undefined} */ #currentAssRenderer; + /** + * @type {any | null | undefined} + */ + #currentPgsRenderer; /** * @type {number | undefined} */ @@ -1172,6 +1176,12 @@ export class HtmlVideoPlayer { octopus.dispose(); } this.#currentAssRenderer = null; + + const pgsRenderer = this.#currentPgsRenderer; + if (pgsRenderer) { + pgsRenderer.dispose(); + } + this.#currentPgsRenderer = null; } /** @@ -1316,6 +1326,19 @@ export class HtmlVideoPlayer { }); } + /** + * @private + */ + renderPgs(videoElement, track, item) { + import('libpgs').then((libpgs) => { + const options = { + video: videoElement, + subUrl: getTextTrackUrl(track, item) + }; + this.#currentPgsRenderer = new libpgs.PgsRenderer(options); + }); + } + /** * @private */ @@ -1434,6 +1457,10 @@ export class HtmlVideoPlayer { this.renderSsaAss(videoElement, track, item); return; } + if (format === 'pgssub') { + this.renderPgs(videoElement, track, item); + return; + } if (this.requiresCustomSubtitlesElement()) { this.renderSubtitlesWithCustomElement(videoElement, track, item, targetTextTrackIndex); diff --git a/src/scripts/browserDeviceProfile.js b/src/scripts/browserDeviceProfile.js index 34fad3c237..505f8276ac 100644 --- a/src/scripts/browserDeviceProfile.js +++ b/src/scripts/browserDeviceProfile.js @@ -48,6 +48,15 @@ function supportsTextTracks() { return _supportsTextTracks; } +let _supportsCanvas2D; +function supportsCanvas2D() { + if (_supportsCanvas2D == null) { + _supportsCanvas2D = document.createElement('canvas').getContext('2d') != null; + } + + return _supportsCanvas2D; +} + let _canPlayHls; function canPlayHls() { if (_canPlayHls == null) { @@ -1432,6 +1441,13 @@ export default function (options) { Method: 'External' }); } + + if (supportsCanvas2D()) { + profile.SubtitleProfiles.push({ + Format: 'pgssub', + Method: 'External' + }); + } } profile.ResponseProfiles = [];