From 946a5c49d060c818cb333095f8f488635a7f5e86 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Mon, 23 Sep 2013 11:37:50 -0400 Subject: #429 - Extract ffmpeg from core product --- .../MediaEncoder/MediaEncoder.cs | 232 +-------------------- 1 file changed, 10 insertions(+), 222 deletions(-) (limited to 'MediaBrowser.Server.Implementations/MediaEncoder/MediaEncoder.cs') diff --git a/MediaBrowser.Server.Implementations/MediaEncoder/MediaEncoder.cs b/MediaBrowser.Server.Implementations/MediaEncoder/MediaEncoder.cs index 5792806d8..b24c9a5ca 100644 --- a/MediaBrowser.Server.Implementations/MediaEncoder/MediaEncoder.cs +++ b/MediaBrowser.Server.Implementations/MediaEncoder/MediaEncoder.cs @@ -1,9 +1,7 @@ using MediaBrowser.Common.Configuration; using MediaBrowser.Common.IO; using MediaBrowser.Common.MediaInfo; -using MediaBrowser.Common.Net; using MediaBrowser.Model.Entities; -using MediaBrowser.Model.IO; using MediaBrowser.Model.Logging; using MediaBrowser.Model.Serialization; using System; @@ -13,7 +11,6 @@ using System.Diagnostics; using System.Globalization; using System.IO; using System.Linq; -using System.Reflection; using System.Runtime.InteropServices; using System.Text; using System.Threading; @@ -26,12 +23,6 @@ namespace MediaBrowser.Server.Implementations.MediaEncoder /// public class MediaEncoder : IMediaEncoder, IDisposable { - /// - /// Gets or sets the zip client. - /// - /// The zip client. - private readonly IZipClient _zipClient; - /// /// The _logger /// @@ -48,8 +39,6 @@ namespace MediaBrowser.Server.Implementations.MediaEncoder /// The json serializer. private readonly IJsonSerializer _jsonSerializer; - private readonly IHttpClient _httpClient; - /// /// The video image resource pool /// @@ -70,50 +59,25 @@ namespace MediaBrowser.Server.Implementations.MediaEncoder /// private readonly SemaphoreSlim _ffProbeResourcePool = new SemaphoreSlim(2, 2); - /// - /// Gets or sets the versioned directory path. - /// - /// The versioned directory path. - private string VersionedDirectoryPath { get; set; } + public string FFMpegPath { get; private set; } - /// - /// Initializes a new instance of the class. - /// - /// The logger. - /// The zip client. - /// The app paths. - /// The json serializer. - public MediaEncoder(ILogger logger, IZipClient zipClient, IApplicationPaths appPaths, - IJsonSerializer jsonSerializer, IHttpClient httpClient) + public string FFProbePath { get; private set; } + + public string Version { get; private set; } + + public MediaEncoder(ILogger logger, IApplicationPaths appPaths, + IJsonSerializer jsonSerializer, string ffMpegPath, string ffProbePath, string version) { _logger = logger; - _zipClient = zipClient; _appPaths = appPaths; _jsonSerializer = jsonSerializer; - _httpClient = httpClient; + Version = version; + FFProbePath = ffProbePath; + FFMpegPath = ffMpegPath; // Not crazy about this but it's the only way to suppress ffmpeg crash dialog boxes SetErrorMode(ErrorModes.SEM_FAILCRITICALERRORS | ErrorModes.SEM_NOALIGNMENTFAULTEXCEPT | ErrorModes.SEM_NOGPFAULTERRORBOX | ErrorModes.SEM_NOOPENFILEERRORBOX); - - Task.Run(() => VersionedDirectoryPath = GetVersionedDirectoryPath()); - } - - /// - /// Gets the media tools path. - /// - /// if set to true [create]. - /// System.String. - private string GetMediaToolsPath(bool create) - { - var path = Path.Combine(_appPaths.ProgramDataPath, "ffmpeg"); - - if (create && !Directory.Exists(path)) - { - Directory.CreateDirectory(path); - } - - return path; } /// @@ -125,182 +89,6 @@ namespace MediaBrowser.Server.Implementations.MediaEncoder get { return FFMpegPath; } } - /// - /// The _ FF MPEG path - /// - private string _FFMpegPath; - - /// - /// Gets the path to ffmpeg.exe - /// - /// The FF MPEG path. - public string FFMpegPath - { - get { return _FFMpegPath ?? (_FFMpegPath = Path.Combine(VersionedDirectoryPath, "ffmpeg.exe")); } - } - - /// - /// The _ FF probe path - /// - private string _FFProbePath; - - /// - /// Gets the path to ffprobe.exe - /// - /// The FF probe path. - private string FFProbePath - { - get { return _FFProbePath ?? (_FFProbePath = Path.Combine(VersionedDirectoryPath, "ffprobe.exe")); } - } - - /// - /// Gets the version. - /// - /// The version. - public string Version - { - get { return Path.GetFileNameWithoutExtension(VersionedDirectoryPath); } - } - - /// - /// Gets the versioned directory path. - /// - /// System.String. - private string GetVersionedDirectoryPath() - { - var assembly = GetType().Assembly; - - var prefix = GetType().Namespace + "."; - - var srch = prefix + "ffmpeg"; - - var resource = assembly.GetManifestResourceNames().First(r => r.StartsWith(srch)); - - var filename = - resource.Substring(resource.IndexOf(prefix, StringComparison.OrdinalIgnoreCase) + prefix.Length); - - var versionedDirectoryPath = Path.Combine(GetMediaToolsPath(true), - Path.GetFileNameWithoutExtension(filename)); - - if (!Directory.Exists(versionedDirectoryPath)) - { - Directory.CreateDirectory(versionedDirectoryPath); - } - - ExtractTools(assembly, resource, versionedDirectoryPath); - - return versionedDirectoryPath; - } - - /// - /// Extracts the tools. - /// - /// The assembly. - /// The zip file resource path. - /// The target path. - private async void ExtractTools(Assembly assembly, string zipFileResourcePath, string targetPath) - { - using (var resourceStream = assembly.GetManifestResourceStream(zipFileResourcePath)) - { - _zipClient.ExtractAll(resourceStream, targetPath, false); - } - - try - { - await DownloadFonts(targetPath).ConfigureAwait(false); - } - catch (Exception ex) - { - _logger.ErrorException("Error getting ffmpeg font files", ex); - } - } - - private const string FontUrl = "https://www.dropbox.com/s/9nb76tybcsw5xrk/ARIALUNI.zip?dl=1"; - - /// - /// Extracts the fonts. - /// - /// The target path. - private async Task DownloadFonts(string targetPath) - { - var fontsDirectory = Path.Combine(targetPath, "fonts"); - - if (!Directory.Exists(fontsDirectory)) - { - Directory.CreateDirectory(fontsDirectory); - } - - const string fontFilename = "ARIALUNI.TTF"; - - var fontFile = Path.Combine(fontsDirectory, fontFilename); - - if (!File.Exists(fontFile)) - { - await DownloadFontFile(fontsDirectory, fontFilename).ConfigureAwait(false); - } - - await WriteFontConfigFile(fontsDirectory).ConfigureAwait(false); - } - - private async Task DownloadFontFile(string fontsDirectory, string fontFilename) - { - var existingFile = Directory - .EnumerateFiles(_appPaths.ProgramDataPath, fontFilename, SearchOption.AllDirectories) - .FirstOrDefault(); - - if (existingFile != null) - { - try - { - File.Copy(existingFile, Path.Combine(fontsDirectory, fontFilename), true); - return; - } - catch (IOException ex) - { - // Log this, but don't let it fail the operation - _logger.ErrorException("Error copying file", ex); - } - } - - var tempFile = await _httpClient.GetTempFile(new HttpRequestOptions - { - Url = FontUrl, - Progress = new Progress() - }); - - _zipClient.ExtractAll(tempFile, fontsDirectory, true); - - try - { - File.Delete(tempFile); - } - catch (IOException ex) - { - // Log this, but don't let it fail the operation - _logger.ErrorException("Error deleting temp file {0}", ex, tempFile); - } - } - - private async Task WriteFontConfigFile(string fontsDirectory) - { - const string fontConfigFilename = "fonts.conf"; - var fontConfigFile = Path.Combine(fontsDirectory, fontConfigFilename); - - if (!File.Exists(fontConfigFile)) - { - var contents = string.Format("{0}ArialArial Unicode MS", fontsDirectory); - - var bytes = Encoding.UTF8.GetBytes(contents); - - using (var fileStream = new FileStream(fontConfigFile, FileMode.Create, FileAccess.Write, - FileShare.Read, StreamDefaults.DefaultFileStreamBufferSize, - FileOptions.Asynchronous)) - { - await fileStream.WriteAsync(bytes, 0, bytes.Length); - } - } - } - /// /// Gets the media info. /// -- cgit v1.2.3