Remove --ffprobe logic

This commit is contained in:
PloughPuff 2019-02-28 22:06:56 +00:00 committed by Ploughpuff
parent 8104e739d5
commit 656bffbbb2
3 changed files with 59 additions and 138 deletions

View File

@ -20,10 +20,10 @@ namespace Jellyfin.Server
[Option('l', "logdir", Required = false, HelpText = "Path to use for writing log files.")] [Option('l', "logdir", Required = false, HelpText = "Path to use for writing log files.")]
public string LogDir { get; set; } public string LogDir { get; set; }
[Option("ffmpeg", Required = false, HelpText = "Path to external FFmpeg executable to use in place of default found in PATH. Must be specified along with --ffprobe.")] [Option("ffmpeg", Required = false, HelpText = "Path to external FFmpeg executable to use in place of default found in PATH.")]
public string FFmpegPath { get; set; } public string FFmpegPath { get; set; }
[Option("ffprobe", Required = false, HelpText = "Path to external FFprobe executable to use in place of default found in PATH. Must be specified along with --ffmpeg.")] [Option("ffprobe", Required = false, HelpText = "(deprecated) Option has no effect and shall be removed in next release.")]
public string FFprobePath { get; set; } public string FFprobePath { get; set; }
[Option("service", Required = false, HelpText = "Run as headless service.")] [Option("service", Required = false, HelpText = "Run as headless service.")]

View File

@ -40,8 +40,6 @@ namespace MediaBrowser.MediaEncoding.Encoder
/// </summary> /// </summary>
public FFmpegLocation EncoderLocation { get; private set; } public FFmpegLocation EncoderLocation { get; private set; }
private FFmpegLocation ProbeLocation;
private readonly ILogger _logger; private readonly ILogger _logger;
private readonly IJsonSerializer _jsonSerializer; private readonly IJsonSerializer _jsonSerializer;
private string FFmpegPath; private string FFmpegPath;
@ -55,11 +53,6 @@ namespace MediaBrowser.MediaEncoding.Encoder
private readonly string StartupOptionFFmpegPath; private readonly string StartupOptionFFmpegPath;
private readonly string StartupOptionFFprobePath; private readonly string StartupOptionFFprobePath;
/// <summary>
/// Enum to identify the two types of FF utilities of interest.
/// </summary>
private enum FFtype { Mpeg, Probe };
private readonly SemaphoreSlim _thumbnailResourcePool = new SemaphoreSlim(1, 1); private readonly SemaphoreSlim _thumbnailResourcePool = new SemaphoreSlim(1, 1);
private readonly List<ProcessWrapper> _runningProcesses = new List<ProcessWrapper>(); private readonly List<ProcessWrapper> _runningProcesses = new List<ProcessWrapper>();
@ -93,14 +86,20 @@ namespace MediaBrowser.MediaEncoding.Encoder
/// </summary> /// </summary>
public void Init() public void Init()
{ {
// 1) Custom path stored in config/encoding xml file under tag <EncoderAppPathCustom> takes precedence // ToDo - Finalise removal of the --ffprobe switch
if (!ValidatePath(FFtype.Mpeg, ConfigurationManager.GetConfiguration<EncodingOptions>("encoding").EncoderAppPathCustom, FFmpegLocation.Custom)) if (!string.IsNullOrEmpty(StartupOptionFFprobePath))
{
_logger.LogWarning("--ffprobe switch is deprecated and shall be removed in the next release");
}
// 1) Custom path stored in config/encoding xml file under tag <EncoderAppPath> takes precedence
if (!ValidatePath(ConfigurationManager.GetConfiguration<EncodingOptions>("encoding").EncoderAppPath, FFmpegLocation.Custom))
{ {
// 2) Check if the --ffmpeg CLI switch has been given // 2) Check if the --ffmpeg CLI switch has been given
if (!ValidatePath(FFtype.Mpeg, StartupOptionFFmpegPath, FFmpegLocation.SetByArgument)) if (!ValidatePath(StartupOptionFFmpegPath, FFmpegLocation.SetByArgument))
{ {
// 3) Search system $PATH environment variable for valid FFmpeg // 3) Search system $PATH environment variable for valid FFmpeg
if (!ValidatePath(FFtype.Mpeg, ExistsOnSystemPath("ffmpeg"), FFmpegLocation.System)) if (!ValidatePath(ExistsOnSystemPath("ffmpeg"), FFmpegLocation.System))
{ {
EncoderLocation = FFmpegLocation.NotFound; EncoderLocation = FFmpegLocation.NotFound;
FFmpegPath = null; FFmpegPath = null;
@ -108,110 +107,80 @@ namespace MediaBrowser.MediaEncoding.Encoder
} }
} }
ReInit(); // Write the FFmpeg path to the config/encoding.xml file as <EncoderAppPathDisplay> so it appears in UI
}
/// <summary>
/// Writes the currently used FFmpeg to config/encoding.xml file.
/// Sets the FFprobe path if not currently set.
/// Interrogates the FFmpeg tool to identify what encoders/decodres are available.
/// </summary>
private void ReInit()
{
// Write the FFmpeg path to the config/encoding.xml file as <EncoderAppPath> so it appears in UI
var config = ConfigurationManager.GetConfiguration<EncodingOptions>("encoding"); var config = ConfigurationManager.GetConfiguration<EncodingOptions>("encoding");
config.EncoderAppPath = FFmpegPath ?? string.Empty; config.EncoderAppPathDisplay = FFmpegPath ?? string.Empty;
ConfigurationManager.SaveConfiguration("encoding", config); ConfigurationManager.SaveConfiguration("encoding", config);
// Clear probe settings in case probe validation fails
ProbeLocation = FFmpegLocation.NotFound;
FFprobePath = null;
// Only if mpeg path is set, try and set path to probe // Only if mpeg path is set, try and set path to probe
if (FFmpegPath != null) if (FFmpegPath != null)
{ {
if (EncoderLocation == FFmpegLocation.Custom || StartupOptionFFprobePath == null) // Determine a probe path from the mpeg path
{ FFprobePath = Regex.Replace(FFmpegPath, @"[^\/\\]+?(\.[^\/\\\n.]+)?$", @"ffprobe$1");
// If mpeg was read from config, or CLI switch not given, try and set probe from mpeg path
ValidatePath(FFtype.Probe, GetProbePathFromEncoderPath(FFmpegPath), EncoderLocation);
}
else
{
// Else try and set probe path from CLI switch
ValidatePath(FFtype.Probe, StartupOptionFFmpegPath, FFmpegLocation.SetByArgument);
}
// Interrogate to understand what coders it supports // Interrogate to understand what coders are supported
var result = new EncoderValidator(_logger, _processFactory).GetAvailableCoders(FFmpegPath); var result = new EncoderValidator(_logger, _processFactory).GetAvailableCoders(FFmpegPath);
SetAvailableDecoders(result.decoders); SetAvailableDecoders(result.decoders);
SetAvailableEncoders(result.encoders); SetAvailableEncoders(result.encoders);
} }
// Stamp FFmpeg paths to the log file _logger.LogInformation("FFmpeg: {0}: {1}", EncoderLocation.ToString(), FFmpegPath ?? string.Empty);
LogPaths();
} }
/// <summary> /// <summary>
/// Triggered from the Settings > Trascoding UI page when users sumits Custom FFmpeg path to use. /// Triggered from the Settings > Transcoding UI page when users submits Custom FFmpeg path to use.
/// Only write the new path to xml if it exists. Do not perform validation checks on ffmpeg here.
/// </summary> /// </summary>
/// <param name="path"></param> /// <param name="path"></param>
/// <param name="pathType"></param> /// <param name="pathType"></param>
public void UpdateEncoderPath(string path, string pathType) public void UpdateEncoderPath(string path, string pathType)
{ {
string newPath;
_logger.LogInformation("Attempting to update encoder path to {0}. pathType: {1}", path ?? string.Empty, pathType ?? string.Empty); _logger.LogInformation("Attempting to update encoder path to {0}. pathType: {1}", path ?? string.Empty, pathType ?? string.Empty);
if (!string.Equals(pathType, "custom", StringComparison.OrdinalIgnoreCase)) if (!string.Equals(pathType, "custom", StringComparison.OrdinalIgnoreCase))
{ {
throw new ArgumentException("Unexpected pathType value"); throw new ArgumentException("Unexpected pathType value");
} }
else if (string.IsNullOrWhiteSpace(path))
if (string.IsNullOrWhiteSpace(path))
{ {
// User had cleared the custom path in UI. Clear the Custom config // User had cleared the custom path in UI
// setting and perform full Init to reinspect any CLI switches and system $PATH newPath = string.Empty;
var config = ConfigurationManager.GetConfiguration<EncodingOptions>("encoding");
config.EncoderAppPathCustom = string.Empty;
ConfigurationManager.SaveConfiguration("encoding", config);
Init();
} }
else if (!File.Exists(path) && !Directory.Exists(path)) else if (File.Exists(path))
{ {
// Given path is neither file or folder newPath = path;
throw new ResourceNotFoundException(); }
else if (Directory.Exists(path))
{
// Given path is directory, so resolve down to filename
newPath = GetEncoderPathFromDirectory(path, "ffmpeg");
} }
else else
{ {
// Supplied path could be either file path or folder path. throw new ResourceNotFoundException();
// Resolve down to file path and validate
if (!ValidatePath(FFtype.Mpeg, GetEncoderPath(path), FFmpegLocation.Custom))
{
throw new ResourceNotFoundException("Failed validation checks.");
}
else
{
// Write the validated mpeg path to the xml as <EncoderAppPathCustom>
// This ensures its not lost on new startup
var config = ConfigurationManager.GetConfiguration<EncodingOptions>("encoding");
config.EncoderAppPathCustom = FFmpegPath;
ConfigurationManager.SaveConfiguration("encoding", config);
ReInit();
}
} }
// Write the new ffmpeg path to the xml as <EncoderAppPath>
// This ensures its not lost on next startup
var config = ConfigurationManager.GetConfiguration<EncodingOptions>("encoding");
config.EncoderAppPath = newPath;
ConfigurationManager.SaveConfiguration("encoding", config);
// Trigger Init so we validate the new path and setup probe path
Init();
} }
/// <summary> /// <summary>
/// Validates the supplied FQPN to ensure it is a FFxxx utility. /// Validates the supplied FQPN to ensure it is a ffmpeg utility.
/// If checks pass, global variable FFmpegPath (or FFprobePath) and /// If checks pass, global variable FFmpegPath and EncoderLocation are updated.
/// EncoderLocation (or ProbeLocation) are updated.
/// </summary> /// </summary>
/// <param name="type">Either mpeg or probe</param>
/// <param name="path">FQPN to test</param> /// <param name="path">FQPN to test</param>
/// <param name="location">Location (External, Custom, System) of tool</param> /// <param name="location">Location (External, Custom, System) of tool</param>
/// <returns></returns> /// <returns></returns>
private bool ValidatePath(FFtype type, string path, FFmpegLocation location) private bool ValidatePath(string path, FFmpegLocation location)
{ {
bool rc = false; bool rc = false;
@ -219,51 +188,28 @@ namespace MediaBrowser.MediaEncoding.Encoder
{ {
if (File.Exists(path)) if (File.Exists(path))
{ {
rc = new EncoderValidator(_logger, _processFactory).ValidateVersion(path, false); rc = new EncoderValidator(_logger, _processFactory).ValidateVersion(path, true);
// Only update the global variables if the checks passed if (!rc)
if (rc)
{ {
if (type == FFtype.Mpeg) _logger.LogWarning("FFmpeg: {0}: Failed version check: {1}", location.ToString(), path);
{
FFmpegPath = path;
EncoderLocation = location;
}
else
{
FFprobePath = path;
ProbeLocation = location;
}
}
else
{
_logger.LogError("{0}: {1}: Failed version check: {2}", type.ToString(), location.ToString(), path);
} }
// ToDo - Enable the ffmpeg validator. At the moment any version can be used.
rc = true;
FFmpegPath = path;
EncoderLocation = location;
} }
else else
{ {
_logger.LogError("{0}: {1}: File not found: {2}", type.ToString(), location.ToString(), path); _logger.LogWarning("FFmpeg: {0}: File not found: {1}", location.ToString(), path);
} }
} }
return rc; return rc;
} }
private string GetEncoderPath(string path)
{
if (Directory.Exists(path))
{
return GetEncoderPathFromDirectory(path, "ffmpeg");
}
if (File.Exists(path))
{
return path;
}
return null;
}
private string GetEncoderPathFromDirectory(string path, string filename) private string GetEncoderPathFromDirectory(string path, string filename)
{ {
try try
@ -282,25 +228,6 @@ namespace MediaBrowser.MediaEncoding.Encoder
} }
} }
/// <summary>
/// With the given path string, replaces the filename with ffprobe, taking case
/// of any file extension (like .exe on windows).
/// </summary>
/// <param name="appPath"></param>
/// <returns></returns>
private string GetProbePathFromEncoderPath(string appPath)
{
if (!string.IsNullOrEmpty(appPath))
{
const string pattern = @"[^\/\\]+?(\.[^\/\\\n.]+)?$";
const string substitution = @"ffprobe$1";
return Regex.Replace(appPath, pattern, substitution);
}
return null;
}
/// <summary> /// <summary>
/// Search the system $PATH environment variable looking for given filename. /// Search the system $PATH environment variable looking for given filename.
/// </summary> /// </summary>
@ -322,12 +249,6 @@ namespace MediaBrowser.MediaEncoding.Encoder
return null; return null;
} }
private void LogPaths()
{
_logger.LogInformation("FFmpeg: {0}: {1}", EncoderLocation.ToString(), FFmpegPath ?? string.Empty);
_logger.LogInformation("FFprobe: {0}: {1}", ProbeLocation.ToString(), FFprobePath ?? string.Empty);
}
private List<string> _encoders = new List<string>(); private List<string> _encoders = new List<string>();
public void SetAvailableEncoders(IEnumerable<string> list) public void SetAvailableEncoders(IEnumerable<string> list)
{ {

View File

@ -11,11 +11,11 @@ namespace MediaBrowser.Model.Configuration
/// <summary> /// <summary>
/// FFmpeg path as set by the user via the UI /// FFmpeg path as set by the user via the UI
/// </summary> /// </summary>
public string EncoderAppPathCustom { get; set; }
/// <summary>
/// The current FFmpeg path being used by the system
/// </summary>
public string EncoderAppPath { get; set; } public string EncoderAppPath { get; set; }
/// <summary>
/// The current FFmpeg path being used by the system and displayed on the transcode page
/// </summary>
public string EncoderAppPathDisplay { get; set; }
public string VaapiDevice { get; set; } public string VaapiDevice { get; set; }
public int H264Crf { get; set; } public int H264Crf { get; set; }
public string H264Preset { get; set; } public string H264Preset { get; set; }