diff --git a/MediaBrowser.Api/HttpHandlers/VideoHandler.cs b/MediaBrowser.Api/HttpHandlers/VideoHandler.cs index d8e06194d9..18060fcb0a 100644 --- a/MediaBrowser.Api/HttpHandlers/VideoHandler.cs +++ b/MediaBrowser.Api/HttpHandlers/VideoHandler.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Linq; using MediaBrowser.Model.Entities; +using System.IO; namespace MediaBrowser.Api.HttpHandlers { @@ -17,12 +18,21 @@ namespace MediaBrowser.Api.HttpHandlers { get { - return new string[] { "mp4", "wmv" }; + return new string[] { "mp4", "wmv", "3gp", "avi", "ogv", "mov", "m4v", "mkv" }; } } protected override bool RequiresConversion() { + string currentFormat = Path.GetExtension(LibraryItem.Path).Replace(".", string.Empty); + + // For now we won't allow these to pass through. + // Later we'll add some intelligence to allow it when possible + if (currentFormat.Equals("mkv", StringComparison.OrdinalIgnoreCase) || currentFormat.Equals("m4v", StringComparison.OrdinalIgnoreCase)) + { + return true; + } + if (base.RequiresConversion()) { return true; @@ -43,6 +53,9 @@ namespace MediaBrowser.Api.HttpHandlers return false; } + /// + /// Translates the file extension to the format param that follows "-f" on the ffmpeg command line + /// private string GetFFMpegOutputFormat(string outputFormat) { if (outputFormat.Equals("mkv", StringComparison.OrdinalIgnoreCase)) @@ -70,22 +83,102 @@ namespace MediaBrowser.Api.HttpHandlers string outputFormat = GetConversionOutputFormat(); - return string.Format("-i \"{0}\" {1} {2} -f {3} -", + return string.Format("-i \"{0}\" -threads 0 {1} {2} -f {3} -", LibraryItem.Path, - GetVideoArguments(), - GetAudioArguments(), + GetVideoArguments(outputFormat), + GetAudioArguments(outputFormat), GetFFMpegOutputFormat(outputFormat) ); } - private string GetVideoArguments() + private string GetVideoArguments(string outputFormat) { - return "-vcodec copy"; + string codec = GetVideoCodec(outputFormat); + + string args = "-vcodec " + codec; + + return args; } - private string GetAudioArguments() + private string GetAudioArguments(string outputFormat) { - return "-acodec copy"; + string codec = GetAudioCodec(outputFormat); + + string args = "-acodec " + codec; + + if (!codec.Equals("copy", StringComparison.OrdinalIgnoreCase)) + { + int? channels = GetNumAudioChannels(codec); + + if (channels.HasValue) + { + args += " -ac " + channels.Value; + } + if (AudioSampleRate.HasValue) + { + args += " -ar " + AudioSampleRate.Value; + } + + } + + return args; + } + + private string GetVideoCodec(string outputFormat) + { + if (outputFormat.Equals("webm")) + { + // Per webm specification, it must be vpx + return "libvpx"; + } + else if (outputFormat.Equals("flv")) + { + return "libx264"; + } + else if (outputFormat.Equals("ts")) + { + return "libx264"; + } + else if (outputFormat.Equals("asf")) + { + return "wmv2"; + } + + return "copy"; + } + + private string GetAudioCodec(string outputFormat) + { + if (outputFormat.Equals("webm")) + { + // Per webm specification, it must be vorbis + return "libvorbis"; + } + else if (outputFormat.Equals("flv")) + { + return "libvo_aacenc"; + } + else if (outputFormat.Equals("ts")) + { + return "libvo_aacenc"; + } + else if (outputFormat.Equals("asf")) + { + return "libvo_aacenc"; + } + + return "copy"; + } + + private int? GetNumAudioChannels(string audioCodec) + { + if (audioCodec.Equals("libvo_aacenc")) + { + // libvo_aacenc currently only supports two channel output + return 2; + } + + return AudioChannels; } } }