diff options
Diffstat (limited to 'MediaBrowser.MediaEncoding/Encoder')
7 files changed, 1 insertions, 1015 deletions
diff --git a/MediaBrowser.MediaEncoding/Encoder/AudioEncoder.cs b/MediaBrowser.MediaEncoding/Encoder/AudioEncoder.cs deleted file mode 100644 index 08b7fbe49..000000000 --- a/MediaBrowser.MediaEncoding/Encoder/AudioEncoder.cs +++ /dev/null @@ -1,91 +0,0 @@ -using MediaBrowser.Common.Configuration; -using MediaBrowser.Common.IO; -using MediaBrowser.Controller.LiveTv; -using MediaBrowser.Model.IO; -using MediaBrowser.Model.Logging; -using System.Collections.Generic; -using System.Globalization; -using System.Threading.Tasks; - -namespace MediaBrowser.MediaEncoding.Encoder -{ - public class AudioEncoder - { - private readonly string _ffmpegPath; - private readonly ILogger _logger; - private readonly IFileSystem _fileSystem; - private readonly IApplicationPaths _appPaths; - private readonly IIsoManager _isoManager; - private readonly ILiveTvManager _liveTvManager; - - private readonly CultureInfo _usCulture = new CultureInfo("en-US"); - - public AudioEncoder(string ffmpegPath, ILogger logger, IFileSystem fileSystem, IApplicationPaths appPaths, IIsoManager isoManager, ILiveTvManager liveTvManager) - { - _ffmpegPath = ffmpegPath; - _logger = logger; - _fileSystem = fileSystem; - _appPaths = appPaths; - _isoManager = isoManager; - _liveTvManager = liveTvManager; - } - - public Task BeginEncoding(InternalEncodingTask task) - { - return new FFMpegProcess(_ffmpegPath, _logger, _fileSystem, _appPaths, _isoManager, _liveTvManager).Start(task, GetArguments); - } - - private string GetArguments(InternalEncodingTask task, string mountedPath) - { - var options = task.Request; - - return string.Format("{0} -i {1} {2} -id3v2_version 3 -write_id3v1 1 \"{3}\"", - GetInputModifier(task), - GetInputArgument(task), - GetOutputModifier(task), - options.OutputPath).Trim(); - } - - private string GetInputModifier(InternalEncodingTask task) - { - return EncodingUtils.GetInputModifier(task); - } - - private string GetInputArgument(InternalEncodingTask task) - { - return EncodingUtils.GetInputArgument(new List<string> { task.MediaPath }, task.IsInputRemote); - } - - private string GetOutputModifier(InternalEncodingTask task) - { - var options = task.Request; - - var audioTranscodeParams = new List<string> - { - "-threads " + EncodingUtils.GetNumberOfThreads(task, false).ToString(_usCulture), - "-vn" - }; - - var bitrate = EncodingUtils.GetAudioBitrateParam(task); - - if (bitrate.HasValue) - { - audioTranscodeParams.Add("-ab " + bitrate.Value.ToString(_usCulture)); - } - - var channels = EncodingUtils.GetNumAudioChannelsParam(options, task.AudioStream); - - if (channels.HasValue) - { - audioTranscodeParams.Add("-ac " + channels.Value); - } - - if (options.AudioSampleRate.HasValue) - { - audioTranscodeParams.Add("-ar " + options.AudioSampleRate.Value); - } - - return string.Join(" ", audioTranscodeParams.ToArray()); - } - } -} diff --git a/MediaBrowser.MediaEncoding/Encoder/EncodingUtils.cs b/MediaBrowser.MediaEncoding/Encoder/EncodingUtils.cs index 231651856..9bd2e9270 100644 --- a/MediaBrowser.MediaEncoding/Encoder/EncodingUtils.cs +++ b/MediaBrowser.MediaEncoding/Encoder/EncodingUtils.cs @@ -64,77 +64,6 @@ namespace MediaBrowser.MediaEncoding.Encoder return string.Format("\"{0}\"", url); } - public static string GetAudioInputModifier(InternalEncodingTask options) - { - return GetCommonInputModifier(options); - } - - public static string GetInputModifier(InternalEncodingTask options) - { - var inputModifier = GetCommonInputModifier(options); - - //if (state.VideoRequest != null) - //{ - // inputModifier += " -fflags genpts"; - //} - - //if (!string.IsNullOrEmpty(state.InputVideoCodec)) - //{ - // inputModifier += " -vcodec " + state.InputVideoCodec; - //} - - //if (!string.IsNullOrEmpty(state.InputVideoSync)) - //{ - // inputModifier += " -vsync " + state.InputVideoSync; - //} - - return inputModifier; - } - - private static string GetCommonInputModifier(InternalEncodingTask options) - { - var inputModifier = string.Empty; - - if (options.EnableDebugLogging) - { - inputModifier += "-loglevel debug"; - } - - var probeSize = GetProbeSizeArgument(options.InputVideoType.HasValue && options.InputVideoType.Value == VideoType.Dvd); - inputModifier += " " + probeSize; - inputModifier = inputModifier.Trim(); - - if (!string.IsNullOrWhiteSpace(options.UserAgent)) - { - inputModifier += " -user-agent \"" + options.UserAgent + "\""; - } - - inputModifier += " " + GetFastSeekValue(options.Request); - inputModifier = inputModifier.Trim(); - - if (!string.IsNullOrEmpty(options.InputFormat)) - { - inputModifier += " -f " + options.InputFormat; - } - - if (!string.IsNullOrEmpty(options.InputAudioCodec)) - { - inputModifier += " -acodec " + options.InputAudioCodec; - } - - if (!string.IsNullOrEmpty(options.InputAudioSync)) - { - inputModifier += " -async " + options.InputAudioSync; - } - - if (options.ReadInputAtNativeFramerate) - { - inputModifier += " -re"; - } - - return inputModifier; - } - private static string GetFastSeekValue(EncodingOptions options) { var time = options.StartTimeTicks; @@ -157,19 +86,6 @@ namespace MediaBrowser.MediaEncoding.Encoder return isDvd ? "-probesize 1G -analyzeduration 200M" : string.Empty; } - public static int? GetAudioBitrateParam(InternalEncodingTask task) - { - if (task.Request.AudioBitRate.HasValue) - { - // Make sure we don't request a bitrate higher than the source - var currentBitrate = task.AudioStream == null ? task.Request.AudioBitRate.Value : task.AudioStream.BitRate ?? task.Request.AudioBitRate.Value; - - return Math.Min(currentBitrate, task.Request.AudioBitRate.Value); - } - - return null; - } - /// <summary> /// Gets the number of audio channels to specify on the command line /// </summary> @@ -201,35 +117,5 @@ namespace MediaBrowser.MediaEncoding.Encoder return request.AudioChannels; } - - public static int GetNumberOfThreads(InternalEncodingTask state, bool isWebm) - { - // Use more when this is true. -re will keep cpu usage under control - if (state.ReadInputAtNativeFramerate) - { - if (isWebm) - { - return Math.Max(Environment.ProcessorCount - 1, 2); - } - - return 0; - } - - // Webm: http://www.webmproject.org/docs/encoder-parameters/ - // The decoder will usually automatically use an appropriate number of threads according to how many cores are available but it can only use multiple threads - // for the coefficient data if the encoder selected --token-parts > 0 at encode time. - - switch (state.QualitySetting) - { - case EncodingQuality.HighSpeed: - return 2; - case EncodingQuality.HighQuality: - return 2; - case EncodingQuality.MaxQuality: - return isWebm ? Math.Max(Environment.ProcessorCount - 1, 2) : 0; - default: - throw new Exception("Unrecognized MediaEncodingQuality value."); - } - } } } diff --git a/MediaBrowser.MediaEncoding/Encoder/FFMpegProcess.cs b/MediaBrowser.MediaEncoding/Encoder/FFMpegProcess.cs deleted file mode 100644 index 05733aef0..000000000 --- a/MediaBrowser.MediaEncoding/Encoder/FFMpegProcess.cs +++ /dev/null @@ -1,168 +0,0 @@ -using MediaBrowser.Common.Configuration; -using MediaBrowser.Common.IO; -using MediaBrowser.Controller.LiveTv; -using MediaBrowser.Model.Entities; -using MediaBrowser.Model.IO; -using MediaBrowser.Model.Logging; -using System; -using System.Diagnostics; -using System.IO; -using System.Threading; -using System.Threading.Tasks; - -namespace MediaBrowser.MediaEncoding.Encoder -{ - public class FFMpegProcess : IDisposable - { - private readonly string _ffmpegPath; - private readonly ILogger _logger; - private readonly IFileSystem _fileSystem; - private readonly IApplicationPaths _appPaths; - private readonly IIsoManager _isoManager; - private readonly ILiveTvManager _liveTvManager; - - private Stream _logFileStream; - private InternalEncodingTask _task; - private IIsoMount _isoMount; - - public FFMpegProcess(string ffmpegPath, ILogger logger, IFileSystem fileSystem, IApplicationPaths appPaths, IIsoManager isoManager, ILiveTvManager liveTvManager) - { - _ffmpegPath = ffmpegPath; - _logger = logger; - _fileSystem = fileSystem; - _appPaths = appPaths; - _isoManager = isoManager; - _liveTvManager = liveTvManager; - } - - public async Task Start(InternalEncodingTask task, Func<InternalEncodingTask,string,string> argumentsFactory) - { - _task = task; - if (!File.Exists(_ffmpegPath)) - { - throw new InvalidOperationException("ffmpeg was not found at " + _ffmpegPath); - } - - Directory.CreateDirectory(Path.GetDirectoryName(task.Request.OutputPath)); - - string mountedPath = null; - if (task.InputVideoType.HasValue && task.InputVideoType == VideoType.Iso && task.IsoType.HasValue) - { - if (_isoManager.CanMount(task.MediaPath)) - { - _isoMount = await _isoManager.Mount(task.MediaPath, CancellationToken.None).ConfigureAwait(false); - mountedPath = _isoMount.MountedPath; - } - } - - var process = new Process - { - StartInfo = new ProcessStartInfo - { - CreateNoWindow = true, - UseShellExecute = false, - - // Must consume both stdout and stderr or deadlocks may occur - RedirectStandardOutput = true, - RedirectStandardError = true, - - FileName = _ffmpegPath, - WorkingDirectory = Path.GetDirectoryName(_ffmpegPath), - Arguments = argumentsFactory(task, mountedPath), - - WindowStyle = ProcessWindowStyle.Hidden, - ErrorDialog = false - }, - - EnableRaisingEvents = true - }; - - _logger.Info(process.StartInfo.FileName + " " + process.StartInfo.Arguments); - - var logFilePath = Path.Combine(_appPaths.LogDirectoryPath, "ffmpeg-" + task.Id + ".txt"); - Directory.CreateDirectory(Path.GetDirectoryName(logFilePath)); - - // FFMpeg writes debug/error info to stderr. This is useful when debugging so let's put it in the log directory. - _logFileStream = _fileSystem.GetFileStream(logFilePath, FileMode.Create, FileAccess.Write, FileShare.Read, true); - - process.Exited += process_Exited; - - try - { - process.Start(); - } - catch (Exception ex) - { - _logger.ErrorException("Error starting ffmpeg", ex); - - task.OnError(); - - DisposeLogFileStream(); - - process.Dispose(); - - throw; - } - - task.OnBegin(); - - // MUST read both stdout and stderr asynchronously or a deadlock may occurr - process.BeginOutputReadLine(); - -#pragma warning disable 4014 - // Important - don't await the log task or we won't be able to kill ffmpeg when the user stops playback - process.StandardError.BaseStream.CopyToAsync(_logFileStream); -#pragma warning restore 4014 - } - - async void process_Exited(object sender, EventArgs e) - { - var process = (Process)sender; - - if (_isoMount != null) - { - _isoMount.Dispose(); - _isoMount = null; - } - - DisposeLogFileStream(); - - try - { - _logger.Info("FFMpeg exited with code {0} for {1}", process.ExitCode, _task.Request.OutputPath); - } - catch - { - _logger.Info("FFMpeg exited with an error for {0}", _task.Request.OutputPath); - } - - _task.OnCompleted(); - - if (!string.IsNullOrEmpty(_task.LiveTvStreamId)) - { - try - { - await _liveTvManager.CloseLiveStream(_task.LiveTvStreamId, CancellationToken.None).ConfigureAwait(false); - } - catch (Exception ex) - { - _logger.ErrorException("Error closing live tv stream", ex); - } - } - } - - public void Dispose() - { - DisposeLogFileStream(); - } - - private void DisposeLogFileStream() - { - if (_logFileStream != null) - { - _logFileStream.Dispose(); - _logFileStream = null; - } - } - } -} diff --git a/MediaBrowser.MediaEncoding/Encoder/ImageEncoder.cs b/MediaBrowser.MediaEncoding/Encoder/ImageEncoder.cs deleted file mode 100644 index e0ca86c41..000000000 --- a/MediaBrowser.MediaEncoding/Encoder/ImageEncoder.cs +++ /dev/null @@ -1,235 +0,0 @@ -using MediaBrowser.Common.Configuration; -using MediaBrowser.Common.IO; -using MediaBrowser.Controller.MediaEncoding; -using MediaBrowser.Model.Logging; -using System; -using System.Diagnostics; -using System.Globalization; -using System.IO; -using System.Linq; -using System.Text; -using System.Threading; -using System.Threading.Tasks; - -namespace MediaBrowser.MediaEncoding.Encoder -{ - public class ImageEncoder - { - private readonly string _ffmpegPath; - private readonly ILogger _logger; - private readonly IFileSystem _fileSystem; - private readonly IApplicationPaths _appPaths; - - private readonly CultureInfo _usCulture = new CultureInfo("en-US"); - - private static readonly SemaphoreSlim ResourcePool = new SemaphoreSlim(10, 10); - - public ImageEncoder(string ffmpegPath, ILogger logger, IFileSystem fileSystem, IApplicationPaths appPaths) - { - _ffmpegPath = ffmpegPath; - _logger = logger; - _fileSystem = fileSystem; - _appPaths = appPaths; - } - - public async Task<Stream> EncodeImage(ImageEncodingOptions options, CancellationToken cancellationToken) - { - ValidateInput(options); - - await ResourcePool.WaitAsync(cancellationToken).ConfigureAwait(false); - - try - { - return await EncodeImageInternal(options, cancellationToken).ConfigureAwait(false); - } - finally - { - ResourcePool.Release(); - } - } - - private async Task<Stream> EncodeImageInternal(ImageEncodingOptions options, CancellationToken cancellationToken) - { - ValidateInput(options); - - var inputPath = options.InputPath; - var filename = Path.GetFileName(inputPath); - - if (HasDiacritics(filename)) - { - inputPath = GetTempFile(inputPath); - filename = Path.GetFileName(inputPath); - } - - var process = new Process - { - StartInfo = new ProcessStartInfo - { - CreateNoWindow = true, - UseShellExecute = false, - FileName = _ffmpegPath, - Arguments = GetArguments(options, filename), - WindowStyle = ProcessWindowStyle.Hidden, - ErrorDialog = false, - RedirectStandardOutput = true, - RedirectStandardError = true, - WorkingDirectory = Path.GetDirectoryName(inputPath) - } - }; - - _logger.Debug("ffmpeg " + process.StartInfo.Arguments); - - process.Start(); - - var memoryStream = new MemoryStream(); - -#pragma warning disable 4014 - // Important - don't await the log task or we won't be able to kill ffmpeg when the user stops playback - process.StandardOutput.BaseStream.CopyToAsync(memoryStream); -#pragma warning restore 4014 - - // MUST read both stdout and stderr asynchronously or a deadlock may occurr - process.BeginErrorReadLine(); - - var ranToCompletion = process.WaitForExit(5000); - - if (!ranToCompletion) - { - try - { - _logger.Info("Killing ffmpeg process"); - - process.Kill(); - - process.WaitForExit(1000); - } - catch (Exception ex) - { - _logger.ErrorException("Error killing process", ex); - } - } - - var exitCode = ranToCompletion ? process.ExitCode : -1; - - process.Dispose(); - - if (exitCode == -1 || memoryStream.Length == 0) - { - memoryStream.Dispose(); - - var msg = string.Format("ffmpeg image encoding failed for {0}", options.InputPath); - - _logger.Error(msg); - - throw new ApplicationException(msg); - } - - memoryStream.Position = 0; - return memoryStream; - } - - private string GetTempFile(string path) - { - var extension = Path.GetExtension(path) ?? string.Empty; - - var tempPath = Path.Combine(_appPaths.TempDirectory, Guid.NewGuid().ToString("N") + extension); - - File.Copy(path, tempPath); - - return tempPath; - } - - private string GetArguments(ImageEncodingOptions options, string inputFilename) - { - var vfScale = GetFilterGraph(options); - var outputFormat = GetOutputFormat(options.Format); - - var quality = (options.Quality ?? 100) * .3; - quality = 31 - quality; - var qualityValue = Convert.ToInt32(Math.Max(quality, 1)); - - return string.Format("-f image2 -i file:\"{3}\" -q:v {0} {1} -f image2pipe -vcodec {2} -", - qualityValue.ToString(_usCulture), - vfScale, - outputFormat, - inputFilename); - } - - private string GetFilterGraph(ImageEncodingOptions options) - { - if (!options.Width.HasValue && - !options.Height.HasValue && - !options.MaxHeight.HasValue && - !options.MaxWidth.HasValue) - { - return string.Empty; - } - - var widthScale = "-1"; - var heightScale = "-1"; - - if (options.MaxWidth.HasValue) - { - widthScale = "min(iw\\," + options.MaxWidth.Value.ToString(_usCulture) + ")"; - } - else if (options.Width.HasValue) - { - widthScale = options.Width.Value.ToString(_usCulture); - } - - if (options.MaxHeight.HasValue) - { - heightScale = "min(ih\\," + options.MaxHeight.Value.ToString(_usCulture) + ")"; - } - else if (options.Height.HasValue) - { - heightScale = options.Height.Value.ToString(_usCulture); - } - - var scaleMethod = "lanczos"; - - return string.Format("-vf scale=\"{0}:{1}\"", - widthScale, - heightScale); - } - - private string GetOutputFormat(string format) - { - if (string.Equals(format, "jpeg", StringComparison.OrdinalIgnoreCase) || - string.Equals(format, "jpg", StringComparison.OrdinalIgnoreCase)) - { - return "mjpeg"; - } - return format; - } - - private void ValidateInput(ImageEncodingOptions options) - { - - } - - /// <summary> - /// Determines whether the specified text has diacritics. - /// </summary> - /// <param name="text">The text.</param> - /// <returns><c>true</c> if the specified text has diacritics; otherwise, <c>false</c>.</returns> - private bool HasDiacritics(string text) - { - return !String.Equals(text, RemoveDiacritics(text), StringComparison.Ordinal); - } - - /// <summary> - /// Removes the diacritics. - /// </summary> - /// <param name="text">The text.</param> - /// <returns>System.String.</returns> - private string RemoveDiacritics(string text) - { - return String.Concat( - text.Normalize(NormalizationForm.FormD) - .Where(ch => CharUnicodeInfo.GetUnicodeCategory(ch) != - UnicodeCategory.NonSpacingMark) - ).Normalize(NormalizationForm.FormC); - } - } -} diff --git a/MediaBrowser.MediaEncoding/Encoder/InternalEncodingTask.cs b/MediaBrowser.MediaEncoding/Encoder/InternalEncodingTask.cs deleted file mode 100644 index 826525aef..000000000 --- a/MediaBrowser.MediaEncoding/Encoder/InternalEncodingTask.cs +++ /dev/null @@ -1,95 +0,0 @@ -using MediaBrowser.Controller.MediaEncoding; -using MediaBrowser.Model.Configuration; -using MediaBrowser.Model.Entities; -using System; -using System.Collections.Generic; -using System.Threading; - -namespace MediaBrowser.MediaEncoding.Encoder -{ - public class InternalEncodingTask - { - public string Id { get; set; } - - public CancellationTokenSource CancellationTokenSource { get; set; } - - public double ProgressPercentage { get; set; } - - public EncodingOptions Request { get; set; } - - public VideoEncodingOptions VideoRequest - { - get { return Request as VideoEncodingOptions; } - } - - public string MediaPath { get; set; } - public List<string> StreamFileNames { get; set; } - public bool IsInputRemote { get; set; } - - public VideoType? InputVideoType { get; set; } - public IsoType? IsoType { get; set; } - public long? InputRunTimeTicks; - - public string AudioSync = "1"; - public string VideoSync = "vfr"; - - public string InputAudioSync { get; set; } - public string InputVideoSync { get; set; } - - public bool DeInterlace { get; set; } - - public bool ReadInputAtNativeFramerate { get; set; } - - public string InputFormat { get; set; } - - public string InputVideoCodec { get; set; } - - public string InputAudioCodec { get; set; } - - public string LiveTvStreamId { get; set; } - - public MediaStream AudioStream { get; set; } - public MediaStream VideoStream { get; set; } - public MediaStream SubtitleStream { get; set; } - public bool HasMediaStreams { get; set; } - - public int SegmentLength = 10; - public int HlsListSize; - - public string MimeType { get; set; } - public string OrgPn { get; set; } - public bool EnableMpegtsM2TsMode { get; set; } - - /// <summary> - /// Gets or sets the user agent. - /// </summary> - /// <value>The user agent.</value> - public string UserAgent { get; set; } - - public EncodingQuality QualitySetting { get; set; } - - public InternalEncodingTask() - { - Id = Guid.NewGuid().ToString("N"); - CancellationTokenSource = new CancellationTokenSource(); - StreamFileNames = new List<string>(); - } - - public bool EnableDebugLogging { get; set; } - - internal void OnBegin() - { - - } - - internal void OnCompleted() - { - - } - - internal void OnError() - { - - } - } -} diff --git a/MediaBrowser.MediaEncoding/Encoder/InternalEncodingTaskFactory.cs b/MediaBrowser.MediaEncoding/Encoder/InternalEncodingTaskFactory.cs deleted file mode 100644 index f52f072df..000000000 --- a/MediaBrowser.MediaEncoding/Encoder/InternalEncodingTaskFactory.cs +++ /dev/null @@ -1,311 +0,0 @@ -using MediaBrowser.Controller.Configuration; -using MediaBrowser.Controller.Dlna; -using MediaBrowser.Controller.Entities; -using MediaBrowser.Controller.Library; -using MediaBrowser.Controller.LiveTv; -using MediaBrowser.Controller.MediaEncoding; -using MediaBrowser.Controller.Persistence; -using MediaBrowser.Model.Configuration; -using MediaBrowser.Model.Entities; -using MediaBrowser.Model.LiveTv; -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Threading; -using System.Threading.Tasks; - -namespace MediaBrowser.MediaEncoding.Encoder -{ - public class InternalEncodingTaskFactory - { - private readonly ILibraryManager _libraryManager; - private readonly ILiveTvManager _liveTvManager; - private readonly IItemRepository _itemRepo; - private readonly IServerConfigurationManager _config; - - public InternalEncodingTaskFactory(ILibraryManager libraryManager, ILiveTvManager liveTvManager, IItemRepository itemRepo, IServerConfigurationManager config) - { - _libraryManager = libraryManager; - _liveTvManager = liveTvManager; - _itemRepo = itemRepo; - _config = config; - } - - public async Task<InternalEncodingTask> Create(EncodingOptions request, CancellationToken cancellationToken) - { - ValidateInput(request); - - var state = new InternalEncodingTask - { - Request = request - }; - - var item = string.IsNullOrEmpty(request.MediaSourceId) ? - _libraryManager.GetItemById(new Guid(request.ItemId)) : - _libraryManager.GetItemById(new Guid(request.MediaSourceId)); - - if (item is ILiveTvRecording) - { - var recording = await _liveTvManager.GetInternalRecording(request.ItemId, cancellationToken).ConfigureAwait(false); - - if (string.Equals(recording.MediaType, MediaType.Video, StringComparison.OrdinalIgnoreCase)) - { - state.InputVideoType = VideoType.VideoFile; - } - - var path = recording.RecordingInfo.Path; - var mediaUrl = recording.RecordingInfo.Url; - - if (string.IsNullOrWhiteSpace(path) && string.IsNullOrWhiteSpace(mediaUrl)) - { - var streamInfo = await _liveTvManager.GetRecordingStream(request.ItemId, cancellationToken).ConfigureAwait(false); - - state.LiveTvStreamId = streamInfo.Id; - - path = streamInfo.Path; - mediaUrl = streamInfo.Url; - } - - if (!string.IsNullOrEmpty(path) && File.Exists(path)) - { - state.MediaPath = path; - state.IsInputRemote = false; - } - else if (!string.IsNullOrEmpty(mediaUrl)) - { - state.MediaPath = mediaUrl; - state.IsInputRemote = true; - } - - state.InputRunTimeTicks = recording.RunTimeTicks; - if (recording.RecordingInfo.Status == RecordingStatus.InProgress && !state.IsInputRemote) - { - await Task.Delay(1000, cancellationToken).ConfigureAwait(false); - } - - state.ReadInputAtNativeFramerate = recording.RecordingInfo.Status == RecordingStatus.InProgress; - state.AudioSync = "1000"; - state.DeInterlace = true; - state.InputVideoSync = "-1"; - state.InputAudioSync = "1"; - } - else if (item is LiveTvChannel) - { - var channel = _liveTvManager.GetInternalChannel(request.ItemId); - - if (string.Equals(channel.MediaType, MediaType.Video, StringComparison.OrdinalIgnoreCase)) - { - state.InputVideoType = VideoType.VideoFile; - } - - var streamInfo = await _liveTvManager.GetChannelStream(request.ItemId, cancellationToken).ConfigureAwait(false); - - state.LiveTvStreamId = streamInfo.Id; - - if (!string.IsNullOrEmpty(streamInfo.Path) && File.Exists(streamInfo.Path)) - { - state.MediaPath = streamInfo.Path; - state.IsInputRemote = false; - - await Task.Delay(1000, cancellationToken).ConfigureAwait(false); - } - else if (!string.IsNullOrEmpty(streamInfo.Url)) - { - state.MediaPath = streamInfo.Url; - state.IsInputRemote = true; - } - - state.ReadInputAtNativeFramerate = true; - state.AudioSync = "1000"; - state.DeInterlace = true; - state.InputVideoSync = "-1"; - state.InputAudioSync = "1"; - } - else - { - state.MediaPath = item.Path; - state.IsInputRemote = item.LocationType == LocationType.Remote; - - var video = item as Video; - - if (video != null) - { - state.InputVideoType = video.VideoType; - state.IsoType = video.IsoType; - - state.StreamFileNames = video.PlayableStreamFileNames.ToList(); - } - - state.InputRunTimeTicks = item.RunTimeTicks; - } - - var videoRequest = request as VideoEncodingOptions; - - var mediaStreams = _itemRepo.GetMediaStreams(new MediaStreamQuery - { - ItemId = item.Id - - }).ToList(); - - if (videoRequest != null) - { - state.VideoStream = GetMediaStream(mediaStreams, videoRequest.VideoStreamIndex, MediaStreamType.Video); - state.SubtitleStream = GetMediaStream(mediaStreams, videoRequest.SubtitleStreamIndex, MediaStreamType.Subtitle, false); - state.AudioStream = GetMediaStream(mediaStreams, videoRequest.AudioStreamIndex, MediaStreamType.Audio); - - if (state.VideoStream != null && state.VideoStream.IsInterlaced) - { - state.DeInterlace = true; - } - } - else - { - state.AudioStream = GetMediaStream(mediaStreams, null, MediaStreamType.Audio, true); - } - - state.HasMediaStreams = mediaStreams.Count > 0; - - state.SegmentLength = state.ReadInputAtNativeFramerate ? 5 : 10; - state.HlsListSize = state.ReadInputAtNativeFramerate ? 100 : 1440; - - state.QualitySetting = GetQualitySetting(); - - ApplyDeviceProfileSettings(state); - - return state; - } - - private void ValidateInput(EncodingOptions request) - { - if (string.IsNullOrWhiteSpace(request.ItemId)) - { - throw new ArgumentException("ItemId is required."); - } - if (string.IsNullOrWhiteSpace(request.OutputPath)) - { - throw new ArgumentException("OutputPath is required."); - } - if (string.IsNullOrWhiteSpace(request.Container)) - { - throw new ArgumentException("Container is required."); - } - if (string.IsNullOrWhiteSpace(request.AudioCodec)) - { - throw new ArgumentException("AudioCodec is required."); - } - - var videoRequest = request as VideoEncodingOptions; - - if (videoRequest == null) - { - return; - } - } - - /// <summary> - /// Determines which stream will be used for playback - /// </summary> - /// <param name="allStream">All stream.</param> - /// <param name="desiredIndex">Index of the desired.</param> - /// <param name="type">The type.</param> - /// <param name="returnFirstIfNoIndex">if set to <c>true</c> [return first if no index].</param> - /// <returns>MediaStream.</returns> - private MediaStream GetMediaStream(IEnumerable<MediaStream> allStream, int? desiredIndex, MediaStreamType type, bool returnFirstIfNoIndex = true) - { - var streams = allStream.Where(s => s.Type == type).OrderBy(i => i.Index).ToList(); - - if (desiredIndex.HasValue) - { - var stream = streams.FirstOrDefault(s => s.Index == desiredIndex.Value); - - if (stream != null) - { - return stream; - } - } - - if (returnFirstIfNoIndex && type == MediaStreamType.Audio) - { - return streams.FirstOrDefault(i => i.Channels.HasValue && i.Channels.Value > 0) ?? - streams.FirstOrDefault(); - } - - // Just return the first one - return returnFirstIfNoIndex ? streams.FirstOrDefault() : null; - } - - private void ApplyDeviceProfileSettings(InternalEncodingTask state) - { - var profile = state.Request.DeviceProfile; - - if (profile == null) - { - // Don't use settings from the default profile. - // Only use a specific profile if it was requested. - return; - } - - var container = state.Request.Container; - - var audioCodec = state.Request.AudioCodec; - - if (string.Equals(audioCodec, "copy", StringComparison.OrdinalIgnoreCase) && state.AudioStream != null) - { - audioCodec = state.AudioStream.Codec; - } - - var videoCodec = state.VideoRequest == null ? null : state.VideoRequest.VideoCodec; - - if (string.Equals(videoCodec, "copy", StringComparison.OrdinalIgnoreCase) && state.VideoStream != null) - { - videoCodec = state.VideoStream.Codec; - } - - //var mediaProfile = state.VideoRequest == null ? - // profile.GetAudioMediaProfile(container, audioCodec) : - // profile.GetVideoMediaProfile(container, audioCodec, videoCodec, state.AudioStream, state.VideoStream); - - //if (mediaProfile != null) - //{ - // state.MimeType = mediaProfile.MimeType; - // state.OrgPn = mediaProfile.OrgPn; - //} - - //var transcodingProfile = state.VideoRequest == null ? - // profile.GetAudioTranscodingProfile(container, audioCodec) : - // profile.GetVideoTranscodingProfile(container, audioCodec, videoCodec); - - //if (transcodingProfile != null) - //{ - // //state.EstimateContentLength = transcodingProfile.EstimateContentLength; - // state.EnableMpegtsM2TsMode = transcodingProfile.EnableMpegtsM2TsMode; - // //state.TranscodeSeekInfo = transcodingProfile.TranscodeSeekInfo; - - // if (state.VideoRequest != null && string.IsNullOrWhiteSpace(state.VideoRequest.VideoProfile)) - // { - // state.VideoRequest.VideoProfile = transcodingProfile.VideoProfile; - // } - //} - } - - private EncodingQuality GetQualitySetting() - { - var quality = _config.Configuration.MediaEncodingQuality; - - if (quality == EncodingQuality.Auto) - { - var cpuCount = Environment.ProcessorCount; - - if (cpuCount >= 4) - { - //return EncodingQuality.HighQuality; - } - - return EncodingQuality.HighSpeed; - } - - return quality; - } - } -} diff --git a/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs b/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs index 389046c9e..9ff28dda2 100644 --- a/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs +++ b/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs @@ -853,7 +853,7 @@ namespace MediaBrowser.MediaEncoding.Encoder public Task<Stream> EncodeImage(ImageEncodingOptions options, CancellationToken cancellationToken) { - return new ImageEncoder(FFMpegPath, _logger, _fileSystem, _appPaths).EncodeImage(options, cancellationToken); + throw new NotImplementedException(); } /// <summary> |
