Jelajahi Sumber

Workarounds TV tuners rejecting HEAD method

Fallback to the old behavior of checking path extension when 405 occurs on HEAD request. Required as the TV Tuner's http sever is not always properly implemented.

Signed-off-by: gnattu <gnattuoc@me.com>
gnattu 1 tahun lalu
induk
melakukan
e355c7bfb5
1 mengubah file dengan 29 tambahan dan 4 penghapusan
  1. 29 4
      src/Jellyfin.LiveTv/TunerHosts/M3UTunerHost.cs

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

@@ -5,7 +5,9 @@
 using System;
 using System;
 using System.Collections.Generic;
 using System.Collections.Generic;
 using System.Globalization;
 using System.Globalization;
+using System.IO;
 using System.Linq;
 using System.Linq;
+using System.Net;
 using System.Net.Http;
 using System.Net.Http;
 using System.Threading;
 using System.Threading;
 using System.Threading.Tasks;
 using System.Threading.Tasks;
@@ -38,6 +40,14 @@ namespace Jellyfin.LiveTv.TunerHosts
             "video/vnd.mpeg.dash.mpd"
             "video/vnd.mpeg.dash.mpd"
         };
         };
 
 
+        private static readonly string[] _disallowedSharedStreamExtensions =
+        {
+            ".mkv",
+            ".mp4",
+            ".m3u8",
+            ".mpd"
+        };
+
         private readonly IHttpClientFactory _httpClientFactory;
         private readonly IHttpClientFactory _httpClientFactory;
         private readonly IServerApplicationHost _appHost;
         private readonly IServerApplicationHost _appHost;
         private readonly INetworkManager _networkManager;
         private readonly INetworkManager _networkManager;
@@ -106,11 +116,26 @@ namespace Jellyfin.LiveTv.TunerHosts
                     .SendAsync(message, cancellationToken)
                     .SendAsync(message, cancellationToken)
                     .ConfigureAwait(false);
                     .ConfigureAwait(false);
 
 
-                response.EnsureSuccessStatusCode();
-
-                if (!_disallowedMimeTypes.Contains(response.Content.Headers.ContentType?.ToString(), StringComparison.OrdinalIgnoreCase))
+                if (response.IsSuccessStatusCode)
+                {
+                    if (!_disallowedMimeTypes.Contains(response.Content.Headers.ContentType?.ToString(), StringComparison.OrdinalIgnoreCase))
+                    {
+                        return new SharedHttpStream(mediaSource, tunerHost, streamId, FileSystem, _httpClientFactory, Logger, Config, _appHost, _streamHelper);
+                    }
+                }
+                else if (response.StatusCode == HttpStatusCode.MethodNotAllowed)
+                {
+                    // 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))
+                    {
+                        return new SharedHttpStream(mediaSource, tunerHost, streamId, FileSystem, _httpClientFactory, Logger, Config, _appHost, _streamHelper);
+                    }
+                }
+                else
                 {
                 {
-                    return new SharedHttpStream(mediaSource, tunerHost, streamId, FileSystem, _httpClientFactory, Logger, Config, _appHost, _streamHelper);
+                    response.EnsureSuccessStatusCode();
                 }
                 }
             }
             }