Browse Source

More video handler improvements

LukePulverenti Luke Pulverenti luke pulverenti 13 years ago
parent
commit
a05a947fcf
1 changed files with 101 additions and 8 deletions
  1. 101 8
      MediaBrowser.Api/HttpHandlers/VideoHandler.cs

+ 101 - 8
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;
         }
 
+        /// <summary>
+        /// Translates the file extension to the format param that follows "-f" on the ffmpeg command line
+        /// </summary>
         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)
+        {
+            string codec = GetVideoCodec(outputFormat);
+
+            string args = "-vcodec " + codec;
+
+            return args;
+        }
+
+        private string GetAudioArguments(string outputFormat)
+        {
+            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)
         {
-            return "-vcodec copy";
+            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 string GetAudioArguments()
+        private int? GetNumAudioChannels(string audioCodec)
         {
-            return "-acodec copy";
+            if (audioCodec.Equals("libvo_aacenc"))
+            {
+                // libvo_aacenc currently only supports two channel output
+                return 2;
+            }
+            
+            return AudioChannels;
         }
     }
 }