|
@@ -23,7 +23,6 @@ using MediaBrowser.Model.Entities;
|
|
using MediaBrowser.Model.Globalization;
|
|
using MediaBrowser.Model.Globalization;
|
|
using MediaBrowser.Model.IO;
|
|
using MediaBrowser.Model.IO;
|
|
using MediaBrowser.Model.MediaInfo;
|
|
using MediaBrowser.Model.MediaInfo;
|
|
-using MediaBrowser.Model.System;
|
|
|
|
using Microsoft.Extensions.Configuration;
|
|
using Microsoft.Extensions.Configuration;
|
|
using Microsoft.Extensions.Logging;
|
|
using Microsoft.Extensions.Logging;
|
|
|
|
|
|
@@ -72,7 +71,7 @@ namespace MediaBrowser.MediaEncoding.Encoder
|
|
private Version _ffmpegVersion = null;
|
|
private Version _ffmpegVersion = null;
|
|
private string _ffmpegPath = string.Empty;
|
|
private string _ffmpegPath = string.Empty;
|
|
private string _ffprobePath;
|
|
private string _ffprobePath;
|
|
- private int threads;
|
|
|
|
|
|
+ private int _threads;
|
|
|
|
|
|
public MediaEncoder(
|
|
public MediaEncoder(
|
|
ILogger<MediaEncoder> logger,
|
|
ILogger<MediaEncoder> logger,
|
|
@@ -92,9 +91,6 @@ namespace MediaBrowser.MediaEncoding.Encoder
|
|
/// <inheritdoc />
|
|
/// <inheritdoc />
|
|
public string EncoderPath => _ffmpegPath;
|
|
public string EncoderPath => _ffmpegPath;
|
|
|
|
|
|
- /// <inheritdoc />
|
|
|
|
- public FFmpegLocation EncoderLocation { get; private set; }
|
|
|
|
-
|
|
|
|
/// <summary>
|
|
/// <summary>
|
|
/// Run at startup or if the user removes a Custom path from transcode page.
|
|
/// Run at startup or if the user removes a Custom path from transcode page.
|
|
/// Sets global variables FFmpegPath.
|
|
/// Sets global variables FFmpegPath.
|
|
@@ -103,20 +99,23 @@ namespace MediaBrowser.MediaEncoding.Encoder
|
|
public void SetFFmpegPath()
|
|
public void SetFFmpegPath()
|
|
{
|
|
{
|
|
// 1) Custom path stored in config/encoding xml file under tag <EncoderAppPath> takes precedence
|
|
// 1) Custom path stored in config/encoding xml file under tag <EncoderAppPath> takes precedence
|
|
- if (!ValidatePath(_configurationManager.GetEncodingOptions().EncoderAppPath, FFmpegLocation.Custom))
|
|
|
|
|
|
+ var ffmpegPath = _configurationManager.GetEncodingOptions().EncoderAppPath;
|
|
|
|
+ if (string.IsNullOrEmpty(ffmpegPath))
|
|
{
|
|
{
|
|
// 2) Check if the --ffmpeg CLI switch has been given
|
|
// 2) Check if the --ffmpeg CLI switch has been given
|
|
- if (!ValidatePath(_startupOptionFFmpegPath, FFmpegLocation.SetByArgument))
|
|
|
|
|
|
+ ffmpegPath = _startupOptionFFmpegPath;
|
|
|
|
+ if (string.IsNullOrEmpty(ffmpegPath))
|
|
{
|
|
{
|
|
- // 3) Search system $PATH environment variable for valid FFmpeg
|
|
|
|
- if (!ValidatePath(ExistsOnSystemPath("ffmpeg"), FFmpegLocation.System))
|
|
|
|
- {
|
|
|
|
- EncoderLocation = FFmpegLocation.NotFound;
|
|
|
|
- _ffmpegPath = null;
|
|
|
|
- }
|
|
|
|
|
|
+ // 3) Check "ffmpeg"
|
|
|
|
+ ffmpegPath = "ffmpeg";
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ if (!ValidatePath(ffmpegPath))
|
|
|
|
+ {
|
|
|
|
+ _ffmpegPath = null;
|
|
|
|
+ }
|
|
|
|
+
|
|
// Write the FFmpeg path to the config/encoding.xml file as <EncoderAppPathDisplay> so it appears in UI
|
|
// Write the FFmpeg path to the config/encoding.xml file as <EncoderAppPathDisplay> so it appears in UI
|
|
var config = _configurationManager.GetEncodingOptions();
|
|
var config = _configurationManager.GetEncodingOptions();
|
|
config.EncoderAppPathDisplay = _ffmpegPath ?? string.Empty;
|
|
config.EncoderAppPathDisplay = _ffmpegPath ?? string.Empty;
|
|
@@ -138,10 +137,10 @@ namespace MediaBrowser.MediaEncoding.Encoder
|
|
SetAvailableHwaccels(validator.GetHwaccels());
|
|
SetAvailableHwaccels(validator.GetHwaccels());
|
|
SetMediaEncoderVersion(validator);
|
|
SetMediaEncoderVersion(validator);
|
|
|
|
|
|
- threads = EncodingHelper.GetNumberOfThreads(null, _configurationManager.GetEncodingOptions(), null);
|
|
|
|
|
|
+ _threads = EncodingHelper.GetNumberOfThreads(null, _configurationManager.GetEncodingOptions(), null);
|
|
}
|
|
}
|
|
|
|
|
|
- _logger.LogInformation("FFmpeg: {EncoderLocation}: {FfmpegPath}", EncoderLocation, _ffmpegPath ?? string.Empty);
|
|
|
|
|
|
+ _logger.LogInformation("FFmpeg: {FfmpegPath}", _ffmpegPath ?? string.Empty);
|
|
}
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// <summary>
|
|
@@ -160,15 +159,12 @@ namespace MediaBrowser.MediaEncoding.Encoder
|
|
{
|
|
{
|
|
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
|
|
// User had cleared the custom path in UI
|
|
newPath = string.Empty;
|
|
newPath = string.Empty;
|
|
}
|
|
}
|
|
- else if (File.Exists(path))
|
|
|
|
- {
|
|
|
|
- newPath = path;
|
|
|
|
- }
|
|
|
|
else if (Directory.Exists(path))
|
|
else if (Directory.Exists(path))
|
|
{
|
|
{
|
|
// Given path is directory, so resolve down to filename
|
|
// Given path is directory, so resolve down to filename
|
|
@@ -176,7 +172,7 @@ namespace MediaBrowser.MediaEncoding.Encoder
|
|
}
|
|
}
|
|
else
|
|
else
|
|
{
|
|
{
|
|
- throw new ResourceNotFoundException();
|
|
|
|
|
|
+ newPath = path;
|
|
}
|
|
}
|
|
|
|
|
|
// Write the new ffmpeg path to the xml as <EncoderAppPath>
|
|
// Write the new ffmpeg path to the xml as <EncoderAppPath>
|
|
@@ -191,37 +187,26 @@ namespace MediaBrowser.MediaEncoding.Encoder
|
|
|
|
|
|
/// <summary>
|
|
/// <summary>
|
|
/// Validates the supplied FQPN to ensure it is a ffmpeg utility.
|
|
/// Validates the supplied FQPN to ensure it is a ffmpeg utility.
|
|
- /// If checks pass, global variable FFmpegPath and EncoderLocation are updated.
|
|
|
|
|
|
+ /// If checks pass, global variable FFmpegPath is updated.
|
|
/// </summary>
|
|
/// </summary>
|
|
/// <param name="path">FQPN to test.</param>
|
|
/// <param name="path">FQPN to test.</param>
|
|
- /// <param name="location">Location (External, Custom, System) of tool.</param>
|
|
|
|
/// <returns><c>true</c> if the version validation succeeded; otherwise, <c>false</c>.</returns>
|
|
/// <returns><c>true</c> if the version validation succeeded; otherwise, <c>false</c>.</returns>
|
|
- private bool ValidatePath(string path, FFmpegLocation location)
|
|
|
|
|
|
+ private bool ValidatePath(string path)
|
|
{
|
|
{
|
|
- bool rc = false;
|
|
|
|
-
|
|
|
|
- if (!string.IsNullOrEmpty(path))
|
|
|
|
|
|
+ if (string.IsNullOrEmpty(path))
|
|
{
|
|
{
|
|
- if (File.Exists(path))
|
|
|
|
- {
|
|
|
|
- rc = new EncoderValidator(_logger, path).ValidateVersion();
|
|
|
|
-
|
|
|
|
- if (!rc)
|
|
|
|
- {
|
|
|
|
- _logger.LogWarning("FFmpeg: {Location}: Failed version check: {Path}", location, path);
|
|
|
|
- }
|
|
|
|
|
|
+ return false;
|
|
|
|
+ }
|
|
|
|
|
|
- _ffmpegPath = path;
|
|
|
|
- EncoderLocation = location;
|
|
|
|
- return true;
|
|
|
|
- }
|
|
|
|
- else
|
|
|
|
- {
|
|
|
|
- _logger.LogWarning("FFmpeg: {Location}: File not found: {Path}", location, path);
|
|
|
|
- }
|
|
|
|
|
|
+ bool rc = new EncoderValidator(_logger, path).ValidateVersion();
|
|
|
|
+ if (!rc)
|
|
|
|
+ {
|
|
|
|
+ _logger.LogWarning("FFmpeg: Failed version check: {Path}", path);
|
|
|
|
+ return false;
|
|
}
|
|
}
|
|
|
|
|
|
- return rc;
|
|
|
|
|
|
+ _ffmpegPath = path;
|
|
|
|
+ return true;
|
|
}
|
|
}
|
|
|
|
|
|
private string GetEncoderPathFromDirectory(string path, string filename, bool recursive = false)
|
|
private string GetEncoderPathFromDirectory(string path, string filename, bool recursive = false)
|
|
@@ -242,34 +227,6 @@ namespace MediaBrowser.MediaEncoding.Encoder
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
- /// <summary>
|
|
|
|
- /// Search the system $PATH environment variable looking for given filename.
|
|
|
|
- /// </summary>
|
|
|
|
- /// <param name="fileName">The filename.</param>
|
|
|
|
- /// <returns>The full path to the file.</returns>
|
|
|
|
- private string ExistsOnSystemPath(string fileName)
|
|
|
|
- {
|
|
|
|
- var inJellyfinPath = GetEncoderPathFromDirectory(AppContext.BaseDirectory, fileName, recursive: true);
|
|
|
|
- if (!string.IsNullOrEmpty(inJellyfinPath))
|
|
|
|
- {
|
|
|
|
- return inJellyfinPath;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- var values = Environment.GetEnvironmentVariable("PATH");
|
|
|
|
-
|
|
|
|
- foreach (var path in values.Split(Path.PathSeparator))
|
|
|
|
- {
|
|
|
|
- var candidatePath = GetEncoderPathFromDirectory(path, fileName);
|
|
|
|
-
|
|
|
|
- if (!string.IsNullOrEmpty(candidatePath))
|
|
|
|
- {
|
|
|
|
- return candidatePath;
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- return null;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
public void SetAvailableEncoders(IEnumerable<string> list)
|
|
public void SetAvailableEncoders(IEnumerable<string> list)
|
|
{
|
|
{
|
|
_encoders = list.ToList();
|
|
_encoders = list.ToList();
|
|
@@ -425,7 +382,7 @@ namespace MediaBrowser.MediaEncoding.Encoder
|
|
var args = extractChapters
|
|
var args = extractChapters
|
|
? "{0} -i {1} -threads {2} -v warning -print_format json -show_streams -show_chapters -show_format"
|
|
? "{0} -i {1} -threads {2} -v warning -print_format json -show_streams -show_chapters -show_format"
|
|
: "{0} -i {1} -threads {2} -v warning -print_format json -show_streams -show_format";
|
|
: "{0} -i {1} -threads {2} -v warning -print_format json -show_streams -show_format";
|
|
- args = string.Format(CultureInfo.InvariantCulture, args, probeSizeArgument, inputPath, threads).Trim();
|
|
|
|
|
|
+ args = string.Format(CultureInfo.InvariantCulture, args, probeSizeArgument, inputPath, _threads).Trim();
|
|
|
|
|
|
var process = new Process
|
|
var process = new Process
|
|
{
|
|
{
|
|
@@ -646,7 +603,7 @@ namespace MediaBrowser.MediaEncoding.Encoder
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
- var args = string.Format(CultureInfo.InvariantCulture, "-i {0}{3} -threads {4} -v quiet -vframes 1 {2} -f image2 \"{1}\"", inputPath, tempExtractPath, vf, mapArg, threads);
|
|
|
|
|
|
+ var args = string.Format(CultureInfo.InvariantCulture, "-i {0}{3} -threads {4} -v quiet -vframes 1 {2} -f image2 \"{1}\"", inputPath, tempExtractPath, vf, mapArg, _threads);
|
|
|
|
|
|
if (offset.HasValue)
|
|
if (offset.HasValue)
|
|
{
|
|
{
|
|
@@ -759,7 +716,7 @@ namespace MediaBrowser.MediaEncoding.Encoder
|
|
Directory.CreateDirectory(targetDirectory);
|
|
Directory.CreateDirectory(targetDirectory);
|
|
var outputPath = Path.Combine(targetDirectory, filenamePrefix + "%05d.jpg");
|
|
var outputPath = Path.Combine(targetDirectory, filenamePrefix + "%05d.jpg");
|
|
|
|
|
|
- var args = string.Format(CultureInfo.InvariantCulture, "-i {0} -threads {3} -v quiet {2} -f image2 \"{1}\"", inputArgument, outputPath, vf, threads);
|
|
|
|
|
|
+ var args = string.Format(CultureInfo.InvariantCulture, "-i {0} -threads {3} -v quiet {2} -f image2 \"{1}\"", inputArgument, outputPath, vf, _threads);
|
|
|
|
|
|
if (!string.IsNullOrWhiteSpace(container))
|
|
if (!string.IsNullOrWhiteSpace(container))
|
|
{
|
|
{
|