From 12ec0e285ddf8a5360859b5c49bb4b7b916569d2 Mon Sep 17 00:00:00 2001 From: "Negulici-R. Barnabas" Date: Mon, 18 Jul 2022 17:50:52 +0300 Subject: [PATCH 1/4] Chapter Images: - chapter image extraction intervals, limit count and resolutions can be set by the user from the server general settings; --- .../Encoder/MediaEncoder.cs | 30 ++++++++++++- .../Configuration/ServerConfiguration.cs | 18 ++++++++ MediaBrowser.Model/Drawing/ImageResolution.cs | 43 +++++++++++++++++++ .../MediaInfo/FFProbeVideoInfo.cs | 9 ++-- 4 files changed, 93 insertions(+), 7 deletions(-) create mode 100644 MediaBrowser.Model/Drawing/ImageResolution.cs diff --git a/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs b/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs index 77b97c9b48..5e2d318290 100644 --- a/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs +++ b/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs @@ -51,6 +51,7 @@ namespace MediaBrowser.MediaEncoding.Encoder private readonly IFileSystem _fileSystem; private readonly ILocalizationManager _localization; private readonly IConfiguration _config; + private readonly IServerConfigurationManager _serverConfig; private readonly string _startupOptionFFmpegPath; private readonly SemaphoreSlim _thumbnailResourcePool = new SemaphoreSlim(2, 2); @@ -81,13 +82,15 @@ namespace MediaBrowser.MediaEncoding.Encoder IServerConfigurationManager configurationManager, IFileSystem fileSystem, ILocalizationManager localization, - IConfiguration config) + IConfiguration config, + IServerConfigurationManager serverConfig) { _logger = logger; _configurationManager = configurationManager; _fileSystem = fileSystem; _localization = localization; _config = config; + _serverConfig = serverConfig; _startupOptionFFmpegPath = config.GetValue(Controller.Extensions.ConfigurationExtensions.FfmpegPathKey) ?? string.Empty; _jsonSerializerOptions = JsonDefaults.Options; } @@ -598,6 +601,29 @@ namespace MediaBrowser.MediaEncoding.Encoder _ => ".jpg" }; + bool enumConversionStatus = Enum.TryParse(_serverConfig.Configuration.ChapterImageResolution, out ImageResolution resolution); + var outputResolution = string.Empty; + + if (enumConversionStatus) + { + outputResolution = resolution switch + { + ImageResolution.P240 => "426x240", + ImageResolution.P360 => "640x360", + ImageResolution.P480 => "854x480", + ImageResolution.P720 => "1280x720", + ImageResolution.P1080 => "1920x1080", + ImageResolution.P1440 => "2560x1440", + ImageResolution.P2160 => "3840x2160", + _ => string.Empty + }; + + if (!string.IsNullOrEmpty(outputResolution)) + { + outputResolution = " -s " + outputResolution; + } + } + var tempExtractPath = Path.Combine(_configurationManager.ApplicationPaths.TempDirectory, Guid.NewGuid() + outputExtension); Directory.CreateDirectory(Path.GetDirectoryName(tempExtractPath)); @@ -651,7 +677,7 @@ namespace MediaBrowser.MediaEncoding.Encoder var vf = string.Join(',', filters); var mapArg = imageStreamIndex.HasValue ? (" -map 0:" + imageStreamIndex.Value.ToString(CultureInfo.InvariantCulture)) : string.Empty; - var args = string.Format(CultureInfo.InvariantCulture, "-i {0}{3} -threads {4} -v quiet -vframes 1 -vf {2} -f image2 \"{1}\"", inputPath, tempExtractPath, vf, mapArg, _threads); + var args = string.Format(CultureInfo.InvariantCulture, "-i {0}{3} -threads {4} -v quiet -vframes 1 -vf {2}{5} -f image2 \"{1}\"", inputPath, tempExtractPath, vf, mapArg, _threads, outputResolution); if (offset.HasValue) { diff --git a/MediaBrowser.Model/Configuration/ServerConfiguration.cs b/MediaBrowser.Model/Configuration/ServerConfiguration.cs index e61b896b9d..c37c167eb6 100644 --- a/MediaBrowser.Model/Configuration/ServerConfiguration.cs +++ b/MediaBrowser.Model/Configuration/ServerConfiguration.cs @@ -240,5 +240,23 @@ namespace MediaBrowser.Model.Configuration /// Gets or sets a value indicating whether clients should be allowed to upload logs. /// public bool AllowClientLogUpload { get; set; } = true; + + /// + /// Gets or sets the dummy chapters duration in seconds. + /// + /// The dummy chapters duration. + public int DummyChapterDuration { get; set; } = 300; + + /// + /// Gets or sets the dummy chapter count. + /// + /// The dummy chapter count. + public int DummyChapterCount { get; set; } = 100; + + /// + /// Gets or sets the chapter image resolution. + /// + /// The chapter image resolution. + public string ChapterImageResolution { get; set; } = "Match Source"; } } diff --git a/MediaBrowser.Model/Drawing/ImageResolution.cs b/MediaBrowser.Model/Drawing/ImageResolution.cs new file mode 100644 index 0000000000..7e1c54f5a3 --- /dev/null +++ b/MediaBrowser.Model/Drawing/ImageResolution.cs @@ -0,0 +1,43 @@ +namespace MediaBrowser.Model.Drawing +{ + /// + /// Enum ImageResolution. + /// + public enum ImageResolution + { + /// + /// 240p. + /// + P240, + + /// + /// 360p. + /// + P360, + + /// + /// 480p. + /// + P480, + + /// + /// 720p. + /// + P720, + + /// + /// 1080p. + /// + P1080, + + /// + /// 1440p. + /// + P1440, + + /// + /// 2160p. + /// + P2160 + } +} diff --git a/MediaBrowser.Providers/MediaInfo/FFProbeVideoInfo.cs b/MediaBrowser.Providers/MediaInfo/FFProbeVideoInfo.cs index 8c08ab30ef..c8ff5de69a 100644 --- a/MediaBrowser.Providers/MediaInfo/FFProbeVideoInfo.cs +++ b/MediaBrowser.Providers/MediaInfo/FFProbeVideoInfo.cs @@ -48,8 +48,6 @@ namespace MediaBrowser.Providers.MediaInfo private readonly SubtitleResolver _subtitleResolver; private readonly IMediaSourceManager _mediaSourceManager; - private readonly long _dummyChapterDuration = TimeSpan.FromMinutes(5).Ticks; - public FFProbeVideoInfo( ILogger logger, IMediaSourceManager mediaSourceManager, @@ -651,6 +649,7 @@ namespace MediaBrowser.Providers.MediaInfo private ChapterInfo[] CreateDummyChapters(Video video) { var runtime = video.RunTimeTicks ?? 0; + long dummyChapterDuration = TimeSpan.FromSeconds(_config.Configuration.DummyChapterDuration).Ticks; if (runtime < 0) { @@ -662,13 +661,13 @@ namespace MediaBrowser.Providers.MediaInfo runtime)); } - if (runtime < _dummyChapterDuration) + if (runtime < dummyChapterDuration) { return Array.Empty(); } // Limit to 100 chapters just in case there's some incorrect metadata here - int chapterCount = (int)Math.Min(runtime / _dummyChapterDuration, 100); + int chapterCount = (int)Math.Min(runtime / dummyChapterDuration, _config.Configuration.DummyChapterCount); var chapters = new ChapterInfo[chapterCount]; long currentChapterTicks = 0; @@ -679,7 +678,7 @@ namespace MediaBrowser.Providers.MediaInfo StartPositionTicks = currentChapterTicks }; - currentChapterTicks += _dummyChapterDuration; + currentChapterTicks += dummyChapterDuration; } return chapters; From 7db1813cc8358ac7d4c7a78022553e1e3215679e Mon Sep 17 00:00:00 2001 From: "Negulici-R. Barnabas" Date: Sun, 13 Nov 2022 16:23:21 +0200 Subject: [PATCH 2/4] changed ChapterImageResolution in model to enum type; added 144p to the ImageResolution enum; updated chapters limit comment inside FFProbeVideoInfo.cs; --- .../Encoder/MediaEncoder.cs | 51 ++++++++++--------- .../Configuration/ServerConfiguration.cs | 3 +- MediaBrowser.Model/Drawing/ImageResolution.cs | 10 ++++ .../MediaInfo/FFProbeVideoInfo.cs | 2 +- 4 files changed, 40 insertions(+), 26 deletions(-) diff --git a/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs b/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs index cc6b51f58e..b7c49ed99b 100644 --- a/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs +++ b/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs @@ -609,6 +609,32 @@ namespace MediaBrowser.MediaEncoding.Encoder return await ExtractImageInternal(inputArgument, container, videoStream, imageStreamIndex, threedFormat, offset, false, targetFormat, cancellationToken).ConfigureAwait(false); } + private string GetImageResolutionParameter() + { + string imageResolutionParameter; + + imageResolutionParameter = _serverConfig.Configuration.ChapterImageResolution switch + { + ImageResolution.P144 => "256x144", + ImageResolution.P240 => "426x240", + ImageResolution.P360 => "640x360", + ImageResolution.P480 => "854x480", + ImageResolution.P720 => "1280x720", + ImageResolution.P1080 => "1920x1080", + ImageResolution.P1440 => "2560x1440", + ImageResolution.P2160 => "3840x2160", + _ => string.Empty + }; + + if (!string.IsNullOrEmpty(imageResolutionParameter)) + { + imageResolutionParameter = " -s " + imageResolutionParameter; + } + + return imageResolutionParameter; + } + + private async Task ExtractImageInternal(string inputPath, string container, MediaStream videoStream, int? imageStreamIndex, Video3DFormat? threedFormat, TimeSpan? offset, bool useIFrame, ImageFormat? targetFormat, CancellationToken cancellationToken) { if (string.IsNullOrEmpty(inputPath)) @@ -626,29 +652,6 @@ namespace MediaBrowser.MediaEncoding.Encoder _ => ".jpg" }; - bool enumConversionStatus = Enum.TryParse(_serverConfig.Configuration.ChapterImageResolution, out ImageResolution resolution); - var outputResolution = string.Empty; - - if (enumConversionStatus) - { - outputResolution = resolution switch - { - ImageResolution.P240 => "426x240", - ImageResolution.P360 => "640x360", - ImageResolution.P480 => "854x480", - ImageResolution.P720 => "1280x720", - ImageResolution.P1080 => "1920x1080", - ImageResolution.P1440 => "2560x1440", - ImageResolution.P2160 => "3840x2160", - _ => string.Empty - }; - - if (!string.IsNullOrEmpty(outputResolution)) - { - outputResolution = " -s " + outputResolution; - } - } - var tempExtractPath = Path.Combine(_configurationManager.ApplicationPaths.TempDirectory, Guid.NewGuid() + outputExtension); Directory.CreateDirectory(Path.GetDirectoryName(tempExtractPath)); @@ -702,7 +705,7 @@ namespace MediaBrowser.MediaEncoding.Encoder var vf = string.Join(',', filters); var mapArg = imageStreamIndex.HasValue ? (" -map 0:" + imageStreamIndex.Value.ToString(CultureInfo.InvariantCulture)) : string.Empty; - var args = string.Format(CultureInfo.InvariantCulture, "-i {0}{3} -threads {4} -v quiet -vframes 1 -vf {2}{5} -f image2 \"{1}\"", inputPath, tempExtractPath, vf, mapArg, _threads, outputResolution); + var args = string.Format(CultureInfo.InvariantCulture, "-i {0}{3} -threads {4} -v quiet -vframes 1 -vf {2}{5} -f image2 \"{1}\"", inputPath, tempExtractPath, vf, mapArg, _threads, GetImageResolutionParameter()); if (offset.HasValue) { diff --git a/MediaBrowser.Model/Configuration/ServerConfiguration.cs b/MediaBrowser.Model/Configuration/ServerConfiguration.cs index c37c167eb6..a07ab7121e 100644 --- a/MediaBrowser.Model/Configuration/ServerConfiguration.cs +++ b/MediaBrowser.Model/Configuration/ServerConfiguration.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Generic; +using MediaBrowser.Model.Drawing; using MediaBrowser.Model.Dto; using MediaBrowser.Model.Updates; @@ -257,6 +258,6 @@ namespace MediaBrowser.Model.Configuration /// Gets or sets the chapter image resolution. /// /// The chapter image resolution. - public string ChapterImageResolution { get; set; } = "Match Source"; + public ImageResolution ChapterImageResolution { get; set; } = ImageResolution.MatchSource; } } diff --git a/MediaBrowser.Model/Drawing/ImageResolution.cs b/MediaBrowser.Model/Drawing/ImageResolution.cs index 7e1c54f5a3..99967da45e 100644 --- a/MediaBrowser.Model/Drawing/ImageResolution.cs +++ b/MediaBrowser.Model/Drawing/ImageResolution.cs @@ -5,6 +5,16 @@ namespace MediaBrowser.Model.Drawing /// public enum ImageResolution { + /// + /// MatchSource. + /// + MatchSource, + + /// + /// 144p. + /// + P144, + /// /// 240p. /// diff --git a/MediaBrowser.Providers/MediaInfo/FFProbeVideoInfo.cs b/MediaBrowser.Providers/MediaInfo/FFProbeVideoInfo.cs index c8ff5de69a..686f68c5d7 100644 --- a/MediaBrowser.Providers/MediaInfo/FFProbeVideoInfo.cs +++ b/MediaBrowser.Providers/MediaInfo/FFProbeVideoInfo.cs @@ -666,7 +666,7 @@ namespace MediaBrowser.Providers.MediaInfo return Array.Empty(); } - // Limit to 100 chapters just in case there's some incorrect metadata here + // Limit the chapters just in case there's some incorrect metadata here int chapterCount = (int)Math.Min(runtime / dummyChapterDuration, _config.Configuration.DummyChapterCount); var chapters = new ChapterInfo[chapterCount]; From 2036f58b184e7ae13a0e9564e44daed8d361fbeb Mon Sep 17 00:00:00 2001 From: "Negulici-R. Barnabas" Date: Mon, 14 Nov 2022 16:48:45 +0200 Subject: [PATCH 3/4] added associated value to ImageResolution enum; --- MediaBrowser.Model/Drawing/ImageResolution.cs | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/MediaBrowser.Model/Drawing/ImageResolution.cs b/MediaBrowser.Model/Drawing/ImageResolution.cs index 99967da45e..5834fa4a03 100644 --- a/MediaBrowser.Model/Drawing/ImageResolution.cs +++ b/MediaBrowser.Model/Drawing/ImageResolution.cs @@ -8,46 +8,46 @@ namespace MediaBrowser.Model.Drawing /// /// MatchSource. /// - MatchSource, + MatchSource = 0, /// /// 144p. /// - P144, + P144 = 1, /// /// 240p. /// - P240, + P240 = 2, /// /// 360p. /// - P360, + P360 = 3, /// /// 480p. /// - P480, + P480 = 4, /// /// 720p. /// - P720, + P720 = 5, /// /// 1080p. /// - P1080, + P1080 = 6, /// /// 1440p. /// - P1440, + P1440 = 7, /// /// 2160p. /// - P2160 + P2160 = 8 } } From d3580f25daf7c9512e83c2f4f86494a454143738 Mon Sep 17 00:00:00 2001 From: "Negulici-R. Barnabas" Date: Mon, 14 Nov 2022 16:57:30 +0200 Subject: [PATCH 4/4] fixed namescope for ImageResolution enum; --- MediaBrowser.Model/Drawing/ImageResolution.cs | 81 +++++++++---------- 1 file changed, 40 insertions(+), 41 deletions(-) diff --git a/MediaBrowser.Model/Drawing/ImageResolution.cs b/MediaBrowser.Model/Drawing/ImageResolution.cs index 5834fa4a03..34738b7990 100644 --- a/MediaBrowser.Model/Drawing/ImageResolution.cs +++ b/MediaBrowser.Model/Drawing/ImageResolution.cs @@ -1,53 +1,52 @@ -namespace MediaBrowser.Model.Drawing +namespace MediaBrowser.Model.Drawing; + +/// +/// Enum ImageResolution. +/// +public enum ImageResolution { /// - /// Enum ImageResolution. + /// MatchSource. /// - public enum ImageResolution - { - /// - /// MatchSource. - /// - MatchSource = 0, + MatchSource = 0, - /// - /// 144p. - /// - P144 = 1, + /// + /// 144p. + /// + P144 = 1, - /// - /// 240p. - /// - P240 = 2, + /// + /// 240p. + /// + P240 = 2, - /// - /// 360p. - /// - P360 = 3, + /// + /// 360p. + /// + P360 = 3, - /// - /// 480p. - /// - P480 = 4, + /// + /// 480p. + /// + P480 = 4, - /// - /// 720p. - /// - P720 = 5, + /// + /// 720p. + /// + P720 = 5, - /// - /// 1080p. - /// - P1080 = 6, + /// + /// 1080p. + /// + P1080 = 6, - /// - /// 1440p. - /// - P1440 = 7, + /// + /// 1440p. + /// + P1440 = 7, - /// - /// 2160p. - /// - P2160 = 8 - } + /// + /// 2160p. + /// + P2160 = 8 }