aboutsummaryrefslogtreecommitdiff
path: root/MediaBrowser.MediaEncoding
diff options
context:
space:
mode:
authorAnthony Lavado <anthonylavado@users.noreply.github.com>2019-01-02 14:02:48 -0500
committerGitHub <noreply@github.com>2019-01-02 14:02:48 -0500
commita06a5c8d18badb73df64cb09a3ab677922379823 (patch)
tree3ae3c19fc2bb822a81c57f948043c67ea68dbd95 /MediaBrowser.MediaEncoding
parente12888c2c5288ab2e313d74b6fad01a82720f4e2 (diff)
parent0cafd7dfefe07bf8e1d997c384561707e1b22c6a (diff)
Merge branch 'dev' into project-updates
Diffstat (limited to 'MediaBrowser.MediaEncoding')
-rw-r--r--MediaBrowser.MediaEncoding/Encoder/EncoderValidator.cs104
-rw-r--r--MediaBrowser.MediaEncoding/Encoder/FontConfigLoader.cs179
-rw-r--r--MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs41
3 files changed, 62 insertions, 262 deletions
diff --git a/MediaBrowser.MediaEncoding/Encoder/EncoderValidator.cs b/MediaBrowser.MediaEncoding/Encoder/EncoderValidator.cs
index fb131f304..b68961889 100644
--- a/MediaBrowser.MediaEncoding/Encoder/EncoderValidator.cs
+++ b/MediaBrowser.MediaEncoding/Encoder/EncoderValidator.cs
@@ -1,7 +1,8 @@
using System;
using System.Collections.Generic;
-using System.Diagnostics;
using System.Globalization;
+using System.Linq;
+using System.Text.RegularExpressions;
using MediaBrowser.Model.Diagnostics;
using Microsoft.Extensions.Logging;
@@ -18,21 +19,21 @@ namespace MediaBrowser.MediaEncoding.Encoder
_processFactory = processFactory;
}
- public Tuple<List<string>, List<string>> Validate(string encoderPath)
+ public (IEnumerable<string> decoders, IEnumerable<string> encoders) Validate(string encoderPath)
{
- _logger.LogInformation("Validating media encoder at {0}", encoderPath);
+ _logger.LogInformation("Validating media encoder at {EncoderPath}", encoderPath);
- var decoders = GetDecoders(encoderPath);
- var encoders = GetEncoders(encoderPath);
+ var decoders = GetCodecs(encoderPath, Codec.Decoder);
+ var encoders = GetCodecs(encoderPath, Codec.Encoder);
_logger.LogInformation("Encoder validation complete");
- return new Tuple<List<string>, List<string>>(decoders, encoders);
+ return (decoders, encoders);
}
public bool ValidateVersion(string encoderAppPath, bool logOutput)
{
- string output = string.Empty;
+ string output = null;
try
{
output = GetProcessOutput(encoderAppPath, "-version");
@@ -71,20 +72,7 @@ namespace MediaBrowser.MediaEncoding.Encoder
return true;
}
- private List<string> GetDecoders(string encoderAppPath)
- {
- string output = string.Empty;
- try
- {
- output = GetProcessOutput(encoderAppPath, "-decoders");
- }
- catch (Exception ex)
- {
- _logger.LogError(ex, "Error detecting available decoders");
- }
-
- var found = new List<string>();
- var required = new[]
+ private static readonly string[] requiredDecoders = new[]
{
"mpeg2video",
"h264_qsv",
@@ -101,33 +89,7 @@ namespace MediaBrowser.MediaEncoding.Encoder
"hevc"
};
- foreach (var codec in required)
- {
- var srch = " " + codec + " ";
-
- if (output.IndexOf(srch, StringComparison.OrdinalIgnoreCase) != -1)
- {
- _logger.LogInformation("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[]
+ private static readonly string[] requiredEncoders = new[]
{
"libx264",
"libx265",
@@ -151,32 +113,46 @@ namespace MediaBrowser.MediaEncoding.Encoder
"ac3"
};
- output = output ?? string.Empty;
+ private enum Codec
+ {
+ Encoder,
+ Decoder
+ }
- var index = 0;
+ private IEnumerable<string> GetCodecs(string encoderAppPath, Codec codec)
+ {
+ string codecstr = codec == Codec.Encoder ? "encoders" : "decoders";
+ string output = null;
+ try
+ {
+ output = GetProcessOutput(encoderAppPath, "-" + codecstr);
+ }
+ catch (Exception ex)
+ {
+ _logger.LogError(ex, "Error detecting available {Codec}", codecstr);
+ }
- foreach (var codec in required)
+ if (string.IsNullOrWhiteSpace(output))
{
- var srch = " " + codec + " ";
+ return Enumerable.Empty<string>();
+ }
- if (output.IndexOf(srch, StringComparison.OrdinalIgnoreCase) != -1)
- {
- if (index < required.Length - 1)
- {
- _logger.LogInformation("Encoder available: " + codec);
- }
+ var required = codec == Codec.Encoder ? requiredEncoders : requiredDecoders;
- found.Add(codec);
- }
- index++;
- }
+ var found = Regex
+ .Matches(output, @"^\s\S{6}\s(?<codec>[\w|-]+)\s+.+$", RegexOptions.Multiline)
+ .Cast<Match>()
+ .Select(x => x.Groups["codec"].Value)
+ .Where(x => required.Contains(x));
+
+ _logger.LogInformation("Available {Codec}: {Codecs}", codecstr, found);
return found;
}
private string GetProcessOutput(string path, string arguments)
{
- var process = _processFactory.Create(new ProcessOptions
+ IProcess process = _processFactory.Create(new ProcessOptions
{
CreateNoWindow = true,
UseShellExecute = false,
@@ -187,7 +163,7 @@ namespace MediaBrowser.MediaEncoding.Encoder
RedirectStandardOutput = true
});
- _logger.LogInformation("Running {path} {arguments}", path, arguments);
+ _logger.LogInformation("Running {Path} {Arguments}", path, arguments);
using (process)
{
diff --git a/MediaBrowser.MediaEncoding/Encoder/FontConfigLoader.cs b/MediaBrowser.MediaEncoding/Encoder/FontConfigLoader.cs
deleted file mode 100644
index c62de0b11..000000000
--- a/MediaBrowser.MediaEncoding/Encoder/FontConfigLoader.cs
+++ /dev/null
@@ -1,179 +0,0 @@
-using System;
-using System.IO;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-using MediaBrowser.Common.Configuration;
-using MediaBrowser.Common.Net;
-using MediaBrowser.Common.Progress;
-using MediaBrowser.Model.IO;
-using MediaBrowser.Model.Net;
-using Microsoft.Extensions.Logging;
-
-namespace MediaBrowser.MediaEncoding.Encoder
-{
- public class FontConfigLoader
- {
- private readonly IHttpClient _httpClient;
- private readonly IApplicationPaths _appPaths;
- private readonly ILogger _logger;
- private readonly IZipClient _zipClient;
- private readonly IFileSystem _fileSystem;
-
- private readonly string[] _fontUrls =
- {
- "https://github.com/MediaBrowser/MediaBrowser.Resources/raw/master/ffmpeg/ARIALUNI.7z"
- };
-
- public FontConfigLoader(IHttpClient httpClient, IApplicationPaths appPaths, ILogger logger, IZipClient zipClient, IFileSystem fileSystem)
- {
- _httpClient = httpClient;
- _appPaths = appPaths;
- _logger = logger;
- _zipClient = zipClient;
- _fileSystem = fileSystem;
- }
-
- /// <summary>
- /// Extracts the fonts.
- /// </summary>
- /// <param name="targetPath">The target path.</param>
- /// <returns>Task.</returns>
- public async Task DownloadFonts(string targetPath)
- {
- try
- {
- var fontsDirectory = Path.Combine(targetPath, "fonts");
-
- _fileSystem.CreateDirectory(fontsDirectory);
-
- const string fontFilename = "ARIALUNI.TTF";
-
- var fontFile = Path.Combine(fontsDirectory, fontFilename);
-
- if (_fileSystem.FileExists(fontFile))
- {
- await WriteFontConfigFile(fontsDirectory).ConfigureAwait(false);
- }
- else
- {
- // Kick this off, but no need to wait on it
- var task = Task.Run(async () =>
- {
- await DownloadFontFile(fontsDirectory, fontFilename, new SimpleProgress<double>()).ConfigureAwait(false);
-
- await WriteFontConfigFile(fontsDirectory).ConfigureAwait(false);
- });
- }
- }
- catch (HttpException ex)
- {
- // Don't let the server crash because of this
- _logger.LogError(ex, "Error downloading ffmpeg font files");
- }
- catch (Exception ex)
- {
- // Don't let the server crash because of this
- _logger.LogError(ex, "Error writing ffmpeg font files");
- }
- }
-
- /// <summary>
- /// Downloads the font file.
- /// </summary>
- /// <param name="fontsDirectory">The fonts directory.</param>
- /// <param name="fontFilename">The font filename.</param>
- /// <returns>Task.</returns>
- private async Task DownloadFontFile(string fontsDirectory, string fontFilename, IProgress<double> progress)
- {
- var existingFile = _fileSystem
- .GetFilePaths(_appPaths.ProgramDataPath, true)
- .FirstOrDefault(i => string.Equals(fontFilename, Path.GetFileName(i), StringComparison.OrdinalIgnoreCase));
-
- if (existingFile != null)
- {
- try
- {
- _fileSystem.CopyFile(existingFile, Path.Combine(fontsDirectory, fontFilename), true);
- return;
- }
- catch (IOException ex)
- {
- // Log this, but don't let it fail the operation
- _logger.LogError(ex, "Error copying file");
- }
- }
-
- string tempFile = null;
-
- foreach (var url in _fontUrls)
- {
- progress.Report(0);
-
- try
- {
- tempFile = await _httpClient.GetTempFile(new HttpRequestOptions
- {
- Url = url,
- Progress = progress
-
- }).ConfigureAwait(false);
-
- break;
- }
- catch (Exception ex)
- {
- // The core can function without the font file, so handle this
- _logger.LogError(ex, "Failed to download ffmpeg font file from {url}", url);
- }
- }
-
- if (string.IsNullOrEmpty(tempFile))
- {
- return;
- }
-
- Extract7zArchive(tempFile, fontsDirectory);
-
- try
- {
- _fileSystem.DeleteFile(tempFile);
- }
- catch (IOException ex)
- {
- // Log this, but don't let it fail the operation
- _logger.LogError(ex, "Error deleting temp file {path}", tempFile);
- }
- }
- private void Extract7zArchive(string archivePath, string targetPath)
- {
- _logger.LogInformation("Extracting {ArchivePath} to {TargetPath}", archivePath, targetPath);
-
- _zipClient.ExtractAllFrom7z(archivePath, targetPath, true);
- }
-
- /// <summary>
- /// Writes the font config file.
- /// </summary>
- /// <param name="fontsDirectory">The fonts directory.</param>
- /// <returns>Task.</returns>
- private async Task WriteFontConfigFile(string fontsDirectory)
- {
- const string fontConfigFilename = "fonts.conf";
- var fontConfigFile = Path.Combine(fontsDirectory, fontConfigFilename);
-
- if (!_fileSystem.FileExists(fontConfigFile))
- {
- var contents = string.Format("<?xml version=\"1.0\"?><fontconfig><dir>{0}</dir><alias><family>Arial</family><prefer>Arial Unicode MS</prefer></alias></fontconfig>", fontsDirectory);
-
- var bytes = Encoding.UTF8.GetBytes(contents);
-
- using (var fileStream = _fileSystem.GetFileStream(fontConfigFile, FileOpenMode.Create, FileAccessMode.Write,
- FileShareMode.Read, true))
- {
- await fileStream.WriteAsync(bytes, 0, bytes.Length);
- }
- }
- }
- }
-}
diff --git a/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs b/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs
index 181fc0f65..a93dd9742 100644
--- a/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs
+++ b/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs
@@ -70,13 +70,27 @@ namespace MediaBrowser.MediaEncoding.Encoder
private readonly string _originalFFMpegPath;
private readonly string _originalFFProbePath;
private readonly int DefaultImageExtractionTimeoutMs;
- private readonly bool EnableEncoderFontFile;
-
private readonly IEnvironmentInfo _environmentInfo;
- 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, IProcessFactory processFactory,
+ 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,
+ IProcessFactory processFactory,
int defaultImageExtractionTimeoutMs,
- bool enableEncoderFontFile, IEnvironmentInfo environmentInfo)
+ IEnvironmentInfo environmentInfo)
{
_logger = logger;
_jsonSerializer = jsonSerializer;
@@ -93,7 +107,6 @@ namespace MediaBrowser.MediaEncoding.Encoder
_zipClient = zipClient;
_processFactory = processFactory;
DefaultImageExtractionTimeoutMs = defaultImageExtractionTimeoutMs;
- EnableEncoderFontFile = enableEncoderFontFile;
_environmentInfo = environmentInfo;
FFProbePath = ffProbePath;
FFMpegPath = ffMpegPath;
@@ -175,18 +188,8 @@ namespace MediaBrowser.MediaEncoding.Encoder
{
var result = new EncoderValidator(_logger, _processFactory).Validate(FFMpegPath);
- SetAvailableDecoders(result.Item1);
- SetAvailableEncoders(result.Item2);
-
- if (EnableEncoderFontFile)
- {
- var directory = FileSystem.GetDirectoryName(FFMpegPath);
-
- if (!string.IsNullOrWhiteSpace(directory) && FileSystem.ContainsSubPath(ConfigurationManager.ApplicationPaths.ProgramDataPath, directory))
- {
- new FontConfigLoader(_httpClient, ConfigurationManager.ApplicationPaths, _logger, _zipClient, FileSystem).DownloadFonts(directory).ConfigureAwait(false);
- }
- }
+ SetAvailableDecoders(result.decoders);
+ SetAvailableEncoders(result.encoders);
}
}
@@ -401,14 +404,14 @@ namespace MediaBrowser.MediaEncoding.Encoder
}
private List<string> _encoders = new List<string>();
- public void SetAvailableEncoders(List<string> list)
+ public void SetAvailableEncoders(IEnumerable<string> list)
{
_encoders = list.ToList();
//_logger.Info("Supported encoders: {0}", string.Join(",", list.ToArray()));
}
private List<string> _decoders = new List<string>();
- public void SetAvailableDecoders(List<string> list)
+ public void SetAvailableDecoders(IEnumerable<string> list)
{
_decoders = list.ToList();
//_logger.Info("Supported decoders: {0}", string.Join(",", list.ToArray()));