feat: implement jassub instead of libass

Implementation has been done without the legacy worker
In this client we already assume a modern environment
We don't use polyfills anywhere else, so increasing our bundle size + 2MB for JASSUB doesn't seem logical
This commit is contained in:
Thibault Nocchi 2023-03-05 21:28:51 +01:00 committed by Fernando Fernández
parent ae9d06bf2d
commit 81d1b67c5d
4 changed files with 43 additions and 72 deletions

View File

@ -26,7 +26,6 @@
"vue-i18n-extract-remove": "vue-i18n-extract --remove"
},
"dependencies": {
"@jellyfin/libass-wasm": "4.1.1",
"@jellyfin/sdk": "0.0.0-unstable.202301101857",
"@vueuse/components": "9.12.0",
"@vueuse/core": "9.12.0",
@ -38,6 +37,7 @@
"dompurify": "2.3.8",
"he": "1.2.0",
"hls.js": "1.3.1",
"jassub": "1.5.1",
"langs": "2.0.0",
"lodash-es": "4.17.21",
"swiper": "9.0.3",
@ -86,7 +86,6 @@
"vite": "3.2.2",
"vite-plugin-pages": "0.27.1",
"vite-plugin-pwa": "0.13.2",
"vite-plugin-static-copy": "0.13.0",
"vite-plugin-vue-layouts": "0.7.0",
"vue-eslint-parser": "9.1.0",
"vue-i18n-extract": "2.0.7",

View File

@ -6,14 +6,15 @@
*/
import { cloneDeep } from 'lodash-es';
import { nextTick, reactive, watch } from 'vue';
// @ts-expect-error - No types on libass-wasm
import SubtitlesOctopus from '@jellyfin/libass-wasm';
import subtitlesOctopusWorkerUrl from '@jellyfin/libass-wasm/dist/js/subtitles-octopus-worker.js?url';
import JASSUB from 'jassub';
import jassubWorker from 'jassub/dist/jassub-worker.js?url';
import 'jassub/dist/jassub-worker.wasm?url';
import jassubDefaultFont from 'jassub/dist/default.woff2?url';
import { mediaElementRef, playbackManagerStore } from '@/store';
import { useRouter } from '@/composables';
const playbackManager = playbackManagerStore();
let subtitlesOctopus: SubtitlesOctopus | undefined;
let jassub: JASSUB | undefined;
const fullscreenRoute = '/playback/video';
/**
@ -94,26 +95,32 @@ class PlayerElementStore {
};
private _setSsaTrack = async (trackSrc: string): Promise<void> => {
if (!subtitlesOctopus) {
subtitlesOctopus = new SubtitlesOctopus({
if (
!jassub &&
mediaElementRef.value &&
mediaElementRef.value instanceof HTMLVideoElement
) {
jassub = new JASSUB({
video: mediaElementRef.value,
subUrl: trackSrc,
workerUrl: subtitlesOctopusWorkerUrl,
prescaleFactor: 0.5,
renderAhead: 90
workerUrl: jassubWorker,
availableFonts: { 'liberation sans': jassubDefaultFont },
// Both parameters needed for subs to work on iOS
prescaleFactor: 0.8,
onDemandRender: false
});
} else {
subtitlesOctopus.setTrackByUrl(trackSrc);
} else if (jassub) {
jassub.setTrackByUrl(trackSrc);
}
};
public freeSsaTrack = (): void => {
if (subtitlesOctopus) {
if (jassub) {
try {
subtitlesOctopus.dispose();
jassub.destroy();
} catch {}
subtitlesOctopus = undefined;
jassub = undefined;
}
};

View File

@ -6,7 +6,6 @@ import { defineConfig, UserConfig } from 'vite';
import vue from '@vitejs/plugin-vue';
import Pages from 'vite-plugin-pages';
import Layouts from 'vite-plugin-vue-layouts';
import { viteStaticCopy } from 'vite-plugin-static-copy';
import Icons from 'unplugin-icons/vite';
import IconsResolver from 'unplugin-icons/resolver';
import Components from 'unplugin-vue-components/vite';
@ -83,22 +82,6 @@ export default defineConfig(async ({ mode }): Promise<UserConfig> => {
dirname(fileURLToPath(import.meta.url)),
'./locales/**'
)
}),
viteStaticCopy({
targets: [
{
src: resolve(
'../node_modules/@jellyfin/libass-wasm/dist/js/subtitles-octopus-worker.data'
),
dest: 'assets/'
},
{
src: resolve(
'../node_modules/@jellyfin/libass-wasm/dist/js/subtitles-octopus-worker.wasm'
),
dest: 'assets/'
}
]
})
],
build: {
@ -110,6 +93,13 @@ export default defineConfig(async ({ mode }): Promise<UserConfig> => {
reportCompressedSize: false,
rollupOptions: {
output: {
assetFileNames: (assetInfo) => {
if (assetInfo.name?.endsWith('jassub-worker.wasm')) {
return 'assets/jassub-worker.wasm';
}
return 'assets/[name]-[hash][extname]';
},
plugins: [
mode === 'analyze'
? // rollup-plugin-visualizer

53
package-lock.json generated
View File

@ -21,7 +21,6 @@
"version": "0.2.0",
"license": "GPL-3.0-only",
"dependencies": {
"@jellyfin/libass-wasm": "4.1.1",
"@jellyfin/sdk": "0.0.0-unstable.202301101857",
"@vueuse/components": "9.12.0",
"@vueuse/core": "9.12.0",
@ -33,6 +32,7 @@
"dompurify": "2.3.8",
"he": "1.2.0",
"hls.js": "1.3.1",
"jassub": "1.5.1",
"langs": "2.0.0",
"lodash-es": "4.17.21",
"swiper": "9.0.3",
@ -81,7 +81,6 @@
"vite": "3.2.2",
"vite-plugin-pages": "0.27.1",
"vite-plugin-pwa": "0.13.2",
"vite-plugin-static-copy": "0.13.0",
"vite-plugin-vue-layouts": "0.7.0",
"vue-eslint-parser": "9.1.0",
"vue-i18n-extract": "2.0.7",
@ -2262,11 +2261,6 @@
"resolved": "tauri",
"link": true
},
"node_modules/@jellyfin/libass-wasm": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/@jellyfin/libass-wasm/-/libass-wasm-4.1.1.tgz",
"integrity": "sha512-xQVJw+lZUg4U1TmLS80reBECfPtpCgRF8hhUSvUUQM9g68OvINyUU3K2yqRH+8tomGpghiRaIcr/bUJ83e0veA=="
},
"node_modules/@jimp/bmp": {
"version": "0.16.1",
"resolved": "https://registry.npmjs.org/@jimp/bmp/-/bmp-0.16.1.tgz",
@ -10592,6 +10586,14 @@
"node": ">=8"
}
},
"node_modules/jassub": {
"version": "1.5.1",
"resolved": "https://registry.npmjs.org/jassub/-/jassub-1.5.1.tgz",
"integrity": "sha512-li8NUMm9JYHELRrsEEd9+8wX/PdN3H7JKE1V3Hwm9S7QmTr1Rx2VRU9AeiwJbZpxp9CcVSTyw0xFykluDGItHg==",
"dependencies": {
"rvfc-polyfill": "^1.0.4"
}
},
"node_modules/jest-worker": {
"version": "26.6.2",
"resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-26.6.2.tgz",
@ -13279,6 +13281,11 @@
"queue-microtask": "^1.2.2"
}
},
"node_modules/rvfc-polyfill": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/rvfc-polyfill/-/rvfc-polyfill-1.0.4.tgz",
"integrity": "sha512-BemRbBDZiLB8pxoPT+2q6R30ykY1e75XBE/L1A0Ubd/3KdUoCQLqI/z4v4oNFNlN3/Rs93d3b6WoybnXhdebkw=="
},
"node_modules/rxjs": {
"version": "7.5.6",
"resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.5.6.tgz",
@ -15032,38 +15039,6 @@
"workbox-window": "^6.5.4"
}
},
"node_modules/vite-plugin-static-copy": {
"version": "0.13.0",
"resolved": "https://registry.npmjs.org/vite-plugin-static-copy/-/vite-plugin-static-copy-0.13.0.tgz",
"integrity": "sha512-cln+fvKMgwNBjxQ59QVblmExZrc9gGEdRmfqcPOOGpxT5KInfpkGMvmK4L+kCAeHHSSGNU1bM7BA9PQgaAJc6g==",
"dev": true,
"dependencies": {
"chokidar": "^3.5.3",
"fast-glob": "^3.2.11",
"fs-extra": "^11.1.0",
"picocolors": "^1.0.0"
},
"engines": {
"node": "^14.18.0 || >=16.0.0"
},
"peerDependencies": {
"vite": "^3.0.0 || ^4.0.0"
}
},
"node_modules/vite-plugin-static-copy/node_modules/fs-extra": {
"version": "11.1.0",
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.1.0.tgz",
"integrity": "sha512-0rcTq621PD5jM/e0a3EJoGC/1TC5ZBCERW82LQuwfGnCa1V8w7dpYH1yNu+SLb6E5dkeCBzKEyLGlFrnr+dUyw==",
"dev": true,
"dependencies": {
"graceful-fs": "^4.2.0",
"jsonfile": "^6.0.1",
"universalify": "^2.0.0"
},
"engines": {
"node": ">=14.14"
}
},
"node_modules/vite-plugin-vue-layouts": {
"version": "0.7.0",
"resolved": "https://registry.npmjs.org/vite-plugin-vue-layouts/-/vite-plugin-vue-layouts-0.7.0.tgz",