From 21ce0e58c659a976b62e1e0bc0ac37c081f41c58 Mon Sep 17 00:00:00 2001 From: Shadowghost Date: Thu, 31 Mar 2022 02:34:42 +0200 Subject: [PATCH 1/3] Properly handle stream addition and removal for strm use cases --- .../Library/MediaSourceManager.cs | 4 +++- .../MediaEncoding/EncodingHelper.cs | 3 ++- .../MediaInfo/FFProbeVideoInfo.cs | 20 +++++++++++++------ 3 files changed, 19 insertions(+), 8 deletions(-) diff --git a/Emby.Server.Implementations/Library/MediaSourceManager.cs b/Emby.Server.Implementations/Library/MediaSourceManager.cs index d9a1a54872..41f0401615 100644 --- a/Emby.Server.Implementations/Library/MediaSourceManager.cs +++ b/Emby.Server.Implementations/Library/MediaSourceManager.cs @@ -151,7 +151,9 @@ namespace Emby.Server.Implementations.Library { var mediaSources = GetStaticMediaSources(item, enablePathSubstitution, user); - if (allowMediaProbe && mediaSources[0].Type != MediaSourceType.Placeholder && !mediaSources[0].MediaStreams.Any(i => i.Type == MediaStreamType.Audio || i.Type == MediaStreamType.Video)) + if (allowMediaProbe && mediaSources[0].Type != MediaSourceType.Placeholder + && (item.MediaType == MediaType.Video && !mediaSources[0].MediaStreams.Any(i => i.Type == MediaStreamType.Video) + || item.MediaType == MediaType.Audio && !mediaSources[0].MediaStreams.Any(i => i.Type == MediaStreamType.Audio))) { await item.RefreshMetadata( new MetadataRefreshOptions(_directoryService) diff --git a/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs b/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs index 006fd88610..897fd82b48 100644 --- a/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs +++ b/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs @@ -2228,13 +2228,14 @@ namespace MediaBrowser.Controller.MediaEncoding } var args = string.Empty; + var numberOfExternalStreams = state.MediaSource.MediaStreams.Where(stream => stream.IsExternal == true).Count(); if (state.VideoStream != null) { args += string.Format( CultureInfo.InvariantCulture, "-map 0:{0}", - state.VideoStream.Index); + state.VideoStream.Index - numberOfExternalStreams); } else { diff --git a/MediaBrowser.Providers/MediaInfo/FFProbeVideoInfo.cs b/MediaBrowser.Providers/MediaInfo/FFProbeVideoInfo.cs index 4a289b3ab4..6208186ab9 100644 --- a/MediaBrowser.Providers/MediaInfo/FFProbeVideoInfo.cs +++ b/MediaBrowser.Providers/MediaInfo/FFProbeVideoInfo.cs @@ -173,9 +173,22 @@ namespace MediaBrowser.Providers.MediaInfo IReadOnlyList mediaAttachments; ChapterInfo[] chapters; + mediaStreams = new List(); + + // Add external streams before adding the streams from the file to preserve stream IDs on remote videos + await AddExternalSubtitlesAsync(video, mediaStreams, options, cancellationToken).ConfigureAwait(false); + + await AddExternalAudioAsync(video, mediaStreams, options, cancellationToken).ConfigureAwait(false); + if (mediaInfo != null) { - mediaStreams = mediaInfo.MediaStreams.ToList(); + var startIndex = mediaStreams.Count == 0 ? 0 : (mediaStreams.Select(i => i.Index).Max() + 1); + foreach (var mediaStream in mediaInfo.MediaStreams) + { + mediaStream.Index = startIndex++; + mediaStreams.Add(mediaStream); + } + mediaAttachments = mediaInfo.MediaAttachments; video.TotalBitrate = mediaInfo.Bitrate; @@ -213,15 +226,10 @@ namespace MediaBrowser.Providers.MediaInfo } else { - mediaStreams = new List(); mediaAttachments = Array.Empty(); chapters = Array.Empty(); } - await AddExternalSubtitlesAsync(video, mediaStreams, options, cancellationToken).ConfigureAwait(false); - - await AddExternalAudioAsync(video, mediaStreams, options, cancellationToken).ConfigureAwait(false); - var libraryOptions = _libraryManager.GetLibraryOptions(video); if (mediaInfo != null) From 128d54622ad07985688cccf30a897257bf9ea2c2 Mon Sep 17 00:00:00 2001 From: Shadowghost Date: Fri, 1 Apr 2022 02:59:51 +0200 Subject: [PATCH 2/3] Fix stream index and subtitle container handling, preserve attachments and nonexternal streams between scans --- .../Library/MediaSourceManager.cs | 6 ++-- .../MediaEncoding/EncodingHelper.cs | 30 ++++++++++++------- .../MediaEncoding/IMediaEncoder.cs | 7 +++++ .../Encoder/MediaEncoder.cs | 13 ++++++++ .../Subtitles/SubtitleEncoder.cs | 19 ++++++++---- .../MediaInfo/FFProbeVideoInfo.cs | 15 ++++++++-- 6 files changed, 70 insertions(+), 20 deletions(-) diff --git a/Emby.Server.Implementations/Library/MediaSourceManager.cs b/Emby.Server.Implementations/Library/MediaSourceManager.cs index 41f0401615..4af8c9feb5 100644 --- a/Emby.Server.Implementations/Library/MediaSourceManager.cs +++ b/Emby.Server.Implementations/Library/MediaSourceManager.cs @@ -151,9 +151,11 @@ namespace Emby.Server.Implementations.Library { var mediaSources = GetStaticMediaSources(item, enablePathSubstitution, user); + // If file is strm or main media stream is missing, force a metadata refresh with remote probing if (allowMediaProbe && mediaSources[0].Type != MediaSourceType.Placeholder - && (item.MediaType == MediaType.Video && !mediaSources[0].MediaStreams.Any(i => i.Type == MediaStreamType.Video) - || item.MediaType == MediaType.Audio && !mediaSources[0].MediaStreams.Any(i => i.Type == MediaStreamType.Audio))) + && (item.Path.EndsWith(".strm") + || (item.MediaType == MediaType.Video && !mediaSources[0].MediaStreams.Any(i => i.Type == MediaStreamType.Video)) + || (item.MediaType == MediaType.Audio && !mediaSources[0].MediaStreams.Any(i => i.Type == MediaStreamType.Audio)))) { await item.RefreshMetadata( new MetadataRefreshOptions(_directoryService) diff --git a/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs b/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs index 897fd82b48..adac6d280a 100644 --- a/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs +++ b/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs @@ -2228,14 +2228,14 @@ namespace MediaBrowser.Controller.MediaEncoding } var args = string.Empty; - var numberOfExternalStreams = state.MediaSource.MediaStreams.Where(stream => stream.IsExternal == true).Count(); + int videoStreamIndex = state.MediaSource.MediaStreams.Where(i => i.Path == state.VideoStream.Path).ToList().IndexOf(state.VideoStream); if (state.VideoStream != null) { args += string.Format( CultureInfo.InvariantCulture, "-map 0:{0}", - state.VideoStream.Index - numberOfExternalStreams); + videoStreamIndex); } else { @@ -2249,20 +2249,22 @@ namespace MediaBrowser.Controller.MediaEncoding { bool hasExternalGraphicsSubs = state.SubtitleStream != null && state.SubtitleStream.IsExternal && !state.SubtitleStream.IsTextSubtitleStream; int externalAudioMapIndex = hasExternalGraphicsSubs ? 2 : 1; - int externalAudioStream = state.MediaSource.MediaStreams.Where(i => i.Path == state.AudioStream.Path).ToList().IndexOf(state.AudioStream); + int externalAudioStreamIndex = state.MediaSource.MediaStreams.Where(i => i.Path == state.AudioStream.Path).ToList().IndexOf(state.AudioStream); args += string.Format( CultureInfo.InvariantCulture, " -map {0}:{1}", externalAudioMapIndex, - externalAudioStream); + externalAudioStreamIndex); } else { + int subtitleStreamIndex = state.MediaSource.MediaStreams.Where(i => i.Path == state.AudioStream.Path).ToList().IndexOf(state.AudioStream); + args += string.Format( CultureInfo.InvariantCulture, " -map 0:{0}", - state.AudioStream.Index); + subtitleStreamIndex); } } else @@ -2277,14 +2279,21 @@ namespace MediaBrowser.Controller.MediaEncoding } else if (subtitleMethod == SubtitleDeliveryMethod.Embed) { + int subtitleStreamIndex = state.MediaSource.MediaStreams.Where(i => i.Path == state.SubtitleStream.Path).ToList().IndexOf(state.SubtitleStream); + args += string.Format( CultureInfo.InvariantCulture, " -map 0:{0}", - state.SubtitleStream.Index); + subtitleStreamIndex); } else if (state.SubtitleStream.IsExternal && !state.SubtitleStream.IsTextSubtitleStream) { - args += " -map 1:0 -sn"; + int externalSubtitleStreamIndex = state.MediaSource.MediaStreams.Where(i => i.Path == state.SubtitleStream.Path).ToList().IndexOf(state.SubtitleStream); + + args += string.Format( + CultureInfo.InvariantCulture, + " -map 1:{0} -sn", + externalSubtitleStreamIndex); } return args; @@ -4130,9 +4139,8 @@ namespace MediaBrowser.Controller.MediaEncoding string.Join(',', overlayFilters)); var mapPrefix = Convert.ToInt32(state.SubtitleStream.IsExternal); - var subtitleStreamIndex = state.SubtitleStream.IsExternal - ? 0 - : state.SubtitleStream.Index; + var subtitleStreamIndex = state.MediaSource.MediaStreams.Where(i => i.Path == state.SubtitleStream.Path).ToList().IndexOf(state.SubtitleStream); + var videoStreamIndex = state.MediaSource.MediaStreams.Where(i => i.Path == state.VideoStream.Path).ToList().IndexOf(state.VideoStream); if (hasSubs) { @@ -4153,7 +4161,7 @@ namespace MediaBrowser.Controller.MediaEncoding filterStr, mapPrefix, subtitleStreamIndex, - state.VideoStream.Index, + videoStreamIndex, mainStr, subStr, overlayStr); diff --git a/MediaBrowser.Controller/MediaEncoding/IMediaEncoder.cs b/MediaBrowser.Controller/MediaEncoding/IMediaEncoder.cs index 6bf3e7b469..dae30cd8b3 100644 --- a/MediaBrowser.Controller/MediaEncoding/IMediaEncoder.cs +++ b/MediaBrowser.Controller/MediaEncoding/IMediaEncoder.cs @@ -141,6 +141,13 @@ namespace MediaBrowser.Controller.MediaEncoding /// System.String. string GetInputArgument(string inputFile, MediaSourceInfo mediaSource); + /// + /// Gets the input argument for an external subtitle file. + /// + /// The input file. + /// System.String. + string GetExternalSubtitleInputArgument(string inputFile); + /// /// Gets the time parameter. /// diff --git a/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs b/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs index c796ee7806..7e5d7a25f8 100644 --- a/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs +++ b/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs @@ -411,6 +411,19 @@ namespace MediaBrowser.MediaEncoding.Encoder return EncodingUtils.GetInputArgument(prefix, inputFile, mediaSource.Protocol); } + /// + /// Gets the input argument for an external subtitle file. + /// + /// The input file. + /// System.String. + /// Unrecognized InputType. + public string GetExternalSubtitleInputArgument(string inputFile) + { + var prefix = "file"; + + return EncodingUtils.GetInputArgument(prefix, inputFile, MediaProtocol.File); + } + /// /// Gets the media info internal. /// diff --git a/MediaBrowser.MediaEncoding/Subtitles/SubtitleEncoder.cs b/MediaBrowser.MediaEncoding/Subtitles/SubtitleEncoder.cs index f4842d3682..717624279a 100644 --- a/MediaBrowser.MediaEncoding/Subtitles/SubtitleEncoder.cs +++ b/MediaBrowser.MediaEncoding/Subtitles/SubtitleEncoder.cs @@ -195,7 +195,7 @@ namespace MediaBrowser.MediaEncoding.Subtitles MediaStream subtitleStream, CancellationToken cancellationToken) { - if (!subtitleStream.IsExternal) + if (!subtitleStream.IsExternal || subtitleStream.Path.EndsWith(".mks")) { string outputFormat; string outputCodec; @@ -224,7 +224,7 @@ namespace MediaBrowser.MediaEncoding.Subtitles // Extract var outputPath = GetSubtitleCachePath(mediaSource, subtitleStream.Index, "." + outputFormat); - await ExtractTextSubtitle(mediaSource, subtitleStream.Index, outputCodec, outputPath, cancellationToken) + await ExtractTextSubtitle(mediaSource, subtitleStream, outputCodec, outputPath, cancellationToken) .ConfigureAwait(false); return new SubtitleInfo(outputPath, MediaProtocol.File, outputFormat, false); @@ -494,7 +494,7 @@ namespace MediaBrowser.MediaEncoding.Subtitles /// Extracts the text subtitle. /// /// The mediaSource. - /// Index of the subtitle stream. + /// The subtitle stream. /// The output codec. /// The output path. /// The cancellation token. @@ -502,7 +502,7 @@ namespace MediaBrowser.MediaEncoding.Subtitles /// Must use inputPath list overload. private async Task ExtractTextSubtitle( MediaSourceInfo mediaSource, - int subtitleStreamIndex, + MediaStream subtitleStream, string outputCodec, string outputPath, CancellationToken cancellationToken) @@ -511,12 +511,21 @@ namespace MediaBrowser.MediaEncoding.Subtitles await semaphore.WaitAsync(cancellationToken).ConfigureAwait(false); + var subtitleStreamIndex = mediaSource.MediaStreams.Where(i => i.Path == subtitleStream.Path).ToList().IndexOf(subtitleStream); + try { if (!File.Exists(outputPath)) { + var args = _mediaEncoder.GetInputArgument(mediaSource.Path, mediaSource); + + if (subtitleStream.IsExternal) + { + args = _mediaEncoder.GetExternalSubtitleInputArgument(subtitleStream.Path); + } + await ExtractTextSubtitleInternal( - _mediaEncoder.GetInputArgument(mediaSource.Path, mediaSource), + args, subtitleStreamIndex, outputCodec, outputPath, diff --git a/MediaBrowser.Providers/MediaInfo/FFProbeVideoInfo.cs b/MediaBrowser.Providers/MediaInfo/FFProbeVideoInfo.cs index 6208186ab9..c9f7870483 100644 --- a/MediaBrowser.Providers/MediaInfo/FFProbeVideoInfo.cs +++ b/MediaBrowser.Providers/MediaInfo/FFProbeVideoInfo.cs @@ -180,9 +180,10 @@ namespace MediaBrowser.Providers.MediaInfo await AddExternalAudioAsync(video, mediaStreams, options, cancellationToken).ConfigureAwait(false); + var startIndex = mediaStreams.Count == 0 ? 0 : (mediaStreams.Select(i => i.Index).Max() + 1); + if (mediaInfo != null) { - var startIndex = mediaStreams.Count == 0 ? 0 : (mediaStreams.Select(i => i.Index).Max() + 1); foreach (var mediaStream in mediaInfo.MediaStreams) { mediaStream.Index = startIndex++; @@ -226,6 +227,12 @@ namespace MediaBrowser.Providers.MediaInfo } else { + var nonExternalMediaStreams = video.GetMediaStreams().Where(i => !i.IsExternal); + foreach (var mediaStream in nonExternalMediaStreams) + { + mediaStream.Index = startIndex++; + mediaStreams.Add(mediaStream); + } mediaAttachments = Array.Empty(); chapters = Array.Empty(); } @@ -262,7 +269,11 @@ namespace MediaBrowser.Providers.MediaInfo video.HasSubtitles = mediaStreams.Any(i => i.Type == MediaStreamType.Subtitle); _itemRepo.SaveMediaStreams(video.Id, mediaStreams, cancellationToken); - _itemRepo.SaveMediaAttachments(video.Id, mediaAttachments, cancellationToken); + + if (mediaAttachments.Any()) + { + _itemRepo.SaveMediaAttachments(video.Id, mediaAttachments, cancellationToken); + } if (options.MetadataRefreshMode == MetadataRefreshMode.FullRefresh || options.MetadataRefreshMode == MetadataRefreshMode.Default) From a4e4b761d5d17d7d17c04096bd0f825f9cbc7bf1 Mon Sep 17 00:00:00 2001 From: Shadowghost Date: Sat, 2 Apr 2022 02:55:42 +0200 Subject: [PATCH 3/3] Apply review suggestions --- .../Data/SqliteItemRepository.cs | 6 +-- .../Library/MediaSourceManager.cs | 6 +-- .../MediaEncoding/EncodingHelper.cs | 45 ++++++++++++++----- .../Encoder/MediaEncoder.cs | 4 +- .../Subtitles/SubtitleEncoder.cs | 4 +- .../MediaInfo/FFProbeVideoInfo.cs | 16 ++++--- 6 files changed, 53 insertions(+), 28 deletions(-) diff --git a/Emby.Server.Implementations/Data/SqliteItemRepository.cs b/Emby.Server.Implementations/Data/SqliteItemRepository.cs index 5729a70ace..cdc14c2605 100644 --- a/Emby.Server.Implementations/Data/SqliteItemRepository.cs +++ b/Emby.Server.Implementations/Data/SqliteItemRepository.cs @@ -5763,7 +5763,7 @@ AND Type = @InternalPersonType)"); { var itemIdBlob = id.ToByteArray(); - // First delete chapters + // Delete existing mediastreams db.Execute("delete from mediastreams where ItemId=@ItemId", itemIdBlob); InsertMediaStreams(itemIdBlob, streams, db); @@ -5867,10 +5867,10 @@ AND Type = @InternalPersonType)"); } /// - /// Gets the chapter. + /// Gets the media stream. /// /// The reader. - /// ChapterInfo. + /// MediaStream. private MediaStream GetMediaStream(IReadOnlyList reader) { var item = new MediaStream diff --git a/Emby.Server.Implementations/Library/MediaSourceManager.cs b/Emby.Server.Implementations/Library/MediaSourceManager.cs index 4af8c9feb5..c0aef18997 100644 --- a/Emby.Server.Implementations/Library/MediaSourceManager.cs +++ b/Emby.Server.Implementations/Library/MediaSourceManager.cs @@ -153,9 +153,9 @@ namespace Emby.Server.Implementations.Library // If file is strm or main media stream is missing, force a metadata refresh with remote probing if (allowMediaProbe && mediaSources[0].Type != MediaSourceType.Placeholder - && (item.Path.EndsWith(".strm") - || (item.MediaType == MediaType.Video && !mediaSources[0].MediaStreams.Any(i => i.Type == MediaStreamType.Video)) - || (item.MediaType == MediaType.Audio && !mediaSources[0].MediaStreams.Any(i => i.Type == MediaStreamType.Audio)))) + && (item.Path.EndsWith(".strm", StringComparison.OrdinalIgnoreCase) + || (item.MediaType == MediaType.Video && !mediaSources[0].MediaStreams.Any(i => i.Type == MediaStreamType.Video)) + || (item.MediaType == MediaType.Audio && !mediaSources[0].MediaStreams.Any(i => i.Type == MediaStreamType.Audio)))) { await item.RefreshMetadata( new MetadataRefreshOptions(_directoryService) diff --git a/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs b/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs index adac6d280a..1851a9f0c5 100644 --- a/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs +++ b/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs @@ -2215,23 +2215,24 @@ namespace MediaBrowser.Controller.MediaEncoding return state.IsInputVideo ? "-sn" : string.Empty; } - // We have media info, but we don't know the stream indexes + // We have media info, but we don't know the stream index if (state.VideoStream != null && state.VideoStream.Index == -1) { return "-sn"; } - // We have media info, but we don't know the stream indexes + // We have media info, but we don't know the stream index if (state.AudioStream != null && state.AudioStream.Index == -1) { return state.IsInputVideo ? "-sn" : string.Empty; } var args = string.Empty; - int videoStreamIndex = state.MediaSource.MediaStreams.Where(i => i.Path == state.VideoStream.Path).ToList().IndexOf(state.VideoStream); if (state.VideoStream != null) { + int videoStreamIndex = FindIndex(state.MediaSource.MediaStreams, state.VideoStream); + args += string.Format( CultureInfo.InvariantCulture, "-map 0:{0}", @@ -2245,26 +2246,24 @@ namespace MediaBrowser.Controller.MediaEncoding if (state.AudioStream != null) { + int audioStreamIndex = FindIndex(state.MediaSource.MediaStreams, state.AudioStream); if (state.AudioStream.IsExternal) { bool hasExternalGraphicsSubs = state.SubtitleStream != null && state.SubtitleStream.IsExternal && !state.SubtitleStream.IsTextSubtitleStream; int externalAudioMapIndex = hasExternalGraphicsSubs ? 2 : 1; - int externalAudioStreamIndex = state.MediaSource.MediaStreams.Where(i => i.Path == state.AudioStream.Path).ToList().IndexOf(state.AudioStream); args += string.Format( CultureInfo.InvariantCulture, " -map {0}:{1}", externalAudioMapIndex, - externalAudioStreamIndex); + audioStreamIndex); } else { - int subtitleStreamIndex = state.MediaSource.MediaStreams.Where(i => i.Path == state.AudioStream.Path).ToList().IndexOf(state.AudioStream); - args += string.Format( CultureInfo.InvariantCulture, " -map 0:{0}", - subtitleStreamIndex); + audioStreamIndex); } } else @@ -2279,7 +2278,7 @@ namespace MediaBrowser.Controller.MediaEncoding } else if (subtitleMethod == SubtitleDeliveryMethod.Embed) { - int subtitleStreamIndex = state.MediaSource.MediaStreams.Where(i => i.Path == state.SubtitleStream.Path).ToList().IndexOf(state.SubtitleStream); + int subtitleStreamIndex = FindIndex(state.MediaSource.MediaStreams, state.SubtitleStream); args += string.Format( CultureInfo.InvariantCulture, @@ -2288,7 +2287,7 @@ namespace MediaBrowser.Controller.MediaEncoding } else if (state.SubtitleStream.IsExternal && !state.SubtitleStream.IsTextSubtitleStream) { - int externalSubtitleStreamIndex = state.MediaSource.MediaStreams.Where(i => i.Path == state.SubtitleStream.Path).ToList().IndexOf(state.SubtitleStream); + int externalSubtitleStreamIndex = FindIndex(state.MediaSource.MediaStreams, state.SubtitleStream); args += string.Format( CultureInfo.InvariantCulture, @@ -4139,8 +4138,8 @@ namespace MediaBrowser.Controller.MediaEncoding string.Join(',', overlayFilters)); var mapPrefix = Convert.ToInt32(state.SubtitleStream.IsExternal); - var subtitleStreamIndex = state.MediaSource.MediaStreams.Where(i => i.Path == state.SubtitleStream.Path).ToList().IndexOf(state.SubtitleStream); - var videoStreamIndex = state.MediaSource.MediaStreams.Where(i => i.Path == state.VideoStream.Path).ToList().IndexOf(state.VideoStream); + var subtitleStreamIndex = FindIndex(state.MediaSource.MediaStreams, state.SubtitleStream); + var videoStreamIndex = FindIndex(state.MediaSource.MediaStreams, state.VideoStream); if (hasSubs) { @@ -5398,6 +5397,28 @@ namespace MediaBrowser.Controller.MediaEncoding string.Empty).Trim(); } + public static int FindIndex(IReadOnlyList mediaStreams, MediaStream streamToFind) + { + var index = 0; + var length = mediaStreams.Count; + + for (var i = 0; i < length; i++) + { + var currentMediaStream = mediaStreams[i]; + if (currentMediaStream == streamToFind) + { + return index; + } + + if (string.Equals(currentMediaStream.Path, streamToFind.Path, StringComparison.Ordinal)) + { + index++; + } + } + + return -1; + } + public static bool IsCopyCodec(string codec) { return string.Equals(codec, "copy", StringComparison.OrdinalIgnoreCase); diff --git a/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs b/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs index 7e5d7a25f8..1bac4b1875 100644 --- a/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs +++ b/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs @@ -419,9 +419,9 @@ namespace MediaBrowser.MediaEncoding.Encoder /// Unrecognized InputType. public string GetExternalSubtitleInputArgument(string inputFile) { - var prefix = "file"; + const string Prefix = "file"; - return EncodingUtils.GetInputArgument(prefix, inputFile, MediaProtocol.File); + return EncodingUtils.GetInputArgument(Prefix, inputFile, MediaProtocol.File); } /// diff --git a/MediaBrowser.MediaEncoding/Subtitles/SubtitleEncoder.cs b/MediaBrowser.MediaEncoding/Subtitles/SubtitleEncoder.cs index 717624279a..f6b7efb1e9 100644 --- a/MediaBrowser.MediaEncoding/Subtitles/SubtitleEncoder.cs +++ b/MediaBrowser.MediaEncoding/Subtitles/SubtitleEncoder.cs @@ -195,7 +195,7 @@ namespace MediaBrowser.MediaEncoding.Subtitles MediaStream subtitleStream, CancellationToken cancellationToken) { - if (!subtitleStream.IsExternal || subtitleStream.Path.EndsWith(".mks")) + if (!subtitleStream.IsExternal || subtitleStream.Path.EndsWith(".mks", StringComparison.OrdinalIgnoreCase)) { string outputFormat; string outputCodec; @@ -511,7 +511,7 @@ namespace MediaBrowser.MediaEncoding.Subtitles await semaphore.WaitAsync(cancellationToken).ConfigureAwait(false); - var subtitleStreamIndex = mediaSource.MediaStreams.Where(i => i.Path == subtitleStream.Path).ToList().IndexOf(subtitleStream); + var subtitleStreamIndex = EncodingHelper.FindIndex(mediaSource.MediaStreams, subtitleStream); try { diff --git a/MediaBrowser.Providers/MediaInfo/FFProbeVideoInfo.cs b/MediaBrowser.Providers/MediaInfo/FFProbeVideoInfo.cs index c9f7870483..8c08ab30ef 100644 --- a/MediaBrowser.Providers/MediaInfo/FFProbeVideoInfo.cs +++ b/MediaBrowser.Providers/MediaInfo/FFProbeVideoInfo.cs @@ -180,7 +180,7 @@ namespace MediaBrowser.Providers.MediaInfo await AddExternalAudioAsync(video, mediaStreams, options, cancellationToken).ConfigureAwait(false); - var startIndex = mediaStreams.Count == 0 ? 0 : (mediaStreams.Select(i => i.Index).Max() + 1); + var startIndex = mediaStreams.Count == 0 ? 0 : (mediaStreams.Max(i => i.Index) + 1); if (mediaInfo != null) { @@ -196,7 +196,7 @@ namespace MediaBrowser.Providers.MediaInfo // video.FormatName = (mediaInfo.Container ?? string.Empty) // .Replace("matroska", "mkv", StringComparison.OrdinalIgnoreCase); - // For dvd's this may not always be accurate, so don't set the runtime if the item already has one + // For DVDs this may not always be accurate, so don't set the runtime if the item already has one var needToSetRuntime = video.VideoType != VideoType.Dvd || video.RunTimeTicks == null || video.RunTimeTicks.Value == 0; if (needToSetRuntime) @@ -227,12 +227,16 @@ namespace MediaBrowser.Providers.MediaInfo } else { - var nonExternalMediaStreams = video.GetMediaStreams().Where(i => !i.IsExternal); - foreach (var mediaStream in nonExternalMediaStreams) + var currentMediaStreams = video.GetMediaStreams(); + foreach (var mediaStream in currentMediaStreams) { - mediaStream.Index = startIndex++; - mediaStreams.Add(mediaStream); + if (!mediaStream.IsExternal) + { + mediaStream.Index = startIndex++; + mediaStreams.Add(mediaStream); + } } + mediaAttachments = Array.Empty(); chapters = Array.Empty(); }