diff --git a/src/Jellyfin.LiveTv/TunerHosts/M3UTunerHost.cs b/src/Jellyfin.LiveTv/TunerHosts/M3UTunerHost.cs index 8d52151cbb..3307626f49 100644 --- a/src/Jellyfin.LiveTv/TunerHosts/M3UTunerHost.cs +++ b/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(); } }