浏览代码

add extracting attachments from external subs

Nils Fürniß 3 年之前
父节点
当前提交
6904edf68c

+ 10 - 0
Jellyfin.Api/Helpers/TranscodingJobHelper.cs

@@ -13,6 +13,7 @@ using Jellyfin.Api.Models.StreamingDtos;
 using Jellyfin.Data.Enums;
 using MediaBrowser.Common;
 using MediaBrowser.Common.Configuration;
+using MediaBrowser.Common.Extensions;
 using MediaBrowser.Controller.Configuration;
 using MediaBrowser.Controller.Library;
 using MediaBrowser.Controller.MediaEncoding;
@@ -530,6 +531,15 @@ namespace Jellyfin.Api.Helpers
             {
                 var attachmentPath = Path.Combine(_appPaths.CachePath, "attachments", state.MediaSource.Id);
                 await _attachmentExtractor.ExtractAllAttachments(state.MediaPath, state.MediaSource, attachmentPath, CancellationToken.None).ConfigureAwait(false);
+
+                if (state.SubtitleStream.IsExternal)
+                {
+                    string subtitlePath = state.SubtitleStream.Path;
+                    string subtitlePathArgument = string.Format(CultureInfo.InvariantCulture, "file:\"{0}\"", subtitlePath.Replace("\"", "\\\"", StringComparison.Ordinal));
+                    string subtitleId = subtitlePath.GetMD5().ToString("N", CultureInfo.InvariantCulture);
+
+                    await _attachmentExtractor.ExtractAllAttachmentsExternal(subtitlePathArgument, subtitleId, attachmentPath, CancellationToken.None).ConfigureAwait(false);
+                }
             }
 
             var process = new Process

+ 5 - 0
MediaBrowser.Controller/MediaEncoding/IAttachmentExtractor.cs

@@ -23,5 +23,10 @@ namespace MediaBrowser.Controller.MediaEncoding
             MediaSourceInfo mediaSource,
             string outputPath,
             CancellationToken cancellationToken);
+        Task ExtractAllAttachmentsExternal(
+            string inputArgument,
+            string id,
+            string outputPath,
+            CancellationToken cancellationToken);
     }
 }

+ 60 - 18
MediaBrowser.MediaEncoding/Attachments/AttachmentExtractor.cs

@@ -89,29 +89,63 @@ namespace MediaBrowser.MediaEncoding.Attachments
             string outputPath,
             CancellationToken cancellationToken)
         {
-            var semaphore = _semaphoreLocks.GetOrAdd(outputPath, key => new SemaphoreSlim(1, 1));
+            if (!Directory.Exists(outputPath))
+            {
+                var semaphore = _semaphoreLocks.GetOrAdd(outputPath, key => new SemaphoreSlim(1, 1));
 
-            await semaphore.WaitAsync(cancellationToken).ConfigureAwait(false);
+                await semaphore.WaitAsync(cancellationToken).ConfigureAwait(false);
 
-            try
-            {
-                if (!Directory.Exists(outputPath))
+                try
                 {
                     await ExtractAllAttachmentsInternal(
                         _mediaEncoder.GetInputArgument(inputFile, mediaSource),
                         outputPath,
+                        false,
                         cancellationToken).ConfigureAwait(false);
                 }
+                finally
+                {
+                    semaphore.Release();
+                }
             }
-            finally
+        }
+
+        public async Task ExtractAllAttachmentsExternal(
+            string inputArgument,
+            string id,
+            string outputPath,
+            CancellationToken cancellationToken)
+        {
+            if (!File.Exists(Path.Join(outputPath, id)))
             {
-                semaphore.Release();
+                var semaphore = _semaphoreLocks.GetOrAdd(outputPath, key => new SemaphoreSlim(1, 1));
+
+                await semaphore.WaitAsync(cancellationToken).ConfigureAwait(false);
+
+                try
+                {
+                    await ExtractAllAttachmentsInternal(
+                        inputArgument,
+                        outputPath,
+                        true,
+                        cancellationToken).ConfigureAwait(false);
+                }
+                finally
+                {
+                    if (Directory.Exists(outputPath))
+                    {
+                        File.Create(Path.Join(outputPath, id));
+                    }
+
+                    semaphore.Release();
+                }
             }
         }
 
         private async Task ExtractAllAttachmentsInternal(
             string inputPath,
             string outputPath,
+            bool isExternal,
             CancellationToken cancellationToken)
         {
             if (string.IsNullOrEmpty(inputPath))
@@ -124,11 +158,14 @@ namespace MediaBrowser.MediaEncoding.Attachments
                 throw new ArgumentNullException(nameof(outputPath));
             }
 
-            Directory.CreateDirectory(outputPath);
+            if (!Directory.Exists(outputPath))
+            {
+                Directory.CreateDirectory(outputPath);
+            }
 
             var processArgs = string.Format(
                 CultureInfo.InvariantCulture,
-                "-dump_attachment:t \"\" -i {0} -t 0 -f null null",
+                "-dump_attachment:t \"\" -y -i {0} -t 0 -f null null",
                 inputPath);
 
             int exitCode;
@@ -174,19 +211,24 @@ namespace MediaBrowser.MediaEncoding.Attachments
 
             if (exitCode != 0)
             {
-                failed = true;
-
-                _logger.LogWarning("Deleting extracted attachments {Path} due to failure: {ExitCode}", outputPath, exitCode);
-                try
+                if (isExternal && exitCode == 1)
                 {
-                    if (Directory.Exists(outputPath))
+                    // ffmpeg returns exitCode 1 because there is no video or audio stream
+                    // this can be ignored
+                }
+                else
+                {
+                    failed = true;
+
+                    _logger.LogWarning("Deleting extracted attachments {Path} due to failure: {ExitCode}", outputPath, exitCode);
+                    try
                     {
                         Directory.Delete(outputPath);
                     }
-                }
-                catch (IOException ex)
-                {
-                    _logger.LogError(ex, "Error deleting extracted attachments {Path}", outputPath);
+                    catch (IOException ex)
+                    {
+                        _logger.LogError(ex, "Error deleting extracted attachments {Path}", outputPath);
+                    }
                 }
             }
             else if (!Directory.Exists(outputPath))