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)