| 
					
				 | 
			
			
				@@ -1,16 +1,18 @@ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 using System;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 using System.Collections.Generic;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+using System.Diagnostics;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 using System.IO;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-using System.Reflection;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-using MediaBrowser.Api.Transcoding;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-using MediaBrowser.Common.Configuration;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+using System.Linq;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+using System.Net;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+using MediaBrowser.Common.Logging;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+using MediaBrowser.Common.Net;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 using MediaBrowser.Common.Net.Handlers;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 using MediaBrowser.Controller;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 using MediaBrowser.Model.Entities;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 namespace MediaBrowser.Api.HttpHandlers
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 {
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    public class AudioHandler : StaticFileHandler
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    public class AudioHandler : BaseHandler
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     {
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         private Audio _LibraryItem;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         /// <summary>
 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -34,68 +36,42 @@ namespace MediaBrowser.Api.HttpHandlers 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             }
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         }
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        public override string Path
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        public override bool CompressResponse
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         {
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             get
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             {
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                return TranscodedPath;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                return false;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             }
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         }
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        private string _TranscodedPath;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        /// <summary>
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        /// Gets the library item that will be played, if any
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        /// </summary>
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        private string TranscodedPath
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        protected override bool IsAsyncHandler
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         {
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             get
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             {
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                if (_TranscodedPath == null)
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                {
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    string originalMediaPath = LibraryItem == null ? base.Path : LibraryItem.Path;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    if (!RequiresTranscoding())
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    {
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                        _TranscodedPath = originalMediaPath;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    }
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    else
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    {
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                        string outputPath = GetOutputFilePath(originalMediaPath);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                        // Find the job in the list
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                        TranscodingJob job = ApiService.GetTranscodingJob(outputPath);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                        if (job == null && !File.Exists(outputPath))
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                        {
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                            job = GetNewTranscodingJob(originalMediaPath, outputPath);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                            job.Start();
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                        }
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                        if (job != null)
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                        {
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                            job.WaitForExit();
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                        }
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                        _TranscodedPath = outputPath;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    }
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                }
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                return true;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            }
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        }
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                return _TranscodedPath;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        public override string ContentType
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        {
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            get
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            {
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                return MimeTypes.GetMimeType("." + GetOutputFormat());
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             }
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         }
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        public string AudioFormat
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        public IEnumerable<string> AudioFormats
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         {
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             get
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             {
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                string val = QueryString["audiobitrate"];
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                string val = QueryString["audioformat"];
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 if (string.IsNullOrEmpty(val))
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 {
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    return "mp3";
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    return new string[] { "mp3" };
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 }
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                return val;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                return val.Split(',');
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             }
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         }
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 
 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -114,7 +90,7 @@ namespace MediaBrowser.Api.HttpHandlers 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             }
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         }
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        public int? NumAudioChannels
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        public int? AudioChannels
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         {
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             get
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             {
 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -144,87 +120,17 @@ namespace MediaBrowser.Api.HttpHandlers 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             }
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         }
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        private static string _StreamsDirectory = null;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        /// <summary>
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        /// Gets the folder path to where transcodes will be cached
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        /// </summary>
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        public static string StreamsDirectory
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        {
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            get
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            {
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                if (_StreamsDirectory == null)
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                {
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    _StreamsDirectory = System.IO.Path.Combine(ApplicationPaths.ProgramDataPath, "streams");
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    if (!Directory.Exists(_StreamsDirectory))
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    {
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                        Directory.CreateDirectory(_StreamsDirectory);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    }
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                }
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                return _StreamsDirectory;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            }
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        }
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        private static string _FFMpegDirectory = null;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        /// <summary>
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        /// Gets the folder path to ffmpeg
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        /// </summary>
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        public static string FFMpegDirectory
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        {
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            get
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            {
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                if (_FFMpegDirectory == null)
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                {
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    _FFMpegDirectory = System.IO.Path.Combine(ApplicationPaths.ProgramDataPath, "ffmpeg");
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    if (!Directory.Exists(_FFMpegDirectory))
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    {
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                        Directory.CreateDirectory(_FFMpegDirectory);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                        // Extract ffmpeg
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                        using (Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("MediaBrowser.Api.ffmpeg.ffmpeg.exe"))
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                        {
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                            using (FileStream fileStream = new FileStream(FFMpegPath, FileMode.Create))
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                            {
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                                stream.CopyTo(fileStream);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                            }
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                        }
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    }
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                }
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                return _FFMpegDirectory;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            }
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        }
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        private static string FFMpegPath
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        public override void ProcessRequest(HttpListenerContext ctx)
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         {
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            get
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            {
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                return System.IO.Path.Combine(FFMpegDirectory, "ffmpeg.exe");
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            }
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        }
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            HttpListenerContext = ctx;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        private string GetOutputFilePath(string input)
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        {
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            string hash = Kernel.GetMD5(input).ToString();
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            if (AudioBitRate.HasValue)
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if (!RequiresTranscoding())
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             {
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                hash += "_ab" + AudioBitRate;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                new StaticFileHandler() { Path = LibraryItem.Path }.ProcessRequest(ctx);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                return;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             }
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            if (NumAudioChannels.HasValue)
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            {
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                hash += "_ac" + NumAudioChannels;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            }
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            if (AudioSampleRate.HasValue)
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            {
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                hash += "_ar" + AudioSampleRate;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            }
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            string filename = hash + "." + AudioFormat.ToLower();
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            return System.IO.Path.Combine(StreamsDirectory, filename);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            base.ProcessRequest(ctx);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         }
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         /// <summary>
 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -232,14 +138,8 @@ namespace MediaBrowser.Api.HttpHandlers 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         /// </summary>
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         private bool RequiresTranscoding()
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         {
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            // Only support skipping transcoding for library items
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            if (LibraryItem == null)
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            {
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                return true;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            }
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            // If it's not in the same format, we need to transcode
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            if (!LibraryItem.Path.EndsWith(AudioFormat, StringComparison.OrdinalIgnoreCase))
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            // If it's not in a format the consumer accepts, return true
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if (!AudioFormats.Any(f => LibraryItem.Path.EndsWith(f, StringComparison.OrdinalIgnoreCase)))
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             {
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 return true;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             }
 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -254,9 +154,9 @@ namespace MediaBrowser.Api.HttpHandlers 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             }
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             // If the number of channels is greater than our desired channels, we need to transcode
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            if (NumAudioChannels.HasValue)
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if (AudioChannels.HasValue)
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             {
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                if (NumAudioChannels.Value < LibraryItem.Channels)
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                if (AudioChannels.Value < LibraryItem.Channels)
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 {
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                     return true;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 }
 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -270,29 +170,27 @@ namespace MediaBrowser.Api.HttpHandlers 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                     return true;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 }
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             }
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             // Yay
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             return false;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         }
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        /// <summary>
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        /// Creates a new transcoding job
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        /// </summary>
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        private TranscodingJob GetNewTranscodingJob(string input, string output)
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        private string GetOutputFormat()
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         {
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            return new TranscodingJob()
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            string format = AudioFormats.FirstOrDefault(f => LibraryItem.Path.EndsWith(f, StringComparison.OrdinalIgnoreCase));
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if (!string.IsNullOrWhiteSpace(format))
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             {
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                InputFile = input,
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                OutputFile = output,
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                TranscoderPath = FFMpegPath,
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                Arguments = GetAudioArguments(input, output)
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            };
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                return format;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            }
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            return AudioFormats.First();
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         }
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         /// <summary>
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         /// Creates arguments to pass to ffmpeg
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         /// </summary>
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        private string GetAudioArguments(string input, string output)
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        private string GetAudioArguments()
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         {
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             List<string> audioTranscodeParams = new List<string>();
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 
 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -301,9 +199,9 @@ namespace MediaBrowser.Api.HttpHandlers 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 audioTranscodeParams.Add("-ab " + AudioBitRate.Value);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             }
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            if (NumAudioChannels.HasValue)
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if (AudioChannels.HasValue)
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             {
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                audioTranscodeParams.Add("-ac " + NumAudioChannels.Value);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                audioTranscodeParams.Add("-ac " + AudioChannels.Value);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             }
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             if (AudioSampleRate.HasValue)
 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -311,9 +209,45 @@ namespace MediaBrowser.Api.HttpHandlers 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 audioTranscodeParams.Add("-ar " + AudioSampleRate.Value);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             }
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            audioTranscodeParams.Add("-f " + AudioFormat);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            audioTranscodeParams.Add("-f " + GetOutputFormat());
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            return "-i \"" + LibraryItem.Path + "\" -vn " + string.Join(" ", audioTranscodeParams.ToArray()) + " -";
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        }
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        protected async override void WriteResponseToOutputStream(Stream stream)
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        {
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            ProcessStartInfo startInfo = new ProcessStartInfo();
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            startInfo.CreateNoWindow = true;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            startInfo.UseShellExecute = false;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            startInfo.RedirectStandardOutput = true;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            return "-i \"" + input + "\" -vn " + string.Join(" ", audioTranscodeParams.ToArray()) + " \"" + output + "\"";
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            startInfo.FileName = ApiService.FFMpegPath;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            startInfo.WorkingDirectory = ApiService.FFMpegDirectory;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            startInfo.Arguments = GetAudioArguments();
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            Logger.LogInfo("Audio Handler Transcode: " + ApiService.FFMpegPath + " " + startInfo.Arguments);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            Process process = new Process();
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            process.StartInfo = startInfo;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            try
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            {
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                process.Start();
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                await process.StandardOutput.BaseStream.CopyToAsync(stream);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            }
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            catch (Exception ex)
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            {
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                Logger.LogException(ex);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            }
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            finally
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            {
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                DisposeResponseStream();
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                process.Dispose();
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            }
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         }
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     }
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 }
 
			 |