diff options
| author | Anthony Lavado <anthonylavado@users.noreply.github.com> | 2019-01-02 14:02:48 -0500 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2019-01-02 14:02:48 -0500 |
| commit | a06a5c8d18badb73df64cb09a3ab677922379823 (patch) | |
| tree | 3ae3c19fc2bb822a81c57f948043c67ea68dbd95 /MediaBrowser.MediaEncoding | |
| parent | e12888c2c5288ab2e313d74b6fad01a82720f4e2 (diff) | |
| parent | 0cafd7dfefe07bf8e1d997c384561707e1b22c6a (diff) | |
Merge branch 'dev' into project-updates
Diffstat (limited to 'MediaBrowser.MediaEncoding')
| -rw-r--r-- | MediaBrowser.MediaEncoding/Encoder/EncoderValidator.cs | 104 | ||||
| -rw-r--r-- | MediaBrowser.MediaEncoding/Encoder/FontConfigLoader.cs | 179 | ||||
| -rw-r--r-- | MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs | 41 |
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())); |
