123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319 |
- using System;
- using System.Collections.Generic;
- using System.IO;
- using System.Reflection;
- using MediaBrowser.Api.Transcoding;
- using MediaBrowser.Common.Configuration;
- using MediaBrowser.Common.Net.Handlers;
- using MediaBrowser.Controller;
- using MediaBrowser.Model.Entities;
- namespace MediaBrowser.Api.HttpHandlers
- {
- public class AudioHandler : StaticFileHandler
- {
- private Audio _LibraryItem;
- /// <summary>
- /// Gets the library item that will be played, if any
- /// </summary>
- private Audio LibraryItem
- {
- get
- {
- if (_LibraryItem == null)
- {
- string id = QueryString["id"];
- if (!string.IsNullOrEmpty(id))
- {
- _LibraryItem = Kernel.Instance.GetItemById(Guid.Parse(id)) as Audio;
- }
- }
- return _LibraryItem;
- }
- }
- public override string Path
- {
- get
- {
- return TranscodedPath;
- }
- }
- private string _TranscodedPath;
- /// <summary>
- /// Gets the library item that will be played, if any
- /// </summary>
- private string TranscodedPath
- {
- 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 _TranscodedPath;
- }
- }
- public string AudioFormat
- {
- get
- {
- string val = QueryString["audiobitrate"];
- if (string.IsNullOrEmpty(val))
- {
- return "mp3";
- }
- return val;
- }
- }
- public int? AudioBitRate
- {
- get
- {
- string val = QueryString["audiobitrate"];
- if (string.IsNullOrEmpty(val))
- {
- return null;
- }
- return int.Parse(val);
- }
- }
- public int? NumAudioChannels
- {
- get
- {
- string val = QueryString["audiochannels"];
- if (string.IsNullOrEmpty(val))
- {
- return null;
- }
- return int.Parse(val);
- }
- }
- public int? AudioSampleRate
- {
- get
- {
- string val = QueryString["audiosamplerate"];
- if (string.IsNullOrEmpty(val))
- {
- return 44100;
- }
- return int.Parse(val);
- }
- }
- 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
- {
- get
- {
- return System.IO.Path.Combine(FFMpegDirectory, "ffmpeg.exe");
- }
- }
- private string GetOutputFilePath(string input)
- {
- string hash = Kernel.GetMD5(input).ToString();
- if (AudioBitRate.HasValue)
- {
- hash += "_ab" + AudioBitRate;
- }
- if (NumAudioChannels.HasValue)
- {
- hash += "_ac" + NumAudioChannels;
- }
- if (AudioSampleRate.HasValue)
- {
- hash += "_ar" + AudioSampleRate;
- }
- string filename = hash + "." + AudioFormat.ToLower();
- return System.IO.Path.Combine(StreamsDirectory, filename);
- }
- /// <summary>
- /// Determines whether or not the original file requires transcoding
- /// </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))
- {
- return true;
- }
- // If the bitrate is greater than our desired bitrate, we need to transcode
- if (AudioBitRate.HasValue)
- {
- if (AudioBitRate.Value < LibraryItem.BitRate)
- {
- return true;
- }
- }
- // If the number of channels is greater than our desired channels, we need to transcode
- if (NumAudioChannels.HasValue)
- {
- if (NumAudioChannels.Value < LibraryItem.Channels)
- {
- return true;
- }
- }
- // If the sample rate is greater than our desired sample rate, we need to transcode
- if (AudioSampleRate.HasValue)
- {
- if (AudioSampleRate.Value < LibraryItem.SampleRate)
- {
- return true;
- }
- }
-
- // Yay
- return false;
- }
- /// <summary>
- /// Creates a new transcoding job
- /// </summary>
- private TranscodingJob GetNewTranscodingJob(string input, string output)
- {
- return new TranscodingJob()
- {
- InputFile = input,
- OutputFile = output,
- TranscoderPath = FFMpegPath,
- Arguments = GetAudioArguments(input, output)
- };
- }
- /// <summary>
- /// Creates arguments to pass to ffmpeg
- /// </summary>
- private string GetAudioArguments(string input, string output)
- {
- List<string> audioTranscodeParams = new List<string>();
- if (AudioBitRate.HasValue)
- {
- audioTranscodeParams.Add("-ab " + AudioBitRate.Value);
- }
- if (NumAudioChannels.HasValue)
- {
- audioTranscodeParams.Add("-ac " + NumAudioChannels.Value);
- }
- if (AudioSampleRate.HasValue)
- {
- audioTranscodeParams.Add("-ar " + AudioSampleRate.Value);
- }
- audioTranscodeParams.Add("-f " + AudioFormat);
- return "-i \"" + input + "\" -vn " + string.Join(" ", audioTranscodeParams.ToArray()) + " \"" + output + "\"";
- }
- }
- }
|