diff options
Diffstat (limited to 'MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs')
| -rw-r--r-- | MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs | 104 |
1 files changed, 40 insertions, 64 deletions
diff --git a/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs b/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs index 75d85cd32..06867969e 100644 --- a/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs +++ b/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs @@ -82,6 +82,8 @@ namespace MediaBrowser.MediaEncoding.Encoder private readonly List<ProcessWrapper> _runningProcesses = new List<ProcessWrapper>(); private readonly bool _hasExternalEncoder; + private string _originalFFMpegPath; + private string _originalFFProbePath; public MediaEncoder(ILogger logger, IJsonSerializer jsonSerializer, string ffMpegPath, string ffProbePath, bool hasExternalEncoder, IServerConfigurationManager configurationManager, IFileSystem fileSystem, ILiveTvManager liveTvManager, IIsoManager isoManager, ILibraryManager libraryManager, IChannelManager channelManager, ISessionManager sessionManager, Func<ISubtitleEncoder> subtitleEncoder, Func<IMediaSourceManager> mediaSourceManager, IHttpClient httpClient, IZipClient zipClient) { @@ -100,6 +102,8 @@ namespace MediaBrowser.MediaEncoding.Encoder _zipClient = zipClient; FFProbePath = ffProbePath; FFMpegPath = ffMpegPath; + _originalFFProbePath = ffProbePath; + _originalFFMpegPath = ffMpegPath; _hasExternalEncoder = hasExternalEncoder; } @@ -108,11 +112,6 @@ namespace MediaBrowser.MediaEncoding.Encoder { get { - if (_hasExternalEncoder) - { - return "External"; - } - if (string.IsNullOrWhiteSpace(FFMpegPath)) { return null; @@ -177,12 +176,6 @@ namespace MediaBrowser.MediaEncoding.Encoder { ConfigureEncoderPaths(); - if (_hasExternalEncoder) - { - LogPaths(); - return; - } - // If the path was passed in, save it into config now. var encodingOptions = GetEncodingOptions(); var appPath = encodingOptions.EncoderAppPath; @@ -207,11 +200,6 @@ namespace MediaBrowser.MediaEncoding.Encoder public async Task UpdateEncoderPath(string path, string pathType) { - if (_hasExternalEncoder) - { - return; - } - Tuple<string, string> newPaths; if (string.Equals(pathType, "system", StringComparison.OrdinalIgnoreCase)) @@ -247,6 +235,13 @@ namespace MediaBrowser.MediaEncoding.Encoder throw new ResourceNotFoundException("ffprobe not found"); } + path = newPaths.Item1; + + if (!ValidateVersion(path)) + { + throw new ResourceNotFoundException("ffmpeg version 3.0 or greater is required."); + } + var config = GetEncodingOptions(); config.EncoderAppPath = path; ConfigurationManager.SaveConfiguration("encoding", config); @@ -254,13 +249,13 @@ namespace MediaBrowser.MediaEncoding.Encoder Init(); } - private void ConfigureEncoderPaths() + private bool ValidateVersion(string path) { - if (_hasExternalEncoder) - { - return; - } + return new EncoderValidator(_logger).ValidateVersion(path); + } + private void ConfigureEncoderPaths() + { var appPath = GetEncodingOptions().EncoderAppPath; if (string.IsNullOrWhiteSpace(appPath)) @@ -308,45 +303,22 @@ namespace MediaBrowser.MediaEncoding.Encoder string encoderPath = null; string probePath = null; - if (TestSystemInstalled("ffmpeg")) - { - encoderPath = "ffmpeg"; - } - if (TestSystemInstalled("ffprobe")) + if (_hasExternalEncoder && ValidateVersion(_originalFFMpegPath)) { - probePath = "ffprobe"; + encoderPath = _originalFFMpegPath; + probePath = _originalFFProbePath; } - return new Tuple<string, string>(encoderPath, probePath); - } - - private bool TestSystemInstalled(string app) - { - try + if (string.IsNullOrWhiteSpace(encoderPath)) { - var startInfo = new ProcessStartInfo - { - FileName = app, - Arguments = "-v", - UseShellExecute = false, - CreateNoWindow = true, - WindowStyle = ProcessWindowStyle.Hidden, - ErrorDialog = false - }; - - using (var process = Process.Start(startInfo)) + if (ValidateVersion("ffmpeg") && ValidateVersion("ffprobe")) { - process.WaitForExit(); + encoderPath = "ffmpeg"; + probePath = "ffprobe"; } - - _logger.Debug("System app installed: " + app); - return true; - } - catch - { - _logger.Debug("System app not installed: " + app); - return false; } + + return new Tuple<string, string>(encoderPath, probePath); } private Tuple<string, string> GetPathsFromDirectory(string path) @@ -799,20 +771,20 @@ namespace MediaBrowser.MediaEncoding.Encoder public Task<string> ExtractAudioImage(string path, int? imageStreamIndex, CancellationToken cancellationToken) { - return ExtractImage(new[] { path }, imageStreamIndex, MediaProtocol.File, true, null, null, cancellationToken); + return ExtractImage(new[] { path }, null, imageStreamIndex, MediaProtocol.File, true, null, null, cancellationToken); } - public Task<string> ExtractVideoImage(string[] inputFiles, MediaProtocol protocol, Video3DFormat? threedFormat, TimeSpan? offset, CancellationToken cancellationToken) + public Task<string> ExtractVideoImage(string[] inputFiles, string container, MediaProtocol protocol, Video3DFormat? threedFormat, TimeSpan? offset, CancellationToken cancellationToken) { - return ExtractImage(inputFiles, null, protocol, false, threedFormat, offset, cancellationToken); + return ExtractImage(inputFiles, container, null, protocol, false, threedFormat, offset, cancellationToken); } - public Task<string> ExtractVideoImage(string[] inputFiles, MediaProtocol protocol, int? imageStreamIndex, CancellationToken cancellationToken) + public Task<string> ExtractVideoImage(string[] inputFiles, string container, MediaProtocol protocol, int? imageStreamIndex, CancellationToken cancellationToken) { - return ExtractImage(inputFiles, imageStreamIndex, protocol, false, null, null, cancellationToken); + return ExtractImage(inputFiles, container, imageStreamIndex, protocol, false, null, null, cancellationToken); } - private async Task<string> ExtractImage(string[] inputFiles, int? imageStreamIndex, MediaProtocol protocol, bool isAudio, + private async Task<string> ExtractImage(string[] inputFiles, string container, int? imageStreamIndex, MediaProtocol protocol, bool isAudio, Video3DFormat? threedFormat, TimeSpan? offset, CancellationToken cancellationToken) { var resourcePool = isAudio ? _audioImageResourcePool : _videoImageResourcePool; @@ -831,7 +803,7 @@ namespace MediaBrowser.MediaEncoding.Encoder { try { - return await ExtractImageInternal(inputArgument, imageStreamIndex, protocol, threedFormat, offset, true, resourcePool, cancellationToken).ConfigureAwait(false); + return await ExtractImageInternal(inputArgument, container, imageStreamIndex, protocol, threedFormat, offset, true, resourcePool, cancellationToken).ConfigureAwait(false); } catch (ArgumentException) { @@ -843,10 +815,10 @@ namespace MediaBrowser.MediaEncoding.Encoder } } - return await ExtractImageInternal(inputArgument, imageStreamIndex, protocol, threedFormat, offset, false, resourcePool, cancellationToken).ConfigureAwait(false); + return await ExtractImageInternal(inputArgument, container, imageStreamIndex, protocol, threedFormat, offset, false, resourcePool, cancellationToken).ConfigureAwait(false); } - private async Task<string> ExtractImageInternal(string inputPath, int? imageStreamIndex, MediaProtocol protocol, Video3DFormat? threedFormat, TimeSpan? offset, bool useIFrame, SemaphoreSlim resourcePool, CancellationToken cancellationToken) + private async Task<string> ExtractImageInternal(string inputPath, string container, int? imageStreamIndex, MediaProtocol protocol, Video3DFormat? threedFormat, TimeSpan? offset, bool useIFrame, SemaphoreSlim resourcePool, CancellationToken cancellationToken) { if (string.IsNullOrEmpty(inputPath)) { @@ -887,8 +859,11 @@ namespace MediaBrowser.MediaEncoding.Encoder var mapArg = imageStreamIndex.HasValue ? (" -map 0:v:" + imageStreamIndex.Value.ToString(CultureInfo.InvariantCulture)) : string.Empty; + var enableThumbnail = !new List<string> { "wtv" }.Contains(container ?? string.Empty, StringComparer.OrdinalIgnoreCase); + var thumbnail = enableThumbnail ? ",thumbnail=30" : string.Empty; + // Use ffmpeg to sample 100 (we can drop this if required using thumbnail=50 for 50 frames) frames and pick the best thumbnail. Have a fall back just in case. - var args = useIFrame ? string.Format("-i {0}{3} -threads 0 -v quiet -vframes 1 -vf \"{2},thumbnail=30\" -f image2 \"{1}\"", inputPath, tempExtractPath, vf, mapArg) : + var args = useIFrame ? string.Format("-i {0}{3} -threads 0 -v quiet -vframes 1 -vf \"{2}{4}\" -f image2 \"{1}\"", inputPath, tempExtractPath, vf, mapArg, thumbnail) : string.Format("-i {0}{3} -threads 0 -v quiet -vframes 1 -vf \"{2}\" -f image2 \"{1}\"", inputPath, tempExtractPath, vf, mapArg); var probeSize = GetProbeSizeArgument(new[] { inputPath }, protocol); @@ -931,8 +906,9 @@ namespace MediaBrowser.MediaEncoding.Encoder var timeoutMs = ConfigurationManager.Configuration.ImageExtractionTimeoutMs; if (timeoutMs <= 0) { - timeoutMs = 10000; + timeoutMs = Environment.Is64BitOperatingSystem ? (Environment.ProcessorCount > 2 ? 14000 : 20000) : 40000; } + ranToCompletion = process.WaitForExit(timeoutMs); if (!ranToCompletion) |
