diff --git a/src/controllers/dashboard/encodingsettings.html b/src/controllers/dashboard/encodingsettings.html index 5afbdad24f..7a43d67e46 100644 --- a/src/controllers/dashboard/encodingsettings.html +++ b/src/controllers/dashboard/encodingsettings.html @@ -178,6 +178,22 @@
${LabelTranscodingTempPathHelp}
+
+
+
+ +
+ +
+
${LabelFallbackFontPathHelp}
+
+
+ +
${EnableFallbackFontHelp}
+
${LabelDownMixAudioScaleHelp}
diff --git a/src/controllers/dashboard/encodingsettings.js b/src/controllers/dashboard/encodingsettings.js index 6a54e8105d..5c8acff823 100644 --- a/src/controllers/dashboard/encodingsettings.js +++ b/src/controllers/dashboard/encodingsettings.js @@ -19,6 +19,8 @@ import libraryMenu from 'libraryMenu'; page.querySelector('#txtMaxMuxingQueueSize').value = config.MaxMuxingQueueSize || ''; page.querySelector('.txtEncoderPath').value = config.EncoderAppPathDisplay || ''; $('#txtTranscodingTempPath', page).val(systemInfo.TranscodingTempPath || ''); + page.querySelector('#txtFallbackFontPath').value = config.FallbackFontPath || ''; + page.querySelector('#chkEnableFallbackFont').checked = config.EnableFallbackFont; $('#txtVaapiDevice', page).val(config.VaapiDevice || ''); page.querySelector('#chkTonemapping').checked = config.EnableTonemapping; page.querySelector('#txtOpenclDevice').value = config.OpenclDevice || ''; @@ -73,6 +75,8 @@ import libraryMenu from 'libraryMenu'; config.DownMixAudioBoost = $('#txtDownMixAudioBoost', form).val(); config.MaxMuxingQueueSize = form.querySelector('#txtMaxMuxingQueueSize').value; config.TranscodingTempPath = $('#txtTranscodingTempPath', form).val(); + config.FallbackFontPath = form.querySelector('#txtFallbackFontPath').value; + config.EnableFallbackFont = form.querySelector('#txtFallbackFontPath').value ? form.querySelector('#chkEnableFallbackFont').checked : false; config.EncodingThreadCount = $('#selectThreadCount', form).val(); config.HardwareAccelerationType = $('#selectVideoDecoder', form).val(); config.VaapiDevice = $('#txtVaapiDevice', form).val(); @@ -217,6 +221,23 @@ import libraryMenu from 'libraryMenu'; }); }); }); + $('#btnSelectFallbackFontPath', page).on('click.selectDirectory', function () { + import('directorybrowser').then(({default: directoryBrowser}) => { + const picker = new directoryBrowser(); + picker.show({ + includeDirectories: true, + callback: function (path) { + if (path) { + page.querySelector('#txtFallbackFontPath').value = path; + } + + picker.close(); + }, + header: globalize.translate('HeaderSelectFallbackFontPath'), + instruction: globalize.translate('HeaderSelectFallbackFontPathHelp') + }); + }); + }); $('.encodingSettingsForm').off('submit', onSubmit).on('submit', onSubmit); }).on('pageshow', '#encodingSettingsPage', function () { loading.show(); diff --git a/src/plugins/htmlVideoPlayer/plugin.js b/src/plugins/htmlVideoPlayer/plugin.js index 32f96c8e2e..d2b395ffc6 100644 --- a/src/plugins/htmlVideoPlayer/plugin.js +++ b/src/plugins/htmlVideoPlayer/plugin.js @@ -1030,15 +1030,21 @@ function tryRemoveElement(elem) { * @private */ renderSsaAss(videoElement, track, item) { + const avaliableFonts = []; const attachments = this._currentPlayOptions.mediaSource.MediaAttachments || []; + attachments.map(function (i) { + // embedded font url + return avaliableFonts.push(i.DeliveryUrl); + }); const apiClient = window.connectionManager.getApiClient(item); + const fallbackFontList = apiClient.getUrl('/FallbackFont/Fonts', { + api_key: apiClient.accessToken() + }); const htmlVideoPlayer = this; const options = { video: videoElement, subUrl: getTextTrackUrl(track, item), - fonts: attachments.map(function (i) { - return apiClient.getUrl(i.DeliveryUrl); - }), + fonts: avaliableFonts, workerUrl: `${appRouter.baseUrl()}/libraries/subtitles-octopus-worker.js`, legacyWorkerUrl: `${appRouter.baseUrl()}/libraries/subtitles-octopus-worker-legacy.js`, onError() { @@ -1059,7 +1065,21 @@ function tryRemoveElement(elem) { renderAhead: 90 }; import('JavascriptSubtitlesOctopus').then(({default: SubtitlesOctopus}) => { - this.#currentSubtitlesOctopus = new SubtitlesOctopus(options); + apiClient.getNamedConfiguration('encoding').then((config) => { + if (config.EnableFallbackFont) { + apiClient.getJSON(fallbackFontList).then((fontFiles) => { + (fontFiles || []).map(function (font) { + const fontUrl = apiClient.getUrl(`/FallbackFont/Fonts/${font.Name}`, { + api_key: apiClient.accessToken() + }); + return avaliableFonts.push(fontUrl); + }); + this.#currentSubtitlesOctopus = new SubtitlesOctopus(options); + }); + } else { + this.#currentSubtitlesOctopus = new SubtitlesOctopus(options); + } + }); }); } diff --git a/src/strings/en-us.json b/src/strings/en-us.json index c2ad064922..213329f9d0 100644 --- a/src/strings/en-us.json +++ b/src/strings/en-us.json @@ -1420,6 +1420,12 @@ "LabelTonemappingParamHelp": "Tune the tone mapping algorithm. The recommended and default values are NaN. Generally leave it blank.", "StopPlayback": "Stop playback", "ClearQueue": "Clear queue", + "HeaderSelectFallbackFontPath" : "Select Fallback Font Folder Path", + "HeaderSelectFallbackFontPathHelp": "Browse or enter the path of the fallback font folder to use for rendering ASS/SSA subtitles.", + "LabelFallbackFontPath": "Fallback font folder path:", + "LabelFallbackFontPathHelp": "Specify a path containing fallback fonts for rendering ASS/SSA subtitles. The maximum allowed total font size is 20 MB. Lightweight and web-friendly font formats such as woff2 are recommended.", + "EnableFallbackFont" : "Enable fallback fonts", + "EnableFallbackFontHelp" : "Enable custom alternate fonts. This can avoid the problem of incorrect subtitle rendering.", "LabelSubtitleVerticalPosition": "Vertical position:", "SubtitleVerticalPositionHelp": "Line number where text appears. Positive numbers indicate top down. Negative numbers indicate bottom up.", "Preview": "Preview", diff --git a/src/strings/zh-cn.json b/src/strings/zh-cn.json index d6603c6eb9..34d0441236 100644 --- a/src/strings/zh-cn.json +++ b/src/strings/zh-cn.json @@ -1367,6 +1367,12 @@ "StopPlayback": "停止播放", "Writers": "作者", "ViewAlbumArtist": "查看专辑艺术家", + "HeaderSelectFallbackFontPath" : "选择备用字体路径", + "HeaderSelectFallbackFontPathHelp": "浏览或输入一个包含备用字体文件的路径用于渲染 ASS/SSA 字幕。", + "LabelFallbackFontPath": "备用字体文件路径:", + "LabelFallbackFontPathHelp": "指定一个包含备用字体文件的路径用于渲染 ASS/SSA 字幕。允许的最大字体总容量为 20 MB。推荐使用轻量且适合网络传输的字体,例如 woff2。", + "EnableFallbackFont" : "启用备用字体", + "EnableFallbackFontHelp" : "使用自定义的备用字体。这可以避免一些字幕渲染不正确的问题。", "Preview": "预览", "SubtitleVerticalPositionHelp": "文字出现的行号。正数表示由上到下,负数表示由下到上。", "LabelSubtitleVerticalPosition": "垂直位置:",