From c888b34a6219be0c06331e568d66a8fdf17bceaa Mon Sep 17 00:00:00 2001 From: nyanmisaka Date: Fri, 24 Jul 2020 21:19:56 +0800 Subject: [PATCH 01/11] add a method to use custom fallback fonts for subtitle rendering --- MediaBrowser.Api/Subtitles/SubtitleService.cs | 53 +++++++++++++++++++ .../Configuration/EncodingOptions.cs | 5 ++ 2 files changed, 58 insertions(+) diff --git a/MediaBrowser.Api/Subtitles/SubtitleService.cs b/MediaBrowser.Api/Subtitles/SubtitleService.cs index a70da8e56c..198e459482 100644 --- a/MediaBrowser.Api/Subtitles/SubtitleService.cs +++ b/MediaBrowser.Api/Subtitles/SubtitleService.cs @@ -6,6 +6,7 @@ using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; +using MediaBrowser.Common.Configuration; using MediaBrowser.Controller.Configuration; using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Library; @@ -122,8 +123,15 @@ namespace MediaBrowser.Api.Subtitles public int SegmentLength { get; set; } } + [Route("/FallbackFont/Font", "GET", Summary = "Gets the fallback font file")] + [Authenticated] + public class GetFallbackFont + { + } + public class SubtitleService : BaseApiService { + private readonly IServerConfigurationManager _serverConfigurationManager; private readonly ILibraryManager _libraryManager; private readonly ISubtitleManager _subtitleManager; private readonly ISubtitleEncoder _subtitleEncoder; @@ -145,6 +153,7 @@ namespace MediaBrowser.Api.Subtitles IAuthorizationContext authContext) : base(logger, serverConfigurationManager, httpResultFactory) { + _serverConfigurationManager = serverConfigurationManager; _libraryManager = libraryManager; _subtitleManager = subtitleManager; _subtitleEncoder = subtitleEncoder; @@ -298,5 +307,49 @@ namespace MediaBrowser.Api.Subtitles } }); } + + public async Task Get(GetFallbackFont request) + { + var fallbackFontPath = EncodingConfigurationExtensions.GetEncodingOptions(_serverConfigurationManager).FallbackFontPath; + + if (!string.IsNullOrEmpty(fallbackFontPath)) + { + var directoryService = new DirectoryService(_fileSystem); + + try + { + // 10 Megabytes + var maxSize = 10485760; + var fontFile = directoryService.GetFile(fallbackFontPath); + var fileSize = fontFile?.Length; + + if (fileSize != null && fileSize > 0) + { + Logger.LogInformation("Fallback font size is {0} Bytes", fileSize); + + if (fileSize <= maxSize) + { + return await ResultFactory.GetStaticFileResult(Request, fontFile.FullName); + } + + Logger.LogInformation("The selected font is too large. Maximum allowed size is 10 Megabytes"); + } + else + { + Logger.LogInformation("The selected font is null or empty"); + } + } + catch (Exception ex) + { + Logger.LogError(ex, "Error reading fallback font file"); + } + } + else + { + Logger.LogInformation("The path of fallback font has not been set"); + } + + return string.Empty; + } } } diff --git a/MediaBrowser.Model/Configuration/EncodingOptions.cs b/MediaBrowser.Model/Configuration/EncodingOptions.cs index 9a30f7e9f0..aa6ed5bb9f 100644 --- a/MediaBrowser.Model/Configuration/EncodingOptions.cs +++ b/MediaBrowser.Model/Configuration/EncodingOptions.cs @@ -9,6 +9,10 @@ namespace MediaBrowser.Model.Configuration public string TranscodingTempPath { get; set; } + public string FallbackFontPath { get; set; } + + public bool EnableFallbackFont { get; set; } + public double DownMixAudioBoost { get; set; } public bool EnableThrottling { get; set; } @@ -49,6 +53,7 @@ namespace MediaBrowser.Model.Configuration public EncodingOptions() { + EnableFallbackFont = false; DownMixAudioBoost = 2; EnableThrottling = false; ThrottleDelaySeconds = 180; From a78c8e38544a974f07c6efce1af4e7fbef83b2be Mon Sep 17 00:00:00 2001 From: Nyanmisaka Date: Sat, 25 Jul 2020 01:50:18 +0800 Subject: [PATCH 02/11] change loglevels --- MediaBrowser.Api/Subtitles/SubtitleService.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/MediaBrowser.Api/Subtitles/SubtitleService.cs b/MediaBrowser.Api/Subtitles/SubtitleService.cs index 198e459482..b06ffd1851 100644 --- a/MediaBrowser.Api/Subtitles/SubtitleService.cs +++ b/MediaBrowser.Api/Subtitles/SubtitleService.cs @@ -325,18 +325,18 @@ namespace MediaBrowser.Api.Subtitles if (fileSize != null && fileSize > 0) { - Logger.LogInformation("Fallback font size is {0} Bytes", fileSize); + Logger.LogDebug("Fallback font size is {0} Bytes", fileSize); if (fileSize <= maxSize) { return await ResultFactory.GetStaticFileResult(Request, fontFile.FullName); } - Logger.LogInformation("The selected font is too large. Maximum allowed size is 10 Megabytes"); + Logger.LogWarning("The selected font is too large. Maximum allowed size is 10 Megabytes"); } else { - Logger.LogInformation("The selected font is null or empty"); + Logger.LogWarning("The selected font is null or empty"); } } catch (Exception ex) @@ -346,7 +346,7 @@ namespace MediaBrowser.Api.Subtitles } else { - Logger.LogInformation("The path of fallback font has not been set"); + Logger.LogWarning("The path of fallback font has not been set"); } return string.Empty; From 45a97056ea9fe7bc247f205931f5b0e0f2a1ab75 Mon Sep 17 00:00:00 2001 From: nyanmisaka Date: Wed, 29 Jul 2020 02:44:11 +0800 Subject: [PATCH 03/11] allows to provide multiple fonts --- MediaBrowser.Api/Subtitles/SubtitleService.cs | 83 +++++++++++++++++-- MediaBrowser.Model/Subtitles/FontFile.cs | 34 ++++++++ 2 files changed, 108 insertions(+), 9 deletions(-) create mode 100644 MediaBrowser.Model/Subtitles/FontFile.cs diff --git a/MediaBrowser.Api/Subtitles/SubtitleService.cs b/MediaBrowser.Api/Subtitles/SubtitleService.cs index b06ffd1851..b5f5213fe3 100644 --- a/MediaBrowser.Api/Subtitles/SubtitleService.cs +++ b/MediaBrowser.Api/Subtitles/SubtitleService.cs @@ -18,6 +18,7 @@ using MediaBrowser.Model.Entities; using MediaBrowser.Model.IO; using MediaBrowser.Model.Providers; using MediaBrowser.Model.Services; +using MediaBrowser.Model.Subtitles; using Microsoft.Extensions.Logging; using MimeTypes = MediaBrowser.Model.Net.MimeTypes; @@ -123,10 +124,18 @@ namespace MediaBrowser.Api.Subtitles public int SegmentLength { get; set; } } + [Route("/FallbackFont/FontList", "GET", Summary = "Gets the fallback font list")] + [Authenticated] + public class GetFallbackFontList + { + } + [Route("/FallbackFont/Font", "GET", Summary = "Gets the fallback font file")] [Authenticated] public class GetFallbackFont { + [ApiMember(Name = "Name", Description = "The font file name.", IsRequired = true, DataType = "string", ParameterType = "query", Verb = "GET", AllowMultiple = true)] + public string Name { get; set; } } public class SubtitleService : BaseApiService @@ -308,19 +317,74 @@ namespace MediaBrowser.Api.Subtitles }); } - public async Task Get(GetFallbackFont request) + public object Get(GetFallbackFontList request) { - var fallbackFontPath = EncodingConfigurationExtensions.GetEncodingOptions(_serverConfigurationManager).FallbackFontPath; + IEnumerable fontFiles = Enumerable.Empty(); + + var encodingOptions = EncodingConfigurationExtensions.GetEncodingOptions(_serverConfigurationManager); + var fallbackFontPath = encodingOptions.FallbackFontPath; if (!string.IsNullOrEmpty(fallbackFontPath)) { - var directoryService = new DirectoryService(_fileSystem); - try { - // 10 Megabytes + fontFiles = _fileSystem.GetFiles(fallbackFontPath, new[] { ".woff", ".woff2", ".ttf", ".otf" }, false, false); + + var result = fontFiles.Select(i => new FontFile + { + Name = i.Name, + Size = i.Length, + DateCreated = _fileSystem.GetCreationTimeUtc(i), + DateModified = _fileSystem.GetLastWriteTimeUtc(i) + }).OrderBy(i => i.Size) + .ThenBy(i => i.Name) + .ThenByDescending(i => i.DateModified) + .ThenByDescending(i => i.DateCreated) + .ToArray(); + + // max total size 20M + var maxSize = 20971520; + var sizeCounter = 0L; + for (int i = 0; i < result.Length; i++) + { + sizeCounter += result[i].Size; + if (sizeCounter >= maxSize) + { + Logger.LogWarning("Some fonts will not be sent due to size limitations"); + Array.Resize(ref result, i); + break; + } + } + + return ToOptimizedResult(result); + } + catch (Exception ex) + { + Logger.LogError(ex, "Error getting fallback font list"); + } + } + else + { + Logger.LogWarning("The path of fallback font folder has not been set"); + encodingOptions.EnableFallbackFont = false; + } + + return ResultFactory.GetResult(Request, "[]", "application/json"); + } + + public async Task Get(GetFallbackFont request) + { + var encodingOptions = EncodingConfigurationExtensions.GetEncodingOptions(_serverConfigurationManager); + var fallbackFontPath = encodingOptions.FallbackFontPath; + + if (!string.IsNullOrEmpty(fallbackFontPath)) + { + try + { + // max single font size 10M var maxSize = 10485760; - var fontFile = directoryService.GetFile(fallbackFontPath); + var fontFile = _fileSystem.GetFiles(fallbackFontPath) + .First(i => string.Equals(i.Name, request.Name, StringComparison.OrdinalIgnoreCase)); var fileSize = fontFile?.Length; if (fileSize != null && fileSize > 0) @@ -341,15 +405,16 @@ namespace MediaBrowser.Api.Subtitles } catch (Exception ex) { - Logger.LogError(ex, "Error reading fallback font file"); + Logger.LogError(ex, "Error reading fallback font"); } } else { - Logger.LogWarning("The path of fallback font has not been set"); + Logger.LogWarning("The path of fallback font folder has not been set"); + encodingOptions.EnableFallbackFont = false; } - return string.Empty; + return ResultFactory.GetResult(Request, string.Empty, "text/plain"); } } } diff --git a/MediaBrowser.Model/Subtitles/FontFile.cs b/MediaBrowser.Model/Subtitles/FontFile.cs new file mode 100644 index 0000000000..13963a9cb5 --- /dev/null +++ b/MediaBrowser.Model/Subtitles/FontFile.cs @@ -0,0 +1,34 @@ +#nullable disable +#pragma warning disable CS1591 + +using System; + +namespace MediaBrowser.Model.Subtitles +{ + public class FontFile + { + /// + /// Gets or sets the name. + /// + /// The name. + public string Name { get; set; } + + /// + /// Gets or sets the size. + /// + /// The size. + public long Size { get; set; } + + /// + /// Gets or sets the date created. + /// + /// The date created. + public DateTime DateCreated { get; set; } + + /// + /// Gets or sets the date modified. + /// + /// The date modified. + public DateTime DateModified { get; set; } + } +} From 893bc7400bc2dadf2a789ba439d9a469c13b05df Mon Sep 17 00:00:00 2001 From: Nyanmisaka Date: Thu, 30 Jul 2020 16:30:49 +0800 Subject: [PATCH 04/11] update as per suggestions --- MediaBrowser.Api/Subtitles/SubtitleService.cs | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/MediaBrowser.Api/Subtitles/SubtitleService.cs b/MediaBrowser.Api/Subtitles/SubtitleService.cs index b5f5213fe3..e275d3a285 100644 --- a/MediaBrowser.Api/Subtitles/SubtitleService.cs +++ b/MediaBrowser.Api/Subtitles/SubtitleService.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.Globalization; using System.IO; using System.Linq; +using System.Net.Mime; using System.Text; using System.Threading; using System.Threading.Tasks; @@ -124,13 +125,13 @@ namespace MediaBrowser.Api.Subtitles public int SegmentLength { get; set; } } - [Route("/FallbackFont/FontList", "GET", Summary = "Gets the fallback font list")] + [Route("/FallbackFont/Fonts", "GET", Summary = "Gets the fallback font list")] [Authenticated] public class GetFallbackFontList { } - [Route("/FallbackFont/Font", "GET", Summary = "Gets the fallback font file")] + [Route("/FallbackFont/Fonts/{Name}", "GET", Summary = "Gets the fallback font file")] [Authenticated] public class GetFallbackFont { @@ -369,7 +370,7 @@ namespace MediaBrowser.Api.Subtitles encodingOptions.EnableFallbackFont = false; } - return ResultFactory.GetResult(Request, "[]", "application/json"); + return ResultFactory.GetResult(Request, "[]", MediaTypeNames.Application.Json); } public async Task Get(GetFallbackFont request) @@ -414,7 +415,7 @@ namespace MediaBrowser.Api.Subtitles encodingOptions.EnableFallbackFont = false; } - return ResultFactory.GetResult(Request, string.Empty, "text/plain"); + return ResultFactory.GetResult(Request, string.Empty, MediaTypeNames.Text.Plain); } } } From 8165c3bb21a1ac4869dafa951f8a3ca3d21dda1e Mon Sep 17 00:00:00 2001 From: Nyanmisaka Date: Thu, 30 Jul 2020 17:36:38 +0800 Subject: [PATCH 05/11] total font size limit 20M --- MediaBrowser.Api/Subtitles/SubtitleService.cs | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/MediaBrowser.Api/Subtitles/SubtitleService.cs b/MediaBrowser.Api/Subtitles/SubtitleService.cs index e275d3a285..bd4da04f90 100644 --- a/MediaBrowser.Api/Subtitles/SubtitleService.cs +++ b/MediaBrowser.Api/Subtitles/SubtitleService.cs @@ -382,8 +382,6 @@ namespace MediaBrowser.Api.Subtitles { try { - // max single font size 10M - var maxSize = 10485760; var fontFile = _fileSystem.GetFiles(fallbackFontPath) .First(i => string.Equals(i.Name, request.Name, StringComparison.OrdinalIgnoreCase)); var fileSize = fontFile?.Length; @@ -391,13 +389,7 @@ namespace MediaBrowser.Api.Subtitles if (fileSize != null && fileSize > 0) { Logger.LogDebug("Fallback font size is {0} Bytes", fileSize); - - if (fileSize <= maxSize) - { - return await ResultFactory.GetStaticFileResult(Request, fontFile.FullName); - } - - Logger.LogWarning("The selected font is too large. Maximum allowed size is 10 Megabytes"); + return await ResultFactory.GetStaticFileResult(Request, fontFile.FullName); } else { From 988e76d4c7df48370a6cb1de59c4909d140f96e2 Mon Sep 17 00:00:00 2001 From: nyanmisaka Date: Wed, 19 Aug 2020 17:30:22 +0800 Subject: [PATCH 06/11] update endpoints as AspNet controllers --- .../Controllers/SubtitleController.cs | 118 ++++++++++++++++++ 1 file changed, 118 insertions(+) diff --git a/Jellyfin.Api/Controllers/SubtitleController.cs b/Jellyfin.Api/Controllers/SubtitleController.cs index 988acccc3a..387c9b0953 100644 --- a/Jellyfin.Api/Controllers/SubtitleController.cs +++ b/Jellyfin.Api/Controllers/SubtitleController.cs @@ -10,6 +10,8 @@ using System.Text; using System.Threading; using System.Threading.Tasks; using Jellyfin.Api.Constants; +using MediaBrowser.Common.Configuration; +using MediaBrowser.Controller.Configuration; using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Library; using MediaBrowser.Controller.MediaEncoding; @@ -20,6 +22,7 @@ using MediaBrowser.Model.Entities; using MediaBrowser.Model.IO; using MediaBrowser.Model.Net; using MediaBrowser.Model.Providers; +using MediaBrowser.Model.Subtitles; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; @@ -33,6 +36,7 @@ namespace Jellyfin.Api.Controllers [Route("")] public class SubtitleController : BaseJellyfinApiController { + private readonly IServerConfigurationManager _serverConfigurationManager; private readonly ILibraryManager _libraryManager; private readonly ISubtitleManager _subtitleManager; private readonly ISubtitleEncoder _subtitleEncoder; @@ -45,6 +49,7 @@ namespace Jellyfin.Api.Controllers /// /// Initializes a new instance of the class. /// + /// Instance of interface. /// Instance of interface. /// Instance of interface. /// Instance of interface. @@ -54,6 +59,7 @@ namespace Jellyfin.Api.Controllers /// Instance of interface. /// Instance of interface. public SubtitleController( + IServerConfigurationManager serverConfigurationManager, ILibraryManager libraryManager, ISubtitleManager subtitleManager, ISubtitleEncoder subtitleEncoder, @@ -63,6 +69,7 @@ namespace Jellyfin.Api.Controllers IAuthorizationContext authContext, ILogger logger) { + _serverConfigurationManager = serverConfigurationManager; _libraryManager = libraryManager; _subtitleManager = subtitleManager; _subtitleEncoder = subtitleEncoder; @@ -346,5 +353,116 @@ namespace Jellyfin.Api.Controllers copyTimestamps, CancellationToken.None); } + + /// + /// Gets a list of available fallback font files. + /// + /// Information retrieved. + /// An array of with the available font files. + [HttpGet("/FallbackFont/Fonts")] + [Authorize(Policy = Policies.DefaultAuthorization)] + [ProducesResponseType(StatusCodes.Status200OK)] + public ActionResult GetFallbackFontList() + { + IEnumerable fontFiles = Enumerable.Empty(); + + var encodingOptions = EncodingConfigurationExtensions.GetEncodingOptions(_serverConfigurationManager); + var fallbackFontPath = encodingOptions.FallbackFontPath; + + if (!string.IsNullOrEmpty(fallbackFontPath)) + { + try + { + fontFiles = _fileSystem.GetFiles(fallbackFontPath, new[] { ".woff", ".woff2", ".ttf", ".otf" }, false, false); + + var result = fontFiles.Select(i => new FontFile + { + Name = i.Name, + Size = i.Length, + DateCreated = _fileSystem.GetCreationTimeUtc(i), + DateModified = _fileSystem.GetLastWriteTimeUtc(i) + }).OrderBy(i => i.Size) + .ThenBy(i => i.Name) + .ThenByDescending(i => i.DateModified) + .ThenByDescending(i => i.DateCreated) + .ToArray(); + + // max total size 20M + var maxSize = 20971520; + var sizeCounter = 0L; + for (int i = 0; i < result.Length; i++) + { + sizeCounter += result[i].Size; + if (sizeCounter >= maxSize) + { + _logger.LogWarning("Some fonts will not be sent due to size limitations"); + Array.Resize(ref result, i); + break; + } + } + + return result; + } + catch (Exception ex) + { + _logger.LogError(ex, "Error getting fallback font list"); + } + } + else + { + _logger.LogWarning("The path of fallback font folder has not been set"); + encodingOptions.EnableFallbackFont = false; + } + + return File(Encoding.UTF8.GetBytes("[]"), MediaTypeNames.Application.Json); + } + + /// + /// Gets a fallback font file. + /// + /// The name of the fallback font file to get. + /// Fallback font file retrieved. + /// The fallback font file. + [HttpGet("/FallbackFont/Fonts/{name}")] + [Authorize(Policy = Policies.DefaultAuthorization)] + [ProducesResponseType(StatusCodes.Status200OK)] + public ActionResult GetFallbackFont([FromRoute, Required] string? name) + { + var encodingOptions = EncodingConfigurationExtensions.GetEncodingOptions(_serverConfigurationManager); + var fallbackFontPath = encodingOptions.FallbackFontPath; + + if (!string.IsNullOrEmpty(fallbackFontPath)) + { + try + { + var fontFile = _fileSystem.GetFiles(fallbackFontPath) + .First(i => string.Equals(i.Name, name, StringComparison.OrdinalIgnoreCase)); + var fileSize = fontFile?.Length; + + if (fontFile != null && fileSize != null && fileSize > 0) + { + _logger.LogDebug("Fallback font size is {0} Bytes", fileSize); + + FileStream stream = new FileStream(fontFile.FullName, FileMode.Open, FileAccess.Read); + return File(stream, MimeTypes.GetMimeType(fontFile.FullName)); + } + else + { + _logger.LogWarning("The selected font is null or empty"); + } + } + catch (Exception ex) + { + _logger.LogError(ex, "Error reading fallback font"); + } + } + else + { + _logger.LogWarning("The path of fallback font folder has not been set"); + encodingOptions.EnableFallbackFont = false; + } + + return File(Encoding.UTF8.GetBytes(string.Empty), MediaTypeNames.Text.Plain); + } } } From 53861db45139022907c24a43bea43225f34c6a6d Mon Sep 17 00:00:00 2001 From: Nyanmisaka Date: Thu, 20 Aug 2020 00:04:55 +0800 Subject: [PATCH 07/11] Apply suggestions from code review Co-authored-by: Cody Robibero --- .../Controllers/SubtitleController.cs | 69 +++++++++---------- 1 file changed, 33 insertions(+), 36 deletions(-) diff --git a/Jellyfin.Api/Controllers/SubtitleController.cs b/Jellyfin.Api/Controllers/SubtitleController.cs index 387c9b0953..0795f8f649 100644 --- a/Jellyfin.Api/Controllers/SubtitleController.cs +++ b/Jellyfin.Api/Controllers/SubtitleController.cs @@ -359,53 +359,52 @@ namespace Jellyfin.Api.Controllers /// /// Information retrieved. /// An array of with the available font files. - [HttpGet("/FallbackFont/Fonts")] + [HttpGet("FallbackFont/Fonts")] [Authorize(Policy = Policies.DefaultAuthorization)] [ProducesResponseType(StatusCodes.Status200OK)] - public ActionResult GetFallbackFontList() + /// + /// Gets a list of available fallback font files. + /// + /// Information retrieved. + /// An array of with the available font files. + [HttpGet("FallbackFont/Fonts")] + [Authorize(Policy = Policies.DefaultAuthorization)] + [ProducesResponseType(StatusCodes.Status200OK)] + public IEnumerable GetFallbackFontList() { - IEnumerable fontFiles = Enumerable.Empty(); - - var encodingOptions = EncodingConfigurationExtensions.GetEncodingOptions(_serverConfigurationManager); + var encodingOptions = _serverConfigurationManager.GetEncodingOptions(); var fallbackFontPath = encodingOptions.FallbackFontPath; if (!string.IsNullOrEmpty(fallbackFontPath)) { - try - { - fontFiles = _fileSystem.GetFiles(fallbackFontPath, new[] { ".woff", ".woff2", ".ttf", ".otf" }, false, false); + var files = _fileSystem.GetFiles(fallbackFontPath, new[] { ".woff", ".woff2", ".ttf", ".otf" }, false, false); - var result = fontFiles.Select(i => new FontFile + var fontFiles = files + .Select(i => new FontFile { Name = i.Name, Size = i.Length, DateCreated = _fileSystem.GetCreationTimeUtc(i), DateModified = _fileSystem.GetLastWriteTimeUtc(i) - }).OrderBy(i => i.Size) - .ThenBy(i => i.Name) - .ThenByDescending(i => i.DateModified) - .ThenByDescending(i => i.DateCreated) - .ToArray(); + }) + .OrderBy(i => i.Size) + .ThenBy(i => i.Name) + .ThenByDescending(i => i.DateModified) + .ThenByDescending(i => i.DateCreated); - // max total size 20M - var maxSize = 20971520; - var sizeCounter = 0L; - for (int i = 0; i < result.Length; i++) + // max total size 20M + const int MaxSize = 20971520; + var sizeCounter = 0L; + foreach (var fontFile in fontFiles) + { + sizeCounter += fontFile.Size; + if (sizeCounter >= MaxSize) { - sizeCounter += result[i].Size; - if (sizeCounter >= maxSize) - { - _logger.LogWarning("Some fonts will not be sent due to size limitations"); - Array.Resize(ref result, i); - break; - } + _logger.LogWarning("Some fonts will not be sent due to size limitations"); + yield break; } - return result; - } - catch (Exception ex) - { - _logger.LogError(ex, "Error getting fallback font list"); + yield return fontFile; } } else @@ -413,8 +412,6 @@ namespace Jellyfin.Api.Controllers _logger.LogWarning("The path of fallback font folder has not been set"); encodingOptions.EnableFallbackFont = false; } - - return File(Encoding.UTF8.GetBytes("[]"), MediaTypeNames.Application.Json); } /// @@ -423,12 +420,12 @@ namespace Jellyfin.Api.Controllers /// The name of the fallback font file to get. /// Fallback font file retrieved. /// The fallback font file. - [HttpGet("/FallbackFont/Fonts/{name}")] + [HttpGet("FallbackFont/Fonts/{name}")] [Authorize(Policy = Policies.DefaultAuthorization)] [ProducesResponseType(StatusCodes.Status200OK)] - public ActionResult GetFallbackFont([FromRoute, Required] string? name) + public ActionResult GetFallbackFont([FromRoute, Required] string name) { - var encodingOptions = EncodingConfigurationExtensions.GetEncodingOptions(_serverConfigurationManager); + var encodingOptions = _serverConfigurationManager.GetEncodingOptions(); var fallbackFontPath = encodingOptions.FallbackFontPath; if (!string.IsNullOrEmpty(fallbackFontPath)) @@ -441,7 +438,7 @@ namespace Jellyfin.Api.Controllers if (fontFile != null && fileSize != null && fileSize > 0) { - _logger.LogDebug("Fallback font size is {0} Bytes", fileSize); + _logger.LogDebug("Fallback font size is {fileSize} Bytes", fileSize); FileStream stream = new FileStream(fontFile.FullName, FileMode.Open, FileAccess.Read); return File(stream, MimeTypes.GetMimeType(fontFile.FullName)); From 16658c92fe1baeb23909001525008208cfc82f75 Mon Sep 17 00:00:00 2001 From: Nyanmisaka Date: Thu, 20 Aug 2020 00:08:44 +0800 Subject: [PATCH 08/11] fix SubtitlesOctopus --- .../Controllers/SubtitleController.cs | 41 ++++++------------- 1 file changed, 12 insertions(+), 29 deletions(-) diff --git a/Jellyfin.Api/Controllers/SubtitleController.cs b/Jellyfin.Api/Controllers/SubtitleController.cs index 0795f8f649..6c9d1beecd 100644 --- a/Jellyfin.Api/Controllers/SubtitleController.cs +++ b/Jellyfin.Api/Controllers/SubtitleController.cs @@ -354,14 +354,6 @@ namespace Jellyfin.Api.Controllers CancellationToken.None); } - /// - /// Gets a list of available fallback font files. - /// - /// Information retrieved. - /// An array of with the available font files. - [HttpGet("FallbackFont/Fonts")] - [Authorize(Policy = Policies.DefaultAuthorization)] - [ProducesResponseType(StatusCodes.Status200OK)] /// /// Gets a list of available fallback font files. /// @@ -378,7 +370,6 @@ namespace Jellyfin.Api.Controllers if (!string.IsNullOrEmpty(fallbackFontPath)) { var files = _fileSystem.GetFiles(fallbackFontPath, new[] { ".woff", ".woff2", ".ttf", ".otf" }, false, false); - var fontFiles = files .Select(i => new FontFile { @@ -391,7 +382,6 @@ namespace Jellyfin.Api.Controllers .ThenBy(i => i.Name) .ThenByDescending(i => i.DateModified) .ThenByDescending(i => i.DateCreated); - // max total size 20M const int MaxSize = 20971520; var sizeCounter = 0L; @@ -403,7 +393,6 @@ namespace Jellyfin.Api.Controllers _logger.LogWarning("Some fonts will not be sent due to size limitations"); yield break; } - yield return fontFile; } } @@ -430,27 +419,20 @@ namespace Jellyfin.Api.Controllers if (!string.IsNullOrEmpty(fallbackFontPath)) { - try + var fontFile = _fileSystem.GetFiles(fallbackFontPath) + .First(i => string.Equals(i.Name, name, StringComparison.OrdinalIgnoreCase)); + var fileSize = fontFile?.Length; + + if (fontFile != null && fileSize != null && fileSize > 0) { - var fontFile = _fileSystem.GetFiles(fallbackFontPath) - .First(i => string.Equals(i.Name, name, StringComparison.OrdinalIgnoreCase)); - var fileSize = fontFile?.Length; + _logger.LogDebug("Fallback font size is {fileSize} Bytes", fileSize); - if (fontFile != null && fileSize != null && fileSize > 0) - { - _logger.LogDebug("Fallback font size is {fileSize} Bytes", fileSize); - - FileStream stream = new FileStream(fontFile.FullName, FileMode.Open, FileAccess.Read); - return File(stream, MimeTypes.GetMimeType(fontFile.FullName)); - } - else - { - _logger.LogWarning("The selected font is null or empty"); - } + FileStream stream = new FileStream(fontFile.FullName, FileMode.Open, FileAccess.Read); + return File(stream, MimeTypes.GetMimeType(fontFile.FullName)); } - catch (Exception ex) + else { - _logger.LogError(ex, "Error reading fallback font"); + _logger.LogWarning("The selected font is null or empty"); } } else @@ -459,7 +441,8 @@ namespace Jellyfin.Api.Controllers encodingOptions.EnableFallbackFont = false; } - return File(Encoding.UTF8.GetBytes(string.Empty), MediaTypeNames.Text.Plain); + // returning HTTP 204 will break the SubtitlesOctopus + return Ok(); } } } From dd3b48f2039fe299a55db437190a9e0d5c78145c Mon Sep 17 00:00:00 2001 From: nyanmisaka Date: Thu, 20 Aug 2020 15:17:42 +0800 Subject: [PATCH 09/11] fix lint --- Jellyfin.Api/Controllers/SubtitleController.cs | 3 ++- MediaBrowser.Model/Subtitles/FontFile.cs | 8 ++++---- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/Jellyfin.Api/Controllers/SubtitleController.cs b/Jellyfin.Api/Controllers/SubtitleController.cs index 6c9d1beecd..912de0fd60 100644 --- a/Jellyfin.Api/Controllers/SubtitleController.cs +++ b/Jellyfin.Api/Controllers/SubtitleController.cs @@ -393,6 +393,7 @@ namespace Jellyfin.Api.Controllers _logger.LogWarning("Some fonts will not be sent due to size limitations"); yield break; } + yield return fontFile; } } @@ -425,7 +426,7 @@ namespace Jellyfin.Api.Controllers if (fontFile != null && fileSize != null && fileSize > 0) { - _logger.LogDebug("Fallback font size is {fileSize} Bytes", fileSize); + _logger.LogDebug("Fallback font size is {FileSize} Bytes", fileSize); FileStream stream = new FileStream(fontFile.FullName, FileMode.Open, FileAccess.Read); return File(stream, MimeTypes.GetMimeType(fontFile.FullName)); diff --git a/MediaBrowser.Model/Subtitles/FontFile.cs b/MediaBrowser.Model/Subtitles/FontFile.cs index 13963a9cb5..115c492957 100644 --- a/MediaBrowser.Model/Subtitles/FontFile.cs +++ b/MediaBrowser.Model/Subtitles/FontFile.cs @@ -1,17 +1,17 @@ -#nullable disable -#pragma warning disable CS1591 - using System; namespace MediaBrowser.Model.Subtitles { + /// + /// Class FontFile. + /// public class FontFile { /// /// Gets or sets the name. /// /// The name. - public string Name { get; set; } + public string? Name { get; set; } /// /// Gets or sets the size. From 05e78ee78c56364971956507f6239ded61f0af87 Mon Sep 17 00:00:00 2001 From: Nyanmisaka Date: Thu, 20 Aug 2020 22:53:36 +0800 Subject: [PATCH 10/11] Apply suggestions from code review Co-authored-by: Cody Robibero --- Jellyfin.Api/Controllers/SubtitleController.cs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/Jellyfin.Api/Controllers/SubtitleController.cs b/Jellyfin.Api/Controllers/SubtitleController.cs index 912de0fd60..8550a86e0c 100644 --- a/Jellyfin.Api/Controllers/SubtitleController.cs +++ b/Jellyfin.Api/Controllers/SubtitleController.cs @@ -427,9 +427,7 @@ namespace Jellyfin.Api.Controllers if (fontFile != null && fileSize != null && fileSize > 0) { _logger.LogDebug("Fallback font size is {FileSize} Bytes", fileSize); - - FileStream stream = new FileStream(fontFile.FullName, FileMode.Open, FileAccess.Read); - return File(stream, MimeTypes.GetMimeType(fontFile.FullName)); + return PhysicalFile(fontFile.FullName, MimeTypes.GetMimeType(fontFile.FullName)); } else { From 2229ca38aca0d3007473a52c9560cec0bac8ac05 Mon Sep 17 00:00:00 2001 From: nyanmisaka Date: Sun, 8 Nov 2020 19:33:40 +0800 Subject: [PATCH 11/11] pascal case --- Jellyfin.Api/Controllers/SubtitleController.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Jellyfin.Api/Controllers/SubtitleController.cs b/Jellyfin.Api/Controllers/SubtitleController.cs index 4c9a153840..a01ae31a0e 100644 --- a/Jellyfin.Api/Controllers/SubtitleController.cs +++ b/Jellyfin.Api/Controllers/SubtitleController.cs @@ -459,7 +459,7 @@ namespace Jellyfin.Api.Controllers if (fontFile != null && fileSize != null && fileSize > 0) { - _logger.LogDebug("Fallback font size is {FileSize} Bytes", fileSize); + _logger.LogDebug("Fallback font size is {fileSize} Bytes", fileSize); return PhysicalFile(fontFile.FullName, MimeTypes.GetMimeType(fontFile.FullName)); } else