diff --git a/MediaBrowser.Api/HttpHandlers/AudioHandler.cs b/MediaBrowser.Api/HttpHandlers/AudioHandler.cs
index 294a5b7afc..51d7ba06ae 100644
--- a/MediaBrowser.Api/HttpHandlers/AudioHandler.cs
+++ b/MediaBrowser.Api/HttpHandlers/AudioHandler.cs
@@ -5,6 +5,7 @@ using System.IO;
using System.Linq;
using System.Net;
using System.Threading.Tasks;
+using MediaBrowser.Common.Configuration;
using MediaBrowser.Common.Logging;
using MediaBrowser.Common.Net;
using MediaBrowser.Common.Net.Handlers;
@@ -241,16 +242,26 @@ namespace MediaBrowser.Api.HttpHandlers
Process process = new Process();
process.StartInfo = startInfo;
+ // FFMpeg writes debug info to StdErr. This is useful when debugging so let's put it in the log directory.
+ FileStream logStream = new FileStream(Path.Combine(ApplicationPaths.LogDirectoryPath, "ffmpeg-" + Guid.NewGuid().ToString() + ".txt"), FileMode.Create);
+
try
{
process.Start();
// MUST read both stdout and stderr asynchronously or a deadlock may occurr
- process.BeginErrorReadLine();
+ // If we ever decide to disable the ffmpeg log then you must uncomment the below line.
+ //process.BeginErrorReadLine();
+
+ Task errorTask = Task.Run(async () => { await process.StandardError.BaseStream.CopyToAsync(logStream); });
await process.StandardOutput.BaseStream.CopyToAsync(stream);
process.WaitForExit();
+
+ await errorTask;
+
+ Logger.LogInfo("FFMpeg exited with code " + process.ExitCode);
}
catch (Exception ex)
{
@@ -258,6 +269,7 @@ namespace MediaBrowser.Api.HttpHandlers
}
finally
{
+ logStream.Dispose();
process.Dispose();
}
}
diff --git a/MediaBrowser.Api/HttpHandlers/VideoHandler.cs b/MediaBrowser.Api/HttpHandlers/VideoHandler.cs
index 1b5c50c38a..0b556b886a 100644
--- a/MediaBrowser.Api/HttpHandlers/VideoHandler.cs
+++ b/MediaBrowser.Api/HttpHandlers/VideoHandler.cs
@@ -54,6 +54,21 @@ namespace MediaBrowser.Api.HttpHandlers
return false;
}
+ private string GetFFMpegOutputFormat(string outputFormat)
+ {
+ if (outputFormat.Equals("mkv", StringComparison.OrdinalIgnoreCase))
+ {
+ return "matroska";
+ }
+
+ return outputFormat;
+ }
+
+ private int GetOutputAudioStreamIndex(string outputFormat)
+ {
+ return 0;
+ }
+
///
/// Creates arguments to pass to ffmpeg
///
@@ -62,8 +77,61 @@ namespace MediaBrowser.Api.HttpHandlers
List audioTranscodeParams = new List();
string outputFormat = GetOutputFormat();
- outputFormat = "matroska";
- return "-i \"" + LibraryItem.Path + "\" -vcodec copy -acodec copy -f " + outputFormat + " -";
+
+ int audioStreamIndex = GetOutputAudioStreamIndex(outputFormat);
+
+ List maps = new List();
+
+ // Add the video stream
+ maps.Add("-map 0:0");
+
+ // Add the audio stream
+ if (audioStreamIndex != -1)
+ {
+ maps.Add("-map 0:" + (1 + audioStreamIndex));
+ }
+
+ // Add all the subtitle streams
+ for (int i = 0; i < LibraryItem.Subtitles.Count(); i++)
+ {
+ maps.Add("-map 0:" + (1 + LibraryItem.AudioStreams.Count() + i));
+
+ }
+
+ return string.Format("-i \"{0}\" {1} {2} {3} -f {4} -",
+ LibraryItem.Path,
+ string.Join(" ", maps.ToArray()),
+ GetVideoArguments(),
+ GetAudioArguments(),
+ GetFFMpegOutputFormat(outputFormat)
+ );
+ }
+
+ private string GetVideoArguments()
+ {
+ return "-c:v copy";
+ }
+
+ private string GetAudioArguments()
+ {
+ return "-c:a copy";
+ }
+
+ private string GetSubtitleArguments()
+ {
+ string args = "";
+
+ for (int i = 0; i < LibraryItem.Subtitles.Count(); i++)
+ {
+ if (i > 0)
+ {
+ args += " ";
+ }
+ args += "-c:s copy";
+
+ }
+
+ return args;
}
}
}