소스 검색

allow customization of ffmpeg path

Luke Pulverenti 9 년 전
부모
커밋
6e9f8fb2d1

+ 2 - 0
MediaBrowser.Controller/MediaEncoding/IMediaEncoder.cs

@@ -134,5 +134,7 @@ namespace MediaBrowser.Controller.MediaEncoding
         /// <param name="path">The path.</param>
         /// <returns>System.String.</returns>
         string EscapeSubtitleFilterPath(string path);
+
+        void Init();
     }
 }

+ 71 - 0
MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs

@@ -21,6 +21,8 @@ using System.Linq;
 using System.Threading;
 using System.Threading.Tasks;
 using CommonIO;
+using MediaBrowser.Model.Configuration;
+using MediaBrowser.Common.Configuration;
 
 namespace MediaBrowser.MediaEncoding.Encoder
 {
@@ -77,6 +79,7 @@ namespace MediaBrowser.MediaEncoding.Encoder
         protected readonly Func<IMediaSourceManager> MediaSourceManager;
 
         private readonly List<ProcessWrapper> _runningProcesses = new List<ProcessWrapper>();
+        private readonly bool _hasExternalEncoder;
 
         public MediaEncoder(ILogger logger, IJsonSerializer jsonSerializer, string ffMpegPath, string ffProbePath, string version, IServerConfigurationManager configurationManager, IFileSystem fileSystem, ILiveTvManager liveTvManager, IIsoManager isoManager, ILibraryManager libraryManager, IChannelManager channelManager, ISessionManager sessionManager, Func<ISubtitleEncoder> subtitleEncoder, Func<IMediaSourceManager> mediaSourceManager)
         {
@@ -94,6 +97,74 @@ namespace MediaBrowser.MediaEncoding.Encoder
             MediaSourceManager = mediaSourceManager;
             FFProbePath = ffProbePath;
             FFMpegPath = ffMpegPath;
+
+            _hasExternalEncoder = !string.IsNullOrWhiteSpace(ffMpegPath);
+        }
+
+        public void Init()
+        {
+            ConfigureEncoderPaths();
+        }
+
+        private void ConfigureEncoderPaths()
+        {
+            if (_hasExternalEncoder)
+            {
+                LogPaths();
+                return;
+            }
+
+            var appPath = GetEncodingOptions().EncoderAppPath;
+            appPath = "C:\\dev\\Emby.dev\\ProgramData-Server\\ffmpeg";
+
+            if (Directory.Exists(appPath))
+            {
+                SetPathsFromDirectory(appPath);
+            }
+
+            else if (File.Exists(appPath))
+            {
+                FFMpegPath = appPath;
+
+                SetProbePathFromEncoderPath(appPath);
+            }
+
+            LogPaths();
+        }
+
+        private void SetPathsFromDirectory(string path)
+        {
+            // Since we can't predict the file extension, first try directly within the folder 
+            // If that doesn't pan out, then do a recursive search
+            var files = Directory.GetFiles(path);
+
+            FFMpegPath = files.FirstOrDefault(i => string.Equals(Path.GetFileNameWithoutExtension(i), "ffmpeg", StringComparison.OrdinalIgnoreCase));
+            FFProbePath = files.FirstOrDefault(i => string.Equals(Path.GetFileNameWithoutExtension(i), "ffprobe", StringComparison.OrdinalIgnoreCase));
+
+            if (string.IsNullOrWhiteSpace(FFMpegPath) || !File.Exists(FFMpegPath))
+            {
+                files = Directory.GetFiles(path, "*", SearchOption.AllDirectories);
+
+                FFMpegPath = files.FirstOrDefault(i => string.Equals(Path.GetFileNameWithoutExtension(i), "ffmpeg", StringComparison.OrdinalIgnoreCase));
+                SetProbePathFromEncoderPath(FFMpegPath);
+            }
+        }
+
+        private void SetProbePathFromEncoderPath(string appPath)
+        {
+            FFProbePath = Directory.GetFiles(Path.GetDirectoryName(appPath))
+                .FirstOrDefault(i => string.Equals(Path.GetFileNameWithoutExtension(i), "ffprobe", StringComparison.OrdinalIgnoreCase));
+        }
+
+        private void LogPaths()
+        {
+            _logger.Info("FFMpeg: {0}", FFMpegPath ?? "not found");
+            _logger.Info("FFProbe: {0}", FFProbePath ?? "not found");
+        }
+
+        private EncodingOptions GetEncodingOptions()
+        {
+            return ConfigurationManager.GetConfiguration<EncodingOptions>("encoding");
         }
 
         private List<string> _encoders = new List<string>();

+ 1 - 0
MediaBrowser.Model/Configuration/EncodingOptions.cs

@@ -9,6 +9,7 @@ namespace MediaBrowser.Model.Configuration
         public bool EnableThrottling { get; set; }
         public int ThrottleDelaySeconds { get; set; }
         public string HardwareAccelerationType { get; set; }
+        public string EncoderAppPath { get; set; }
 
         public EncodingOptions()
         {

+ 2 - 0
MediaBrowser.Model/System/SystemInfo.cs

@@ -152,6 +152,8 @@ namespace MediaBrowser.Model.System
         /// <value><c>true</c> if [supports automatic run at startup]; otherwise, <c>false</c>.</value>
         public bool SupportsAutoRunAtStartup { get; set; }
 
+        public bool HasExternalEncoder { get; set; }
+
         /// <summary>
         /// Initializes a new instance of the <see cref="SystemInfo" /> class.
         /// </summary>

+ 21 - 9
MediaBrowser.Server.Startup.Common/ApplicationHost.cs

@@ -323,6 +323,8 @@ namespace MediaBrowser.Server.Startup.Common
 
             await base.RunStartupTasks().ConfigureAwait(false);
 
+            InitMediaEncoder();
+
             Logger.Info("ServerId: {0}", SystemId);
             Logger.Info("Core startup complete");
             HttpServer.GlobalResponse = null;
@@ -344,6 +346,20 @@ namespace MediaBrowser.Server.Startup.Common
             LogManager.RemoveConsoleOutput();
         }
 
+        private void InitMediaEncoder()
+        {
+            MediaEncoder.Init();
+
+            Task.Run(() =>
+            {
+                var result = new FFmpegValidator(Logger, ApplicationPaths, FileSystemManager).Validate(MediaEncoder.EncoderPath);
+
+                var mediaEncoder = (MediaEncoder) MediaEncoder;
+                mediaEncoder.SetAvailableDecoders(result.Item1);
+                mediaEncoder.SetAvailableEncoders(result.Item2);
+            });
+        }
+
         public override Task Init(IProgress<double> progress)
         {
             HttpPort = ServerConfigurationManager.Configuration.HttpServerPortNumber;
@@ -634,6 +650,8 @@ namespace MediaBrowser.Server.Startup.Common
             var info = await new FFMpegLoader(Logger, ApplicationPaths, HttpClient, ZipClient, FileSystemManager, NativeApp.Environment, NativeApp.GetType().Assembly, NativeApp.GetFfmpegInstallInfo())
                 .GetFFMpegInfo(NativeApp.Environment, _startupOptions, progress).ConfigureAwait(false);
 
+            _hasExternalEncoder = !string.IsNullOrWhiteSpace(info.EncoderPath);
+
             var mediaEncoder = new MediaEncoder(LogManager.GetLogger("MediaEncoder"),
                 JsonSerializer,
                 info.EncoderPath,
@@ -651,14 +669,6 @@ namespace MediaBrowser.Server.Startup.Common
 
             MediaEncoder = mediaEncoder;
             RegisterSingleInstance(MediaEncoder);
-
-            Task.Run(() =>
-            {
-                var result = new FFmpegValidator(Logger, ApplicationPaths, FileSystemManager).Validate(info);
-
-                mediaEncoder.SetAvailableDecoders(result.Item1);
-                mediaEncoder.SetAvailableEncoders(result.Item2);
-            });
         }
 
         /// <summary>
@@ -1094,6 +1104,7 @@ namespace MediaBrowser.Server.Startup.Common
             }
         }
 
+        private bool _hasExternalEncoder;
         /// <summary>
         /// Gets the system status.
         /// </summary>
@@ -1133,7 +1144,8 @@ namespace MediaBrowser.Server.Startup.Common
                 SupportsRunningAsService = SupportsRunningAsService,
                 ServerName = FriendlyName,
                 LocalAddress = localAddress,
-                SupportsLibraryMonitor = SupportsLibraryMonitor
+                SupportsLibraryMonitor = SupportsLibraryMonitor,
+                HasExternalEncoder = _hasExternalEncoder
             };
         }
 

+ 3 - 6
MediaBrowser.Server.Startup.Common/FFMpeg/FFmpegValidator.cs

@@ -21,13 +21,10 @@ namespace MediaBrowser.Server.Startup.Common.FFMpeg
             _fileSystem = fileSystem;
         }
 
-        public Tuple<List<string>,List<string>> Validate(FFMpegInfo info)
+        public Tuple<List<string>,List<string>> Validate(string encoderPath)
         {
-            _logger.Info("FFMpeg: {0}", info.EncoderPath);
-            _logger.Info("FFProbe: {0}", info.ProbePath);
-
-            var decoders = GetDecoders(info.EncoderPath);
-            var encoders = GetEncoders(info.EncoderPath);
+            var decoders = GetDecoders(encoderPath);
+            var encoders = GetEncoders(encoderPath);
 
             return new Tuple<List<string>, List<string>>(decoders, encoders);
         }