Browse Source

Merge pull request #11495 from jellyfin/workaround-tuner-head-method-405

Workarounds TV tuners rejecting HEAD method
Joshua M. Boniface 1 year ago
parent
commit
5bf738dafb
1 changed files with 29 additions and 4 deletions
  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.Collections.Generic;
 using System.Globalization;
+using System.IO;
 using System.Linq;
+using System.Net;
 using System.Net.Http;
 using System.Threading;
 using System.Threading.Tasks;
@@ -38,6 +40,14 @@ namespace Jellyfin.LiveTv.TunerHosts
             "video/vnd.mpeg.dash.mpd"
         };
 
+        private static readonly string[] _disallowedSharedStreamExtensions =
+        {
+            ".mkv",
+            ".mp4",
+            ".m3u8",
+            ".mpd"
+        };
+
         private readonly IHttpClientFactory _httpClientFactory;
         private readonly IServerApplicationHost _appHost;
         private readonly INetworkManager _networkManager;
@@ -106,11 +116,26 @@ namespace Jellyfin.LiveTv.TunerHosts
                     .SendAsync(message, cancellationToken)
                     .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();
                 }
             }