diff options
Diffstat (limited to 'MediaBrowser.Api/HttpHandlers/AudioHandler.cs')
| -rw-r--r-- | MediaBrowser.Api/HttpHandlers/AudioHandler.cs | 230 |
1 files changed, 82 insertions, 148 deletions
diff --git a/MediaBrowser.Api/HttpHandlers/AudioHandler.cs b/MediaBrowser.Api/HttpHandlers/AudioHandler.cs index 76a48308b..5bfbfd1a4 100644 --- a/MediaBrowser.Api/HttpHandlers/AudioHandler.cs +++ b/MediaBrowser.Api/HttpHandlers/AudioHandler.cs @@ -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();
+ }
}
}
}
|
