Prechádzať zdrojové kódy

Make Live TV compatibility profiles customizable (#12529)

gnattu 9 mesiacov pred
rodič
commit
b4f71859d9

+ 6 - 19
Jellyfin.Api/Helpers/StreamingHelpers.cs

@@ -142,28 +142,15 @@ public static class StreamingHelpers
         }
         else
         {
-            // Enforce more restrictive transcoding profile for LiveTV due to compatability reasons
-            // Cap the MaxStreamingBitrate to 30Mbps, because we are unable to reliably probe source bitrate,
-            // which will cause the client to request extremely high bitrate that may fail the player/encoder
-            streamingRequest.VideoBitRate = streamingRequest.VideoBitRate > 30000000 ? 30000000 : streamingRequest.VideoBitRate;
-
-            if (streamingRequest.SegmentContainer is not null)
-            {
-                // Remove all fmp4 transcoding profiles, because it causes playback error and/or A/V sync issues
-                // Notably: Some channels won't play on FireFox and LG webOS
-                // Some channels from HDHomerun will experience A/V sync issues
-                streamingRequest.SegmentContainer = "ts";
-                streamingRequest.VideoCodec = "h264";
-                streamingRequest.AudioCodec = "aac";
-                state.SupportedVideoCodecs = ["h264"];
-                state.Request.VideoCodec = "h264";
-                state.SupportedAudioCodecs = ["aac"];
-                state.Request.AudioCodec = "aac";
-            }
-
             var liveStreamInfo = await mediaSourceManager.GetLiveStreamWithDirectStreamProvider(streamingRequest.LiveStreamId, cancellationToken).ConfigureAwait(false);
             mediaSource = liveStreamInfo.Item1;
             state.DirectStreamProvider = liveStreamInfo.Item2;
+
+            // Cap the max bitrate when it is too high. This is usually due to ffmpeg is unable to probe the source liveTV streams' bitrate.
+            if (mediaSource.FallbackMaxStreamingBitrate is not null && streamingRequest.VideoBitRate is not null)
+            {
+                streamingRequest.VideoBitRate = Math.Min(streamingRequest.VideoBitRate.Value, mediaSource.FallbackMaxStreamingBitrate.Value);
+            }
         }
 
         var encodingOptions = serverConfigurationManager.GetEncodingOptions();

+ 1 - 0
MediaBrowser.Model/Dlna/StreamBuilder.cs

@@ -805,6 +805,7 @@ namespace MediaBrowser.Model.Dlna
             }
 
             var transcodingProfiles = options.Profile.TranscodingProfiles
+                .Where(i => !item.UseMostCompatibleTranscodingProfile || string.Equals(i.Container, "ts", StringComparison.OrdinalIgnoreCase))
                 .Where(i => i.Type == playlistItem.MediaType && i.Context == options.Context);
 
             if (options.AllowVideoStreamCopy)

+ 7 - 0
MediaBrowser.Model/Dto/MediaSourceInfo.cs

@@ -3,6 +3,7 @@
 
 using System;
 using System.Collections.Generic;
+using System.ComponentModel;
 using System.Text.Json.Serialization;
 using Jellyfin.Data.Enums;
 using MediaBrowser.Model.Dlna;
@@ -24,6 +25,7 @@ namespace MediaBrowser.Model.Dto
             SupportsDirectStream = true;
             SupportsDirectPlay = true;
             SupportsProbing = true;
+            UseMostCompatibleTranscodingProfile = false;
         }
 
         public MediaProtocol Protocol { get; set; }
@@ -70,6 +72,9 @@ namespace MediaBrowser.Model.Dto
 
         public bool IsInfiniteStream { get; set; }
 
+        [DefaultValue(false)]
+        public bool UseMostCompatibleTranscodingProfile { get; set; }
+
         public bool RequiresOpening { get; set; }
 
         public string OpenToken { get; set; }
@@ -98,6 +103,8 @@ namespace MediaBrowser.Model.Dto
 
         public int? Bitrate { get; set; }
 
+        public int? FallbackMaxStreamingBitrate { get; set; }
+
         public TransportStreamTimestamp? Timestamp { get; set; }
 
         public Dictionary<string, string> RequiredHttpHeaders { get; set; }

+ 9 - 0
MediaBrowser.Model/LiveTv/TunerHostInfo.cs

@@ -9,6 +9,9 @@ namespace MediaBrowser.Model.LiveTv
         {
             AllowHWTranscoding = true;
             IgnoreDts = true;
+            AllowStreamSharing = true;
+            AllowFmp4TranscodingContainer = false;
+            FallbackMaxStreamingBitrate = 30000000;
         }
 
         public string Id { get; set; }
@@ -25,6 +28,12 @@ namespace MediaBrowser.Model.LiveTv
 
         public bool AllowHWTranscoding { get; set; }
 
+        public bool AllowFmp4TranscodingContainer { get; set; }
+
+        public bool AllowStreamSharing { get; set; }
+
+        public int FallbackMaxStreamingBitrate { get; set; }
+
         public bool EnableStreamLooping { get; set; }
 
         public string Source { get; set; }

+ 2 - 0
src/Jellyfin.LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs

@@ -331,6 +331,8 @@ namespace Jellyfin.LiveTv.TunerHosts.HdHomerun
                 SupportsTranscoding = true,
                 IsInfiniteStream = true,
                 IgnoreDts = true,
+                UseMostCompatibleTranscodingProfile = true, // All HDHR tuners require this
+                FallbackMaxStreamingBitrate = info.FallbackMaxStreamingBitrate,
                 // IgnoreIndex = true,
                 // ReadAtNativeFramerate = true
             };

+ 4 - 2
src/Jellyfin.LiveTv/TunerHosts/M3UTunerHost.cs

@@ -94,7 +94,7 @@ namespace Jellyfin.LiveTv.TunerHosts
 
             var mediaSource = sources[0];
 
-            if (mediaSource.Protocol == MediaProtocol.Http && !mediaSource.RequiresLooping)
+            if (tunerHost.AllowStreamSharing && mediaSource.Protocol == MediaProtocol.Http && !mediaSource.RequiresLooping)
             {
                 var extension = Path.GetExtension(new UriBuilder(mediaSource.Path).Path);
 
@@ -200,7 +200,9 @@ namespace Jellyfin.LiveTv.TunerHosts
                 SupportsDirectPlay = supportsDirectPlay,
                 SupportsDirectStream = supportsDirectStream,
 
-                RequiredHttpHeaders = httpHeaders
+                RequiredHttpHeaders = httpHeaders,
+                UseMostCompatibleTranscodingProfile = !info.AllowFmp4TranscodingContainer,
+                FallbackMaxStreamingBitrate = info.FallbackMaxStreamingBitrate
             };
 
             mediaSource.InferTotalBitrate();