From 658a454d81ae99e1e860dee9d0e89e617bc2e610 Mon Sep 17 00:00:00 2001 From: gnattu Date: Thu, 18 Apr 2024 00:44:04 +0800 Subject: fix: don't extract external sub (#11373) --- MediaBrowser.MediaEncoding/Subtitles/SubtitleEncoder.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'MediaBrowser.MediaEncoding/Subtitles/SubtitleEncoder.cs') diff --git a/MediaBrowser.MediaEncoding/Subtitles/SubtitleEncoder.cs b/MediaBrowser.MediaEncoding/Subtitles/SubtitleEncoder.cs index 4b1b1bbc61..21f4cb1cd6 100644 --- a/MediaBrowser.MediaEncoding/Subtitles/SubtitleEncoder.cs +++ b/MediaBrowser.MediaEncoding/Subtitles/SubtitleEncoder.cs @@ -463,7 +463,7 @@ namespace MediaBrowser.MediaEncoding.Subtitles try { var subtitleStreams = mediaSource.MediaStreams - .Where(stream => stream.IsTextSubtitleStream && stream.SupportsExternalStream); + .Where(stream => stream is { IsTextSubtitleStream: true, SupportsExternalStream: true, IsExternal: false }); foreach (var subtitleStream in subtitleStreams) { -- cgit v1.2.3 From af74aa35d76435f5bd01aeec77f406376b3b8c28 Mon Sep 17 00:00:00 2001 From: Mark Cilia Vincenti Date: Mon, 6 May 2024 03:21:54 +0200 Subject: Clean up synchronization (#11458) --- .../Attachments/AttachmentExtractor.cs | 14 +++++--------- MediaBrowser.MediaEncoding/Subtitles/SubtitleEncoder.cs | 14 +++++--------- 2 files changed, 10 insertions(+), 18 deletions(-) (limited to 'MediaBrowser.MediaEncoding/Subtitles/SubtitleEncoder.cs') diff --git a/MediaBrowser.MediaEncoding/Attachments/AttachmentExtractor.cs b/MediaBrowser.MediaEncoding/Attachments/AttachmentExtractor.cs index a11440ced2..3b7745b6a1 100644 --- a/MediaBrowser.MediaEncoding/Attachments/AttachmentExtractor.cs +++ b/MediaBrowser.MediaEncoding/Attachments/AttachmentExtractor.cs @@ -247,7 +247,7 @@ namespace MediaBrowser.MediaEncoding.Attachments MediaSourceInfo mediaSource, CancellationToken cancellationToken) { - var outputFileLocks = new List>(); + var outputFileLocks = new List(); var extractableAttachmentIds = new List(); try @@ -256,16 +256,15 @@ namespace MediaBrowser.MediaEncoding.Attachments { var outputPath = GetAttachmentCachePath(mediaPath, mediaSource, attachment.Index); - var @outputFileLock = _semaphoreLocks.GetOrAdd(outputPath); - await @outputFileLock.SemaphoreSlim.WaitAsync(cancellationToken).ConfigureAwait(false); + var releaser = await _semaphoreLocks.LockAsync(outputPath, cancellationToken).ConfigureAwait(false); if (File.Exists(outputPath)) { - @outputFileLock.Dispose(); + releaser.Dispose(); continue; } - outputFileLocks.Add(@outputFileLock); + outputFileLocks.Add(releaser); extractableAttachmentIds.Add(attachment.Index); } @@ -280,10 +279,7 @@ namespace MediaBrowser.MediaEncoding.Attachments } finally { - foreach (var @outputFileLock in outputFileLocks) - { - @outputFileLock.Dispose(); - } + outputFileLocks.ForEach(x => x.Dispose()); } } diff --git a/MediaBrowser.MediaEncoding/Subtitles/SubtitleEncoder.cs b/MediaBrowser.MediaEncoding/Subtitles/SubtitleEncoder.cs index 21f4cb1cd6..16837d98bd 100644 --- a/MediaBrowser.MediaEncoding/Subtitles/SubtitleEncoder.cs +++ b/MediaBrowser.MediaEncoding/Subtitles/SubtitleEncoder.cs @@ -457,7 +457,7 @@ namespace MediaBrowser.MediaEncoding.Subtitles /// Task. private async Task ExtractAllTextSubtitles(MediaSourceInfo mediaSource, CancellationToken cancellationToken) { - var locks = new List>(); + var locks = new List(); var extractableStreams = new List(); try @@ -469,16 +469,15 @@ namespace MediaBrowser.MediaEncoding.Subtitles { var outputPath = GetSubtitleCachePath(mediaSource, subtitleStream.Index, "." + GetTextSubtitleFormat(subtitleStream)); - var @lock = _semaphoreLocks.GetOrAdd(outputPath); - await @lock.SemaphoreSlim.WaitAsync(cancellationToken).ConfigureAwait(false); + var releaser = await _semaphoreLocks.LockAsync(outputPath, cancellationToken).ConfigureAwait(false); if (File.Exists(outputPath)) { - @lock.Dispose(); + releaser.Dispose(); continue; } - locks.Add(@lock); + locks.Add(releaser); extractableStreams.Add(subtitleStream); } @@ -493,10 +492,7 @@ namespace MediaBrowser.MediaEncoding.Subtitles } finally { - foreach (var @lock in locks) - { - @lock.Dispose(); - } + locks.ForEach(x => x.Dispose()); } } -- cgit v1.2.3 From fc1bee30a62e2e31682809c8245a117f7ecbddd5 Mon Sep 17 00:00:00 2001 From: David Schulte Date: Mon, 15 Jul 2024 14:48:09 +0200 Subject: Allow streaming of raw PGS subtitles without transcoding (#12056) --- .../Library/MediaSourceManager.cs | 5 ++ .../Subtitles/SubtitleEncoder.cs | 54 ++++++++++++++++------ MediaBrowser.Model/Entities/MediaStream.cs | 33 +++++++++++++ 3 files changed, 79 insertions(+), 13 deletions(-) (limited to 'MediaBrowser.MediaEncoding/Subtitles/SubtitleEncoder.cs') diff --git a/Emby.Server.Implementations/Library/MediaSourceManager.cs b/Emby.Server.Implementations/Library/MediaSourceManager.cs index 5ec333cb16..bb22ca82fa 100644 --- a/Emby.Server.Implementations/Library/MediaSourceManager.cs +++ b/Emby.Server.Implementations/Library/MediaSourceManager.cs @@ -113,6 +113,11 @@ namespace Emby.Server.Implementations.Library return true; } + if (stream.IsPgsSubtitleStream) + { + return true; + } + return false; } diff --git a/MediaBrowser.MediaEncoding/Subtitles/SubtitleEncoder.cs b/MediaBrowser.MediaEncoding/Subtitles/SubtitleEncoder.cs index 16837d98bd..9ecbfa9cf5 100644 --- a/MediaBrowser.MediaEncoding/Subtitles/SubtitleEncoder.cs +++ b/MediaBrowser.MediaEncoding/Subtitles/SubtitleEncoder.cs @@ -198,10 +198,11 @@ namespace MediaBrowser.MediaEncoding.Subtitles { if (!subtitleStream.IsExternal || subtitleStream.Path.EndsWith(".mks", StringComparison.OrdinalIgnoreCase)) { - await ExtractAllTextSubtitles(mediaSource, cancellationToken).ConfigureAwait(false); + await ExtractAllExtractableSubtitles(mediaSource, cancellationToken).ConfigureAwait(false); - var outputFormat = GetTextSubtitleFormat(subtitleStream); - var outputPath = GetSubtitleCachePath(mediaSource, subtitleStream.Index, "." + outputFormat); + var outputFileExtension = GetExtractableSubtitleFileExtension(subtitleStream); + var outputFormat = GetExtractableSubtitleFormat(subtitleStream); + var outputPath = GetSubtitleCachePath(mediaSource, subtitleStream.Index, "." + outputFileExtension); return new SubtitleInfo() { @@ -215,6 +216,18 @@ namespace MediaBrowser.MediaEncoding.Subtitles var currentFormat = (Path.GetExtension(subtitleStream.Path) ?? subtitleStream.Codec) .TrimStart('.'); + // Handle PGS subtitles as raw streams for the client to render + if (MediaStream.IsPgsFormat(currentFormat)) + { + return new SubtitleInfo() + { + Path = subtitleStream.Path, + Protocol = _mediaSourceManager.GetPathProtocol(subtitleStream.Path), + Format = "pgssub", + IsExternal = true + }; + } + // Fallback to ffmpeg conversion if (!_subtitleParser.SupportsFileExtension(currentFormat)) { @@ -428,10 +441,11 @@ namespace MediaBrowser.MediaEncoding.Subtitles _logger.LogInformation("ffmpeg subtitle conversion succeeded for {Path}", inputPath); } - private string GetTextSubtitleFormat(MediaStream subtitleStream) + private string GetExtractableSubtitleFormat(MediaStream subtitleStream) { if (string.Equals(subtitleStream.Codec, "ass", StringComparison.OrdinalIgnoreCase) - || string.Equals(subtitleStream.Codec, "ssa", StringComparison.OrdinalIgnoreCase)) + || string.Equals(subtitleStream.Codec, "ssa", StringComparison.OrdinalIgnoreCase) + || string.Equals(subtitleStream.Codec, "pgssub", StringComparison.OrdinalIgnoreCase)) { return subtitleStream.Codec; } @@ -441,21 +455,35 @@ namespace MediaBrowser.MediaEncoding.Subtitles } } + private string GetExtractableSubtitleFileExtension(MediaStream subtitleStream) + { + // Using .pgssub as file extension is not allowed by ffmpeg. The file extension for pgs subtitles is .sup. + if (string.Equals(subtitleStream.Codec, "pgssub", StringComparison.OrdinalIgnoreCase)) + { + return "sup"; + } + else + { + return GetExtractableSubtitleFormat(subtitleStream); + } + } + private bool IsCodecCopyable(string codec) { return string.Equals(codec, "ass", StringComparison.OrdinalIgnoreCase) || string.Equals(codec, "ssa", StringComparison.OrdinalIgnoreCase) || string.Equals(codec, "srt", StringComparison.OrdinalIgnoreCase) - || string.Equals(codec, "subrip", StringComparison.OrdinalIgnoreCase); + || string.Equals(codec, "subrip", StringComparison.OrdinalIgnoreCase) + || string.Equals(codec, "pgssub", StringComparison.OrdinalIgnoreCase); } /// - /// Extracts all text subtitles. + /// Extracts all extractable subtitles (text and pgs). /// /// The mediaSource. /// The cancellation token. /// Task. - private async Task ExtractAllTextSubtitles(MediaSourceInfo mediaSource, CancellationToken cancellationToken) + private async Task ExtractAllExtractableSubtitles(MediaSourceInfo mediaSource, CancellationToken cancellationToken) { var locks = new List(); var extractableStreams = new List(); @@ -463,11 +491,11 @@ namespace MediaBrowser.MediaEncoding.Subtitles try { var subtitleStreams = mediaSource.MediaStreams - .Where(stream => stream is { IsTextSubtitleStream: true, SupportsExternalStream: true, IsExternal: false }); + .Where(stream => stream is { IsExtractableSubtitleStream: true, SupportsExternalStream: true, IsExternal: false }); foreach (var subtitleStream in subtitleStreams) { - var outputPath = GetSubtitleCachePath(mediaSource, subtitleStream.Index, "." + GetTextSubtitleFormat(subtitleStream)); + var outputPath = GetSubtitleCachePath(mediaSource, subtitleStream.Index, "." + GetExtractableSubtitleFileExtension(subtitleStream)); var releaser = await _semaphoreLocks.LockAsync(outputPath, cancellationToken).ConfigureAwait(false); @@ -483,7 +511,7 @@ namespace MediaBrowser.MediaEncoding.Subtitles if (extractableStreams.Count > 0) { - await ExtractAllTextSubtitlesInternal(mediaSource, extractableStreams, cancellationToken).ConfigureAwait(false); + await ExtractAllExtractableSubtitlesInternal(mediaSource, extractableStreams, cancellationToken).ConfigureAwait(false); } } catch (Exception ex) @@ -496,7 +524,7 @@ namespace MediaBrowser.MediaEncoding.Subtitles } } - private async Task ExtractAllTextSubtitlesInternal( + private async Task ExtractAllExtractableSubtitlesInternal( MediaSourceInfo mediaSource, List subtitleStreams, CancellationToken cancellationToken) @@ -510,7 +538,7 @@ namespace MediaBrowser.MediaEncoding.Subtitles foreach (var subtitleStream in subtitleStreams) { - var outputPath = GetSubtitleCachePath(mediaSource, subtitleStream.Index, "." + GetTextSubtitleFormat(subtitleStream)); + var outputPath = GetSubtitleCachePath(mediaSource, subtitleStream.Index, "." + GetExtractableSubtitleFileExtension(subtitleStream)); var outputCodec = IsCodecCopyable(subtitleStream.Codec) ? "copy" : "srt"; var streamIndex = EncodingHelper.FindIndex(mediaSource.MediaStreams, subtitleStream); diff --git a/MediaBrowser.Model/Entities/MediaStream.cs b/MediaBrowser.Model/Entities/MediaStream.cs index e1082adead..9044c0524e 100644 --- a/MediaBrowser.Model/Entities/MediaStream.cs +++ b/MediaBrowser.Model/Entities/MediaStream.cs @@ -585,6 +585,31 @@ namespace MediaBrowser.Model.Entities } } + public bool IsPgsSubtitleStream + { + get + { + if (Type != MediaStreamType.Subtitle) + { + return false; + } + + if (string.IsNullOrEmpty(Codec) && !IsExternal) + { + return false; + } + + return IsPgsFormat(Codec); + } + } + + /// + /// Gets a value indicating whether this is a subtitle steam that is extractable by ffmpeg. + /// All text-based and pgs subtitles can be extracted. + /// + /// true if this is a extractable subtitle steam otherwise, false. + public bool IsExtractableSubtitleStream => IsTextSubtitleStream || IsPgsSubtitleStream; + /// /// Gets or sets a value indicating whether [supports external stream]. /// @@ -666,6 +691,14 @@ namespace MediaBrowser.Model.Entities && !string.Equals(codec, "sub", StringComparison.OrdinalIgnoreCase)); } + public static bool IsPgsFormat(string format) + { + string codec = format ?? string.Empty; + + return codec.Contains("pgs", StringComparison.OrdinalIgnoreCase) + || string.Equals(codec, "sup", StringComparison.OrdinalIgnoreCase); + } + public bool SupportsSubtitleConversionTo(string toCodec) { if (!IsTextSubtitleStream) -- cgit v1.2.3