aboutsummaryrefslogtreecommitdiff
path: root/Jellyfin.Api/Helpers
diff options
context:
space:
mode:
Diffstat (limited to 'Jellyfin.Api/Helpers')
-rw-r--r--Jellyfin.Api/Helpers/AudioHelper.cs22
-rw-r--r--Jellyfin.Api/Helpers/DynamicHlsHelper.cs12
-rw-r--r--Jellyfin.Api/Helpers/StreamingHelpers.cs239
3 files changed, 2 insertions, 271 deletions
diff --git a/Jellyfin.Api/Helpers/AudioHelper.cs b/Jellyfin.Api/Helpers/AudioHelper.cs
index 2b18c389d..926ce99dd 100644
--- a/Jellyfin.Api/Helpers/AudioHelper.cs
+++ b/Jellyfin.Api/Helpers/AudioHelper.cs
@@ -7,8 +7,6 @@ using MediaBrowser.Common.Configuration;
using MediaBrowser.Common.Extensions;
using MediaBrowser.Common.Net;
using MediaBrowser.Controller.Configuration;
-using MediaBrowser.Controller.Devices;
-using MediaBrowser.Controller.Dlna;
using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.MediaEncoding;
using MediaBrowser.Model.MediaInfo;
@@ -23,13 +21,11 @@ namespace Jellyfin.Api.Helpers;
/// </summary>
public class AudioHelper
{
- private readonly IDlnaManager _dlnaManager;
private readonly IUserManager _userManager;
private readonly ILibraryManager _libraryManager;
private readonly IMediaSourceManager _mediaSourceManager;
private readonly IServerConfigurationManager _serverConfigurationManager;
private readonly IMediaEncoder _mediaEncoder;
- private readonly IDeviceManager _deviceManager;
private readonly TranscodingJobHelper _transcodingJobHelper;
private readonly IHttpClientFactory _httpClientFactory;
private readonly IHttpContextAccessor _httpContextAccessor;
@@ -38,37 +34,31 @@ public class AudioHelper
/// <summary>
/// Initializes a new instance of the <see cref="AudioHelper"/> class.
/// </summary>
- /// <param name="dlnaManager">Instance of the <see cref="IDlnaManager"/> interface.</param>
/// <param name="userManager">Instance of the <see cref="IUserManager"/> interface.</param>
/// <param name="libraryManager">Instance of the <see cref="ILibraryManager"/> interface.</param>
/// <param name="mediaSourceManager">Instance of the <see cref="IMediaSourceManager"/> interface.</param>
/// <param name="serverConfigurationManager">Instance of the <see cref="IServerConfigurationManager"/> interface.</param>
/// <param name="mediaEncoder">Instance of the <see cref="IMediaEncoder"/> interface.</param>
- /// <param name="deviceManager">Instance of the <see cref="IDeviceManager"/> interface.</param>
/// <param name="transcodingJobHelper">Instance of <see cref="TranscodingJobHelper"/>.</param>
/// <param name="httpClientFactory">Instance of the <see cref="IHttpClientFactory"/> interface.</param>
/// <param name="httpContextAccessor">Instance of the <see cref="IHttpContextAccessor"/> interface.</param>
/// <param name="encodingHelper">Instance of <see cref="EncodingHelper"/>.</param>
public AudioHelper(
- IDlnaManager dlnaManager,
IUserManager userManager,
ILibraryManager libraryManager,
IMediaSourceManager mediaSourceManager,
IServerConfigurationManager serverConfigurationManager,
IMediaEncoder mediaEncoder,
- IDeviceManager deviceManager,
TranscodingJobHelper transcodingJobHelper,
IHttpClientFactory httpClientFactory,
IHttpContextAccessor httpContextAccessor,
EncodingHelper encodingHelper)
{
- _dlnaManager = dlnaManager;
_userManager = userManager;
_libraryManager = libraryManager;
_mediaSourceManager = mediaSourceManager;
_serverConfigurationManager = serverConfigurationManager;
_mediaEncoder = mediaEncoder;
- _deviceManager = deviceManager;
_transcodingJobHelper = transcodingJobHelper;
_httpClientFactory = httpClientFactory;
_httpContextAccessor = httpContextAccessor;
@@ -104,8 +94,6 @@ public class AudioHelper
_serverConfigurationManager,
_mediaEncoder,
_encodingHelper,
- _dlnaManager,
- _deviceManager,
_transcodingJobHelper,
transcodingJobType,
cancellationTokenSource.Token)
@@ -113,8 +101,6 @@ public class AudioHelper
if (streamingRequest.Static && state.DirectStreamProvider is not null)
{
- StreamingHelpers.AddDlnaHeaders(state, _httpContextAccessor.HttpContext.Response.Headers, true, streamingRequest.StartTimeTicks, _httpContextAccessor.HttpContext.Request, _dlnaManager);
-
var liveStreamInfo = _mediaSourceManager.GetLiveStreamInfo(streamingRequest.LiveStreamId);
if (liveStreamInfo is null)
{
@@ -129,8 +115,6 @@ public class AudioHelper
// Static remote stream
if (streamingRequest.Static && state.InputProtocol == MediaProtocol.Http)
{
- StreamingHelpers.AddDlnaHeaders(state, _httpContextAccessor.HttpContext.Response.Headers, true, streamingRequest.StartTimeTicks, _httpContextAccessor.HttpContext.Request, _dlnaManager);
-
var httpClient = _httpClientFactory.CreateClient(NamedClient.Default);
return await FileStreamResponseHelpers.GetStaticRemoteStreamResult(state, httpClient, _httpContextAccessor.HttpContext).ConfigureAwait(false);
}
@@ -141,12 +125,6 @@ public class AudioHelper
}
var outputPath = state.OutputFilePath;
- var outputPathExists = File.Exists(outputPath);
-
- var transcodingJob = _transcodingJobHelper.GetTranscodingJob(outputPath, TranscodingJobType.Progressive);
- var isTranscodeCached = outputPathExists && transcodingJob is not null;
-
- StreamingHelpers.AddDlnaHeaders(state, _httpContextAccessor.HttpContext.Response.Headers, streamingRequest.Static || isTranscodeCached, streamingRequest.StartTimeTicks, _httpContextAccessor.HttpContext.Request, _dlnaManager);
// Static stream
if (streamingRequest.Static)
diff --git a/Jellyfin.Api/Helpers/DynamicHlsHelper.cs b/Jellyfin.Api/Helpers/DynamicHlsHelper.cs
index a8df628f0..05f7d44bf 100644
--- a/Jellyfin.Api/Helpers/DynamicHlsHelper.cs
+++ b/Jellyfin.Api/Helpers/DynamicHlsHelper.cs
@@ -16,8 +16,6 @@ using MediaBrowser.Common.Configuration;
using MediaBrowser.Common.Extensions;
using MediaBrowser.Common.Net;
using MediaBrowser.Controller.Configuration;
-using MediaBrowser.Controller.Devices;
-using MediaBrowser.Controller.Dlna;
using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.MediaEncoding;
using MediaBrowser.Controller.Trickplay;
@@ -38,11 +36,9 @@ public class DynamicHlsHelper
{
private readonly ILibraryManager _libraryManager;
private readonly IUserManager _userManager;
- private readonly IDlnaManager _dlnaManager;
private readonly IMediaSourceManager _mediaSourceManager;
private readonly IServerConfigurationManager _serverConfigurationManager;
private readonly IMediaEncoder _mediaEncoder;
- private readonly IDeviceManager _deviceManager;
private readonly TranscodingJobHelper _transcodingJobHelper;
private readonly INetworkManager _networkManager;
private readonly ILogger<DynamicHlsHelper> _logger;
@@ -55,11 +51,9 @@ public class DynamicHlsHelper
/// </summary>
/// <param name="libraryManager">Instance of the <see cref="ILibraryManager"/> interface.</param>
/// <param name="userManager">Instance of the <see cref="IUserManager"/> interface.</param>
- /// <param name="dlnaManager">Instance of the <see cref="IDlnaManager"/> interface.</param>
/// <param name="mediaSourceManager">Instance of the <see cref="IMediaSourceManager"/> interface.</param>
/// <param name="serverConfigurationManager">Instance of the <see cref="IServerConfigurationManager"/> interface.</param>
/// <param name="mediaEncoder">Instance of the <see cref="IMediaEncoder"/> interface.</param>
- /// <param name="deviceManager">Instance of the <see cref="IDeviceManager"/> interface.</param>
/// <param name="transcodingJobHelper">Instance of <see cref="TranscodingJobHelper"/>.</param>
/// <param name="networkManager">Instance of the <see cref="INetworkManager"/> interface.</param>
/// <param name="logger">Instance of the <see cref="ILogger{DynamicHlsHelper}"/> interface.</param>
@@ -69,11 +63,9 @@ public class DynamicHlsHelper
public DynamicHlsHelper(
ILibraryManager libraryManager,
IUserManager userManager,
- IDlnaManager dlnaManager,
IMediaSourceManager mediaSourceManager,
IServerConfigurationManager serverConfigurationManager,
IMediaEncoder mediaEncoder,
- IDeviceManager deviceManager,
TranscodingJobHelper transcodingJobHelper,
INetworkManager networkManager,
ILogger<DynamicHlsHelper> logger,
@@ -83,11 +75,9 @@ public class DynamicHlsHelper
{
_libraryManager = libraryManager;
_userManager = userManager;
- _dlnaManager = dlnaManager;
_mediaSourceManager = mediaSourceManager;
_serverConfigurationManager = serverConfigurationManager;
_mediaEncoder = mediaEncoder;
- _deviceManager = deviceManager;
_transcodingJobHelper = transcodingJobHelper;
_networkManager = networkManager;
_logger = logger;
@@ -140,8 +130,6 @@ public class DynamicHlsHelper
_serverConfigurationManager,
_mediaEncoder,
_encodingHelper,
- _dlnaManager,
- _deviceManager,
_transcodingJobHelper,
transcodingJobType,
cancellationTokenSource.Token)
diff --git a/Jellyfin.Api/Helpers/StreamingHelpers.cs b/Jellyfin.Api/Helpers/StreamingHelpers.cs
index 7d9a38931..71c62b235 100644
--- a/Jellyfin.Api/Helpers/StreamingHelpers.cs
+++ b/Jellyfin.Api/Helpers/StreamingHelpers.cs
@@ -12,15 +12,12 @@ using Jellyfin.Extensions;
using MediaBrowser.Common.Configuration;
using MediaBrowser.Common.Extensions;
using MediaBrowser.Controller.Configuration;
-using MediaBrowser.Controller.Devices;
-using MediaBrowser.Controller.Dlna;
using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.MediaEncoding;
using MediaBrowser.Model.Dlna;
using MediaBrowser.Model.Dto;
using MediaBrowser.Model.Entities;
using Microsoft.AspNetCore.Http;
-using Microsoft.Extensions.Primitives;
using Microsoft.Net.Http.Headers;
namespace Jellyfin.Api.Helpers;
@@ -41,8 +38,6 @@ public static class StreamingHelpers
/// <param name="serverConfigurationManager">Instance of the <see cref="IServerConfigurationManager"/> interface.</param>
/// <param name="mediaEncoder">Instance of the <see cref="IMediaEncoder"/> interface.</param>
/// <param name="encodingHelper">Instance of <see cref="EncodingHelper"/>.</param>
- /// <param name="dlnaManager">Instance of the <see cref="IDlnaManager"/> interface.</param>
- /// <param name="deviceManager">Instance of the <see cref="IDeviceManager"/> interface.</param>
/// <param name="transcodingJobHelper">Initialized <see cref="TranscodingJobHelper"/>.</param>
/// <param name="transcodingJobType">The <see cref="TranscodingJobType"/>.</param>
/// <param name="cancellationToken">The <see cref="CancellationToken"/>.</param>
@@ -56,21 +51,11 @@ public static class StreamingHelpers
IServerConfigurationManager serverConfigurationManager,
IMediaEncoder mediaEncoder,
EncodingHelper encodingHelper,
- IDlnaManager dlnaManager,
- IDeviceManager deviceManager,
TranscodingJobHelper transcodingJobHelper,
TranscodingJobType transcodingJobType,
CancellationToken cancellationToken)
{
var httpRequest = httpContext.Request;
- // Parse the DLNA time seek header
- if (!streamingRequest.StartTimeTicks.HasValue)
- {
- var timeSeek = httpRequest.Headers["TimeSeekRange.dlna.org"];
-
- streamingRequest.StartTimeTicks = ParseTimeSeekHeader(timeSeek.ToString());
- }
-
if (!string.IsNullOrWhiteSpace(streamingRequest.Params))
{
ParseParams(streamingRequest);
@@ -89,16 +74,11 @@ public static class StreamingHelpers
streamingRequest.AudioCodec = encodingHelper.InferAudioCodec(url);
}
- var enableDlnaHeaders = !string.IsNullOrWhiteSpace(streamingRequest.Params) ||
- streamingRequest.StreamOptions.ContainsKey("dlnaheaders") ||
- string.Equals(httpRequest.Headers["GetContentFeatures.DLNA.ORG"], "1", StringComparison.OrdinalIgnoreCase);
-
var state = new StreamState(mediaSourceManager, transcodingJobType, transcodingJobHelper)
{
Request = streamingRequest,
RequestedUrl = url,
- UserAgent = httpRequest.Headers[HeaderNames.UserAgent],
- EnableDlnaHeaders = enableDlnaHeaders
+ UserAgent = httpRequest.Headers[HeaderNames.UserAgent]
};
var userId = httpContext.User.GetUserId();
@@ -243,8 +223,6 @@ public static class StreamingHelpers
}
}
- ApplyDeviceProfileSettings(state, dlnaManager, deviceManager, httpRequest, streamingRequest.DeviceProfileId, streamingRequest.Static);
-
var ext = string.IsNullOrWhiteSpace(state.OutputContainer)
? GetOutputFileExtension(state, mediaSource)
: ("." + state.OutputContainer);
@@ -255,123 +233,6 @@ public static class StreamingHelpers
}
/// <summary>
- /// Adds the dlna headers.
- /// </summary>
- /// <param name="state">The state.</param>
- /// <param name="responseHeaders">The response headers.</param>
- /// <param name="isStaticallyStreamed">if set to <c>true</c> [is statically streamed].</param>
- /// <param name="startTimeTicks">The start time in ticks.</param>
- /// <param name="request">The <see cref="HttpRequest"/>.</param>
- /// <param name="dlnaManager">Instance of the <see cref="IDlnaManager"/> interface.</param>
- public static void AddDlnaHeaders(
- StreamState state,
- IHeaderDictionary responseHeaders,
- bool isStaticallyStreamed,
- long? startTimeTicks,
- HttpRequest request,
- IDlnaManager dlnaManager)
- {
- if (!state.EnableDlnaHeaders)
- {
- return;
- }
-
- var profile = state.DeviceProfile;
-
- StringValues transferMode = request.Headers["transferMode.dlna.org"];
- responseHeaders.Append("transferMode.dlna.org", string.IsNullOrEmpty(transferMode) ? "Streaming" : transferMode.ToString());
- responseHeaders.Append("realTimeInfo.dlna.org", "DLNA.ORG_TLAG=*");
-
- if (state.RunTimeTicks.HasValue)
- {
- if (string.Equals(request.Headers["getMediaInfo.sec"], "1", StringComparison.OrdinalIgnoreCase))
- {
- var ms = TimeSpan.FromTicks(state.RunTimeTicks.Value).TotalMilliseconds;
- responseHeaders.Append("MediaInfo.sec", string.Format(
- CultureInfo.InvariantCulture,
- "SEC_Duration={0};",
- Convert.ToInt32(ms)));
- }
-
- if (!isStaticallyStreamed && profile is not null)
- {
- AddTimeSeekResponseHeaders(state, responseHeaders, startTimeTicks);
- }
- }
-
- profile ??= dlnaManager.GetDefaultProfile();
-
- var audioCodec = state.ActualOutputAudioCodec;
-
- if (!state.IsVideoRequest)
- {
- responseHeaders.Append("contentFeatures.dlna.org", ContentFeatureBuilder.BuildAudioHeader(
- profile,
- state.OutputContainer,
- audioCodec,
- state.OutputAudioBitrate,
- state.OutputAudioSampleRate,
- state.OutputAudioChannels,
- state.OutputAudioBitDepth,
- isStaticallyStreamed,
- state.RunTimeTicks,
- state.TranscodeSeekInfo));
- }
- else
- {
- var videoCodec = state.ActualOutputVideoCodec;
-
- responseHeaders.Append(
- "contentFeatures.dlna.org",
- ContentFeatureBuilder.BuildVideoHeader(profile, state.OutputContainer, videoCodec, audioCodec, state.OutputWidth, state.OutputHeight, state.TargetVideoBitDepth, state.OutputVideoBitrate, state.TargetTimestamp, isStaticallyStreamed, state.RunTimeTicks, state.TargetVideoProfile, state.TargetVideoRangeType, state.TargetVideoLevel, state.TargetFramerate, state.TargetPacketLength, state.TranscodeSeekInfo, state.IsTargetAnamorphic, state.IsTargetInterlaced, state.TargetRefFrames, state.TargetVideoStreamCount, state.TargetAudioStreamCount, state.TargetVideoCodecTag, state.IsTargetAVC).FirstOrDefault() ?? string.Empty);
- }
- }
-
- /// <summary>
- /// Parses the time seek header.
- /// </summary>
- /// <param name="value">The time seek header string.</param>
- /// <returns>A nullable <see cref="long"/> representing the seek time in ticks.</returns>
- private static long? ParseTimeSeekHeader(ReadOnlySpan<char> value)
- {
- if (value.IsEmpty)
- {
- return null;
- }
-
- const string npt = "npt=";
- if (!value.StartsWith(npt, StringComparison.OrdinalIgnoreCase))
- {
- throw new ArgumentException("Invalid timeseek header");
- }
-
- var index = value.IndexOf('-');
- value = index == -1
- ? value.Slice(npt.Length)
- : value.Slice(npt.Length, index - npt.Length);
- if (!value.Contains(':'))
- {
- // Parses npt times in the format of '417.33'
- if (double.TryParse(value, CultureInfo.InvariantCulture, out var seconds))
- {
- return TimeSpan.FromSeconds(seconds).Ticks;
- }
-
- throw new ArgumentException("Invalid timeseek header");
- }
-
- try
- {
- // Parses npt times in the format of '10:19:25.7'
- return TimeSpan.Parse(value, CultureInfo.InvariantCulture).Ticks;
- }
- catch
- {
- throw new ArgumentException("Invalid timeseek header");
- }
- }
-
- /// <summary>
/// Parses query parameters as StreamOptions.
/// </summary>
/// <param name="queryString">The query string.</param>
@@ -394,29 +255,6 @@ public static class StreamingHelpers
}
/// <summary>
- /// Adds the dlna time seek headers to the response.
- /// </summary>
- /// <param name="state">The current <see cref="StreamState"/>.</param>
- /// <param name="responseHeaders">The <see cref="IHeaderDictionary"/> of the response.</param>
- /// <param name="startTimeTicks">The start time in ticks.</param>
- private static void AddTimeSeekResponseHeaders(StreamState state, IHeaderDictionary responseHeaders, long? startTimeTicks)
- {
- var runtimeSeconds = TimeSpan.FromTicks(state.RunTimeTicks!.Value).TotalSeconds.ToString(CultureInfo.InvariantCulture);
- var startSeconds = TimeSpan.FromTicks(startTimeTicks ?? 0).TotalSeconds.ToString(CultureInfo.InvariantCulture);
-
- responseHeaders.Append("TimeSeekRange.dlna.org", string.Format(
- CultureInfo.InvariantCulture,
- "npt={0}-{1}/{1}",
- startSeconds,
- runtimeSeconds));
- responseHeaders.Append("X-AvailableSeekRange", string.Format(
- CultureInfo.InvariantCulture,
- "1 npt={0}-{1}",
- startSeconds,
- runtimeSeconds));
- }
-
- /// <summary>
/// Gets the output file extension.
/// </summary>
/// <param name="state">The state.</param>
@@ -519,79 +357,6 @@ public static class StreamingHelpers
return Path.Combine(folder, filename + ext);
}
- private static void ApplyDeviceProfileSettings(StreamState state, IDlnaManager dlnaManager, IDeviceManager deviceManager, HttpRequest request, string? deviceProfileId, bool? @static)
- {
- if (!string.IsNullOrWhiteSpace(deviceProfileId))
- {
- state.DeviceProfile = dlnaManager.GetProfile(deviceProfileId);
-
- if (state.DeviceProfile is null)
- {
- var caps = deviceManager.GetCapabilities(deviceProfileId);
- state.DeviceProfile = caps is null ? dlnaManager.GetProfile(request.Headers) : caps.DeviceProfile;
- }
- }
-
- var profile = state.DeviceProfile;
-
- if (profile is null)
- {
- // Don't use settings from the default profile.
- // Only use a specific profile if it was requested.
- return;
- }
-
- var audioCodec = state.ActualOutputAudioCodec;
- var videoCodec = state.ActualOutputVideoCodec;
-
- var mediaProfile = !state.IsVideoRequest
- ? profile.GetAudioMediaProfile(state.OutputContainer, audioCodec, state.OutputAudioChannels, state.OutputAudioBitrate, state.OutputAudioSampleRate, state.OutputAudioBitDepth)
- : profile.GetVideoMediaProfile(
- state.OutputContainer,
- audioCodec,
- videoCodec,
- state.OutputWidth,
- state.OutputHeight,
- state.TargetVideoBitDepth,
- state.OutputVideoBitrate,
- state.TargetVideoProfile,
- state.TargetVideoRangeType,
- state.TargetVideoLevel,
- state.TargetFramerate,
- state.TargetPacketLength,
- state.TargetTimestamp,
- state.IsTargetAnamorphic,
- state.IsTargetInterlaced,
- state.TargetRefFrames,
- state.TargetVideoStreamCount,
- state.TargetAudioStreamCount,
- state.TargetVideoCodecTag,
- state.IsTargetAVC);
-
- if (mediaProfile is not null)
- {
- state.MimeType = mediaProfile.MimeType;
- }
-
- if (!(@static.HasValue && @static.Value))
- {
- var transcodingProfile = !state.IsVideoRequest ? profile.GetAudioTranscodingProfile(state.OutputContainer, audioCodec) : profile.GetVideoTranscodingProfile(state.OutputContainer, audioCodec, videoCodec);
-
- if (transcodingProfile is not null)
- {
- state.EstimateContentLength = transcodingProfile.EstimateContentLength;
- // state.EnableMpegtsM2TsMode = transcodingProfile.EnableMpegtsM2TsMode;
- state.TranscodeSeekInfo = transcodingProfile.TranscodeSeekInfo;
-
- if (state.VideoRequest is not null)
- {
- state.VideoRequest.CopyTimestamps = transcodingProfile.CopyTimestamps;
- state.VideoRequest.EnableSubtitlesInManifest = transcodingProfile.EnableSubtitlesInManifest;
- }
- }
- }
- }
-
/// <summary>
/// Parses the parameters.
/// </summary>
@@ -619,7 +384,7 @@ public static class StreamingHelpers
switch (i)
{
case 0:
- request.DeviceProfileId = val;
+ // DeviceProfileId
break;
case 1:
request.DeviceId = val;