mirror of
https://github.com/jellyfin/jellyfin-web
synced 2025-03-30 19:56:21 +00:00
Added native PGS (graphical subtitle) rendering for external streams.
This commit is contained in:
parent
9184f06d79
commit
e9aedc3305
4 changed files with 81 additions and 2 deletions
35
package-lock.json
generated
35
package-lock.json
generated
|
@ -45,6 +45,7 @@
|
||||||
"jquery": "3.7.1",
|
"jquery": "3.7.1",
|
||||||
"jstree": "3.3.16",
|
"jstree": "3.3.16",
|
||||||
"libarchive.js": "2.0.2",
|
"libarchive.js": "2.0.2",
|
||||||
|
"libpgs": "0.2.0",
|
||||||
"lodash-es": "4.17.21",
|
"lodash-es": "4.17.21",
|
||||||
"markdown-it": "14.1.0",
|
"markdown-it": "14.1.0",
|
||||||
"material-design-icons-iconfont": "6.7.0",
|
"material-design-icons-iconfont": "6.7.0",
|
||||||
|
@ -138,6 +139,22 @@
|
||||||
"sass-embedded": "1.77.8"
|
"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": {
|
"node_modules/@aashutoshrathi/word-wrap": {
|
||||||
"version": "1.2.6",
|
"version": "1.2.6",
|
||||||
"resolved": "https://registry.npmjs.org/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz",
|
"resolved": "https://registry.npmjs.org/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz",
|
||||||
|
@ -14971,6 +14988,10 @@
|
||||||
"comlink": "^4.4.1"
|
"comlink": "^4.4.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/libpgs": {
|
||||||
|
"resolved": "../libpgs-js",
|
||||||
|
"link": true
|
||||||
|
},
|
||||||
"node_modules/lie": {
|
"node_modules/lie": {
|
||||||
"version": "3.1.1",
|
"version": "3.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/lie/-/lie-3.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/lie/-/lie-3.1.1.tgz",
|
||||||
|
@ -36529,6 +36550,20 @@
|
||||||
"comlink": "^4.4.1"
|
"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": {
|
"lie": {
|
||||||
"version": "3.1.1",
|
"version": "3.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/lie/-/lie-3.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/lie/-/lie-3.1.1.tgz",
|
||||||
|
|
|
@ -123,7 +123,8 @@
|
||||||
"swiper": "11.1.12",
|
"swiper": "11.1.12",
|
||||||
"usehooks-ts": "3.1.0",
|
"usehooks-ts": "3.1.0",
|
||||||
"webcomponents.js": "0.7.24",
|
"webcomponents.js": "0.7.24",
|
||||||
"whatwg-fetch": "3.6.20"
|
"whatwg-fetch": "3.6.20",
|
||||||
|
"libpgs": "0.2.0"
|
||||||
},
|
},
|
||||||
"optionalDependencies": {
|
"optionalDependencies": {
|
||||||
"sass-embedded": "1.77.8"
|
"sass-embedded": "1.77.8"
|
||||||
|
|
|
@ -100,7 +100,7 @@ function enableNativeTrackSupport(mediaSource, track) {
|
||||||
|
|
||||||
if (track) {
|
if (track) {
|
||||||
const format = (track.Codec || '').toLowerCase();
|
const format = (track.Codec || '').toLowerCase();
|
||||||
if (format === 'ssa' || format === 'ass') {
|
if (format === 'ssa' || format === 'ass' || format === 'pgssub') {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -213,6 +213,10 @@ export class HtmlVideoPlayer {
|
||||||
* @type {any | null | undefined}
|
* @type {any | null | undefined}
|
||||||
*/
|
*/
|
||||||
#currentAssRenderer;
|
#currentAssRenderer;
|
||||||
|
/**
|
||||||
|
* @type {any | null | undefined}
|
||||||
|
*/
|
||||||
|
#currentPgsRenderer;
|
||||||
/**
|
/**
|
||||||
* @type {number | undefined}
|
* @type {number | undefined}
|
||||||
*/
|
*/
|
||||||
|
@ -1172,6 +1176,12 @@ export class HtmlVideoPlayer {
|
||||||
octopus.dispose();
|
octopus.dispose();
|
||||||
}
|
}
|
||||||
this.#currentAssRenderer = null;
|
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
|
* @private
|
||||||
*/
|
*/
|
||||||
|
@ -1434,6 +1457,10 @@ export class HtmlVideoPlayer {
|
||||||
this.renderSsaAss(videoElement, track, item);
|
this.renderSsaAss(videoElement, track, item);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (format === 'pgssub') {
|
||||||
|
this.renderPgs(videoElement, track, item);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (this.requiresCustomSubtitlesElement()) {
|
if (this.requiresCustomSubtitlesElement()) {
|
||||||
this.renderSubtitlesWithCustomElement(videoElement, track, item, targetTextTrackIndex);
|
this.renderSubtitlesWithCustomElement(videoElement, track, item, targetTextTrackIndex);
|
||||||
|
|
|
@ -48,6 +48,15 @@ function supportsTextTracks() {
|
||||||
return _supportsTextTracks;
|
return _supportsTextTracks;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let _supportsCanvas2D;
|
||||||
|
function supportsCanvas2D() {
|
||||||
|
if (_supportsCanvas2D == null) {
|
||||||
|
_supportsCanvas2D = document.createElement('canvas').getContext('2d') != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return _supportsCanvas2D;
|
||||||
|
}
|
||||||
|
|
||||||
let _canPlayHls;
|
let _canPlayHls;
|
||||||
function canPlayHls() {
|
function canPlayHls() {
|
||||||
if (_canPlayHls == null) {
|
if (_canPlayHls == null) {
|
||||||
|
@ -1432,6 +1441,13 @@ export default function (options) {
|
||||||
Method: 'External'
|
Method: 'External'
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (supportsCanvas2D()) {
|
||||||
|
profile.SubtitleProfiles.push({
|
||||||
|
Format: 'pgssub',
|
||||||
|
Method: 'External'
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
profile.ResponseProfiles = [];
|
profile.ResponseProfiles = [];
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue