From 792dee44e2c97479a2d038f9f84d0b5315660df3 Mon Sep 17 00:00:00 2001 From: p0358 Date: Sun, 25 Aug 2024 22:18:12 +0200 Subject: [PATCH 1/2] Load only required fallback fonts for ASS subtitles, instead of preloading them all --- src/plugins/htmlVideoPlayer/plugin.js | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/src/plugins/htmlVideoPlayer/plugin.js b/src/plugins/htmlVideoPlayer/plugin.js index 83e247eb83..337b8b3e56 100644 --- a/src/plugins/htmlVideoPlayer/plugin.js +++ b/src/plugins/htmlVideoPlayer/plugin.js @@ -1244,15 +1244,15 @@ export class HtmlVideoPlayer { * @private */ renderSsaAss(videoElement, track, item) { - const supportedFonts = ['application/vnd.ms-opentype', 'application/x-truetype-font', 'font/otf', 'font/ttf', 'font/woff', 'font/woff2']; - const availableFonts = []; + const supportedFontMimeTypes = ['application/vnd.ms-opentype', 'application/x-truetype-font', 'font/otf', 'font/ttf', 'font/woff', 'font/woff2']; + const fontsToPreload = []; const attachments = this._currentPlayOptions.mediaSource.MediaAttachments || []; const apiClient = ServerConnections.getApiClient(item); attachments.forEach(i => { // we only require font files and ignore embedded media attachments like covers as there are cases where ffmpeg fails to extract those - if (supportedFonts.includes(i.MimeType)) { + if (supportedFontMimeTypes.includes(i.MimeType)) { // embedded font url - availableFonts.push(apiClient.getUrl(i.DeliveryUrl)); + fontsToPreload.push(apiClient.getUrl(i.DeliveryUrl)); } }); const fallbackFontList = apiClient.getUrl('/FallbackFont/Fonts', { @@ -1263,7 +1263,7 @@ export class HtmlVideoPlayer { const options = { video: videoElement, subUrl: getTextTrackUrl(track, item), - fonts: availableFonts, + fonts: fontsToPreload, workerUrl: `${appRouter.baseUrl()}/libraries/subtitles-octopus-worker.js`, legacyWorkerUrl: `${appRouter.baseUrl()}/libraries/subtitles-octopus-worker-legacy.js`, onError() { @@ -1301,12 +1301,18 @@ export class HtmlVideoPlayer { if (config.EnableFallbackFont) { apiClient.getJSON(fallbackFontList).then((fontFiles = []) => { + const availableFonts = {}; fontFiles.forEach(font => { - const fontUrl = apiClient.getUrl(`/FallbackFont/Fonts/${encodeURIComponent(font.Name)}`, { - api_key: apiClient.accessToken() - }); - availableFonts.push(fontUrl); + if (!font.FamilyName) return; + const familyNameLower = font.FamilyName.trim().toLowerCase(); + if (!(familyNameLower in availableFonts)) { + const fontUrl = apiClient.getUrl(`/FallbackFont/Fonts/${encodeURIComponent(font.Name)}`, { + api_key: apiClient.accessToken() + }); + availableFonts[familyNameLower] = fontUrl; + } }); + options.availableFonts = availableFonts; this.#currentAssRenderer = new SubtitlesOctopus(options); }); } else { From d821ad3562a55c028fbe3342e821ee31cfc09f83 Mon Sep 17 00:00:00 2001 From: p0358 Date: Sat, 28 Sep 2024 18:11:59 +0200 Subject: [PATCH 2/2] Limit max size of a single fallback font file for ASS to 20 MB It used to be limited to 20 MB total previously. We cannot easily limit total size of fonts anymore, so the least we can do is to keep the size of a single font file in check. --- src/plugins/htmlVideoPlayer/plugin.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/plugins/htmlVideoPlayer/plugin.js b/src/plugins/htmlVideoPlayer/plugin.js index 337b8b3e56..f616723f87 100644 --- a/src/plugins/htmlVideoPlayer/plugin.js +++ b/src/plugins/htmlVideoPlayer/plugin.js @@ -1304,6 +1304,7 @@ export class HtmlVideoPlayer { const availableFonts = {}; fontFiles.forEach(font => { if (!font.FamilyName) return; + if (font.Size > 20 * 1024 * 1024) return; // max 20 MB for any single font file const familyNameLower = font.FamilyName.trim().toLowerCase(); if (!(familyNameLower in availableFonts)) { const fontUrl = apiClient.getUrl(`/FallbackFont/Fonts/${encodeURIComponent(font.Name)}`, {