소스 검색

Use FFmpeg concat for DVD and BD folder playback

Shadowghost 2 년 전
부모
커밋
edf3909157

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

@@ -323,6 +323,11 @@ public class TranscodingJobHelper : IDisposable
         if (delete(job.Path!))
         {
             await DeletePartialStreamFiles(job.Path!, job.Type, 0, 1500).ConfigureAwait(false);
+            if (job.MediaSource?.VideoType == VideoType.Dvd || job.MediaSource?.VideoType == VideoType.BluRay)
+            {
+                var path = Path.GetDirectoryName(job.Path) + "/" + job.MediaSource.Id + ".concat";
+                File.Delete(path);
+            }
         }
 
         if (closeLiveStream && !string.IsNullOrWhiteSpace(job.LiveStreamId))

+ 12 - 2
MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs

@@ -941,8 +941,18 @@ namespace MediaBrowser.Controller.MediaEncoding
                 arg.Append(canvasArgs);
             }
 
-            arg.Append(" -i ")
-                .Append(GetInputPathArgument(state));
+            if (state.MediaSource.VideoType == VideoType.Dvd || state.MediaSource.VideoType == VideoType.BluRay)
+            {
+                var tmpConcatPath = options.TranscodingTempPath + "/" + state.MediaSource.Id + ".concat";
+                _mediaEncoder.GenerateConcatConfig(state.MediaSource, tmpConcatPath);
+                arg.Append(" -f concat -safe 0 ");
+                arg.Append(" -i " + tmpConcatPath + " ");
+            }
+            else
+            {
+                arg.Append(" -i ")
+                    .Append(GetInputPathArgument(state));
+            }
 
             // sub2video for external graphical subtitles
             if (state.SubtitleStream is not null

+ 7 - 0
MediaBrowser.Controller/MediaEncoding/IMediaEncoder.cs

@@ -211,5 +211,12 @@ namespace MediaBrowser.Controller.MediaEncoding
         /// <param name="titleNumber">The title number to start with.</param>
         /// <returns>A playlist.</returns>
         IEnumerable<string> GetPrimaryPlaylistM2TsFiles(string path, uint? titleNumber);
+
+        /// <summary>
+        /// Generates a FFmpeg concat config for the source.
+        /// </summary>
+        /// <param name="source">The <see cref="MediaSourceInfo"/>.</param>
+        /// <param name="concatFilePath">The path the config should be written to.</param>
+        void GenerateConcatConfig(MediaSourceInfo source, string concatFilePath);
     }
 }

+ 40 - 0
MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs

@@ -918,6 +918,46 @@ namespace MediaBrowser.MediaEncoding.Encoder
                 .Select(f => f.FullName);
         }
 
+        public void GenerateConcatConfig(MediaSourceInfo source, string concatFilePath)
+        {
+            var files = new List<string>();
+            var videoType = source.VideoType;
+            if (videoType == VideoType.Dvd)
+            {
+                files = GetPrimaryPlaylistVobFiles(source.Path, null).ToList();
+            }
+            else if (videoType == VideoType.BluRay)
+            {
+                files = GetPrimaryPlaylistM2TsFiles(source.Path, null).ToList();
+            }
+
+            var lines = new List<string>();
+
+            foreach (var path in files)
+            {
+                var fileinfo = _fileSystem.GetFileInfo(path);
+                var mediaInfoResult = GetMediaInfo(
+                    new MediaInfoRequest
+                    {
+                        MediaType = DlnaProfileType.Video,
+                        MediaSource = new MediaSourceInfo
+                        {
+                            Path = path,
+                            Protocol = MediaProtocol.File,
+                            VideoType = videoType
+                        }
+                    },
+                    CancellationToken.None).GetAwaiter().GetResult();
+
+                var duration = TimeSpan.FromTicks(mediaInfoResult.RunTimeTicks.Value).TotalSeconds;
+
+                lines.Add("file " + "'" + path + "'");
+                lines.Add("duration " + duration);
+            }
+
+            File.WriteAllLinesAsync(concatFilePath, lines, CancellationToken.None).GetAwaiter().GetResult();
+        }
+
         public bool CanExtractSubtitles(string codec)
         {
             // TODO is there ever a case when a subtitle can't be extracted??