mirror of
https://github.com/jellyfin/jellyfin.git
synced 2025-07-09 03:04:24 -04:00
Do HEAD request to get content type instead of checking for extension (#8823)
This commit is contained in:
parent
3d635269eb
commit
f954dc5c96
@ -30,12 +30,14 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts
|
|||||||
{
|
{
|
||||||
public class M3UTunerHost : BaseTunerHost, ITunerHost, IConfigurableTunerHost
|
public class M3UTunerHost : BaseTunerHost, ITunerHost, IConfigurableTunerHost
|
||||||
{
|
{
|
||||||
private static readonly string[] _disallowedSharedStreamExtensions =
|
private static readonly string[] _disallowedMimeTypes =
|
||||||
{
|
{
|
||||||
".mkv",
|
"video/x-matroska",
|
||||||
".mp4",
|
"video/mp4",
|
||||||
".m3u8",
|
"application/vnd.apple.mpegurl",
|
||||||
".mpd"
|
"application/mpegurl",
|
||||||
|
"application/x-mpegurl",
|
||||||
|
"video/vnd.mpeg.dash.mpd"
|
||||||
};
|
};
|
||||||
|
|
||||||
private readonly IHttpClientFactory _httpClientFactory;
|
private readonly IHttpClientFactory _httpClientFactory;
|
||||||
@ -118,9 +120,14 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts
|
|||||||
|
|
||||||
if (mediaSource.Protocol == MediaProtocol.Http && !mediaSource.RequiresLooping)
|
if (mediaSource.Protocol == MediaProtocol.Http && !mediaSource.RequiresLooping)
|
||||||
{
|
{
|
||||||
var extension = Path.GetExtension(mediaSource.Path) ?? string.Empty;
|
using var message = new HttpRequestMessage(HttpMethod.Head, mediaSource.Path);
|
||||||
|
using var response = await _httpClientFactory.CreateClient(NamedClient.Default)
|
||||||
|
.SendAsync(message, cancellationToken)
|
||||||
|
.ConfigureAwait(false);
|
||||||
|
|
||||||
if (!_disallowedSharedStreamExtensions.Contains(extension, StringComparison.OrdinalIgnoreCase))
|
response.EnsureSuccessStatusCode();
|
||||||
|
|
||||||
|
if (!_disallowedMimeTypes.Contains(response.Content.Headers.ContentType?.ToString(), StringComparison.OrdinalIgnoreCase))
|
||||||
{
|
{
|
||||||
return new SharedHttpStream(mediaSource, tunerHost, streamId, FileSystem, _httpClientFactory, Logger, Config, _appHost, _streamHelper);
|
return new SharedHttpStream(mediaSource, tunerHost, streamId, FileSystem, _httpClientFactory, Logger, Config, _appHost, _streamHelper);
|
||||||
}
|
}
|
||||||
|
@ -38,7 +38,6 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts
|
|||||||
_httpClientFactory = httpClientFactory;
|
_httpClientFactory = httpClientFactory;
|
||||||
_appHost = appHost;
|
_appHost = appHost;
|
||||||
OriginalStreamId = originalStreamId;
|
OriginalStreamId = originalStreamId;
|
||||||
EnableStreamSharing = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override async Task Open(CancellationToken openCancellationToken)
|
public override async Task Open(CancellationToken openCancellationToken)
|
||||||
@ -59,39 +58,13 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts
|
|||||||
.GetAsync(url, HttpCompletionOption.ResponseHeadersRead, CancellationToken.None)
|
.GetAsync(url, HttpCompletionOption.ResponseHeadersRead, CancellationToken.None)
|
||||||
.ConfigureAwait(false);
|
.ConfigureAwait(false);
|
||||||
|
|
||||||
var contentType = response.Content.Headers.ContentType?.ToString() ?? string.Empty;
|
|
||||||
if (contentType.Contains("matroska", StringComparison.OrdinalIgnoreCase)
|
|
||||||
|| contentType.Contains("mp4", StringComparison.OrdinalIgnoreCase)
|
|
||||||
|| contentType.Contains("dash", StringComparison.OrdinalIgnoreCase)
|
|
||||||
|| contentType.Contains("mpegURL", StringComparison.OrdinalIgnoreCase)
|
|
||||||
|| contentType.Contains("text/", StringComparison.OrdinalIgnoreCase))
|
|
||||||
{
|
|
||||||
// Close the stream without any sharing features
|
|
||||||
response.Dispose();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
SetTempFilePath("ts");
|
|
||||||
|
|
||||||
var taskCompletionSource = new TaskCompletionSource<bool>(TaskCreationOptions.RunContinuationsAsynchronously);
|
var taskCompletionSource = new TaskCompletionSource<bool>(TaskCreationOptions.RunContinuationsAsynchronously);
|
||||||
|
|
||||||
_ = StartStreaming(response, taskCompletionSource, LiveStreamCancellationTokenSource.Token);
|
_ = StartStreaming(response, taskCompletionSource, LiveStreamCancellationTokenSource.Token);
|
||||||
|
|
||||||
// OpenedMediaSource.Protocol = MediaProtocol.File;
|
|
||||||
// OpenedMediaSource.Path = tempFile;
|
|
||||||
// OpenedMediaSource.ReadAtNativeFramerate = true;
|
|
||||||
|
|
||||||
MediaSource.Path = _appHost.GetApiUrlForLocalAccess() + "/LiveTv/LiveStreamFiles/" + UniqueId + "/stream.ts";
|
MediaSource.Path = _appHost.GetApiUrlForLocalAccess() + "/LiveTv/LiveStreamFiles/" + UniqueId + "/stream.ts";
|
||||||
MediaSource.Protocol = MediaProtocol.Http;
|
MediaSource.Protocol = MediaProtocol.Http;
|
||||||
|
|
||||||
// OpenedMediaSource.Path = TempFilePath;
|
|
||||||
// OpenedMediaSource.Protocol = MediaProtocol.File;
|
|
||||||
|
|
||||||
// OpenedMediaSource.Path = _tempFilePath;
|
|
||||||
// OpenedMediaSource.Protocol = MediaProtocol.File;
|
|
||||||
// OpenedMediaSource.SupportsDirectPlay = false;
|
|
||||||
// OpenedMediaSource.SupportsDirectStream = true;
|
|
||||||
// OpenedMediaSource.SupportsTranscoding = true;
|
|
||||||
var res = await taskCompletionSource.Task.ConfigureAwait(false);
|
var res = await taskCompletionSource.Task.ConfigureAwait(false);
|
||||||
if (!res)
|
if (!res)
|
||||||
{
|
{
|
||||||
@ -108,15 +81,17 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
Logger.LogInformation("Beginning {StreamType} stream to {FilePath}", GetType().Name, TempFilePath);
|
Logger.LogInformation("Beginning {StreamType} stream to {FilePath}", GetType().Name, TempFilePath);
|
||||||
using var message = response;
|
using (response)
|
||||||
await using var stream = await response.Content.ReadAsStreamAsync(cancellationToken).ConfigureAwait(false);
|
{
|
||||||
await using var fileStream = new FileStream(TempFilePath, FileMode.Create, FileAccess.Write, FileShare.Read, IODefaults.FileStreamBufferSize, FileOptions.Asynchronous);
|
await using var stream = await response.Content.ReadAsStreamAsync(cancellationToken).ConfigureAwait(false);
|
||||||
await StreamHelper.CopyToAsync(
|
await using var fileStream = new FileStream(TempFilePath, FileMode.Create, FileAccess.Write, FileShare.Read, IODefaults.FileStreamBufferSize, FileOptions.Asynchronous);
|
||||||
stream,
|
await StreamHelper.CopyToAsync(
|
||||||
fileStream,
|
stream,
|
||||||
IODefaults.CopyToBufferSize,
|
fileStream,
|
||||||
() => Resolve(openTaskCompletionSource),
|
IODefaults.CopyToBufferSize,
|
||||||
cancellationToken).ConfigureAwait(false);
|
() => Resolve(openTaskCompletionSource),
|
||||||
|
cancellationToken).ConfigureAwait(false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
catch (OperationCanceledException ex)
|
catch (OperationCanceledException ex)
|
||||||
{
|
{
|
||||||
|
Loading…
x
Reference in New Issue
Block a user