| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211 | using System;using System.Collections.Generic;using System.Diagnostics;using System.Globalization;using MediaBrowser.Model.Diagnostics;using MediaBrowser.Model.Logging;namespace MediaBrowser.MediaEncoding.Encoder{    public class EncoderValidator    {        private readonly ILogger _logger;        private readonly IProcessFactory _processFactory;        public EncoderValidator(ILogger logger, IProcessFactory processFactory)        {            _logger = logger;            _processFactory = processFactory;        }        public Tuple<List<string>, List<string>> Validate(string encoderPath)        {            _logger.Info("Validating media encoder at {0}", encoderPath);            var decoders = GetDecoders(encoderPath);            var encoders = GetEncoders(encoderPath);            _logger.Info("Encoder validation complete");            return new Tuple<List<string>, List<string>>(decoders, encoders);        }        public bool ValidateVersion(string encoderAppPath, bool logOutput)        {            string output = string.Empty;            try            {                output = GetProcessOutput(encoderAppPath, "-version");            }            catch (Exception ex)            {                if (logOutput)                {                    _logger.ErrorException("Error validating encoder", ex);                }            }            if (string.IsNullOrWhiteSpace(output))            {                return false;            }            _logger.Info("ffmpeg info: {0}", output);            if (output.IndexOf("Libav developers", StringComparison.OrdinalIgnoreCase) != -1)            {                return false;            }            output = " " + output + " ";            for (var i = 2013; i <= 2015; i++)            {                var yearString = i.ToString(CultureInfo.InvariantCulture);                if (output.IndexOf(" " + yearString + " ", StringComparison.OrdinalIgnoreCase) != -1)                {                    return false;                }            }            return true;        }        private List<string> GetDecoders(string encoderAppPath)        {            string output = string.Empty;            try            {                output = GetProcessOutput(encoderAppPath, "-decoders");            }            catch (Exception )            {                //_logger.ErrorException("Error detecting available decoders", ex);            }            var found = new List<string>();            var required = new[]            {                "mpeg2video",                "h264_qsv",                "hevc_qsv",                "mpeg2_qsv",                "vc1_qsv"            };            foreach (var codec in required)            {                var srch = " " + codec + "  ";                if (output.IndexOf(srch, StringComparison.OrdinalIgnoreCase) != -1)                {                    _logger.Info("Decoder available: " + codec);                    found.Add(codec);                }            }            return found;        }        private List<string> GetEncoders(string encoderAppPath)        {            string output = null;            try            {                output = GetProcessOutput(encoderAppPath, "-encoders");            }            catch            {            }            var found = new List<string>();            var required = new[]            {                "libx264",                "libx265",                "mpeg4",                "msmpeg4",                "libvpx",                "libvpx-vp9",                "aac",                "libmp3lame",                "libopus",                "libvorbis",                "srt",                "h264_nvenc",                "hevc_nvenc",                "h264_qsv",                "hevc_qsv",                "h264_omx",                "hevc_omx",                "h264_vaapi",                "hevc_vaapi",                "ac3"            };            output = output ?? string.Empty;            var index = 0;            foreach (var codec in required)            {                var srch = " " + codec + "  ";                if (output.IndexOf(srch, StringComparison.OrdinalIgnoreCase) != -1)                {                    if (index < required.Length - 1)                    {                        _logger.Info("Encoder available: " + codec);                    }                    found.Add(codec);                }                index++;            }            return found;        }        private string GetProcessOutput(string path, string arguments)        {            var process = _processFactory.Create(new ProcessOptions            {                CreateNoWindow = true,                UseShellExecute = false,                FileName = path,                Arguments = arguments,                IsHidden = true,                ErrorDialog = false,                RedirectStandardOutput = true            });            _logger.Info("Running {0} {1}", path, arguments);            using (process)            {                process.Start();                try                {                    return process.StandardOutput.ReadToEnd();                }                catch                {                    _logger.Info("Killing process {0} {1}", path, arguments);                    // Hate having to do this                    try                    {                        process.Kill();                    }                    catch (Exception ex1)                    {                        _logger.ErrorException("Error killing process", ex1);                    }                    throw;                }            }        }    }}
 |