Browse Source

Use SharedStream for LiveTV more restrictively (#11805)

gnattu 1 year ago
parent
commit
ef985896e2
1 changed files with 23 additions and 34 deletions
  1. 23 34
      src/Jellyfin.LiveTv/TunerHosts/M3UTunerHost.cs

+ 23 - 34
src/Jellyfin.LiveTv/TunerHosts/M3UTunerHost.cs

@@ -30,25 +30,8 @@ namespace Jellyfin.LiveTv.TunerHosts
 {
     public class M3UTunerHost : BaseTunerHost, ITunerHost, IConfigurableTunerHost
     {
-        private static readonly string[] _disallowedMimeTypes =
-        {
-            "text/plain",
-            "text/html",
-            "video/x-matroska",
-            "video/mp4",
-            "application/vnd.apple.mpegurl",
-            "application/mpegurl",
-            "application/x-mpegurl",
-            "video/vnd.mpeg.dash.mpd"
-        };
-
-        private static readonly string[] _disallowedSharedStreamExtensions =
-        {
-            ".mkv",
-            ".mp4",
-            ".m3u8",
-            ".mpd"
-        };
+        private static readonly string[] _mimeTypesCanShareHttpStream = ["video/MP2T"];
+        private static readonly string[] _extensionsCanShareHttpStream = [".ts", ".tsv", ".m2t"];
 
         private readonly IHttpClientFactory _httpClientFactory;
         private readonly IServerApplicationHost _appHost;
@@ -113,28 +96,34 @@ namespace Jellyfin.LiveTv.TunerHosts
 
             if (mediaSource.Protocol == MediaProtocol.Http && !mediaSource.RequiresLooping)
             {
-                using var message = new HttpRequestMessage(HttpMethod.Head, mediaSource.Path);
-                using var response = await _httpClientFactory.CreateClient(NamedClient.Default)
-                    .SendAsync(message, cancellationToken)
-                    .ConfigureAwait(false);
+                var extension = Path.GetExtension(new UriBuilder(mediaSource.Path).Path);
 
-                if (response.IsSuccessStatusCode)
+                if (string.IsNullOrEmpty(extension))
                 {
-                    if (!_disallowedMimeTypes.Contains(response.Content.Headers.ContentType?.MediaType, StringComparison.OrdinalIgnoreCase))
+                    try
                     {
-                        return new SharedHttpStream(mediaSource, tunerHost, streamId, FileSystem, _httpClientFactory, Logger, Config, _appHost, _streamHelper);
+                        using var message = new HttpRequestMessage(HttpMethod.Head, mediaSource.Path);
+                        using var response = await _httpClientFactory.CreateClient(NamedClient.Default)
+                            .SendAsync(message, cancellationToken)
+                            .ConfigureAwait(false);
+
+                        if (response.IsSuccessStatusCode)
+                        {
+                            if (_mimeTypesCanShareHttpStream.Contains(response.Content.Headers.ContentType?.MediaType, StringComparison.OrdinalIgnoreCase))
+                            {
+                                return new SharedHttpStream(mediaSource, tunerHost, streamId, FileSystem, _httpClientFactory, Logger, Config, _appHost, _streamHelper);
+                            }
+                        }
                     }
-                }
-                else
-                {
-                    // Fallback to check path extension when the server does not support HEAD method
-                    // Use UriBuilder to remove all query string as GetExtension will include them when used directly
-                    var extension = Path.GetExtension(new UriBuilder(mediaSource.Path).Path);
-                    if (!_disallowedSharedStreamExtensions.Contains(extension, StringComparison.OrdinalIgnoreCase))
+                    catch (Exception)
                     {
-                        return new SharedHttpStream(mediaSource, tunerHost, streamId, FileSystem, _httpClientFactory, Logger, Config, _appHost, _streamHelper);
+                        Logger.LogWarning("HEAD request to check MIME type failed, shared stream disabled");
                     }
                 }
+                else if (_extensionsCanShareHttpStream.Contains(extension, StringComparison.OrdinalIgnoreCase))
+                {
+                    return new SharedHttpStream(mediaSource, tunerHost, streamId, FileSystem, _httpClientFactory, Logger, Config, _appHost, _streamHelper);
+                }
             }
 
             return new LiveStream(mediaSource, tunerHost, FileSystem, Logger, Config, _streamHelper);