aboutsummaryrefslogtreecommitdiff
path: root/Jellyfin.Api/Helpers/StreamingHelpers.cs
diff options
context:
space:
mode:
Diffstat (limited to 'Jellyfin.Api/Helpers/StreamingHelpers.cs')
-rw-r--r--Jellyfin.Api/Helpers/StreamingHelpers.cs59
1 files changed, 43 insertions, 16 deletions
diff --git a/Jellyfin.Api/Helpers/StreamingHelpers.cs b/Jellyfin.Api/Helpers/StreamingHelpers.cs
index f4ec29bde..c6d844c4f 100644
--- a/Jellyfin.Api/Helpers/StreamingHelpers.cs
+++ b/Jellyfin.Api/Helpers/StreamingHelpers.cs
@@ -83,8 +83,12 @@ namespace Jellyfin.Api.Helpers
}
streamingRequest.StreamOptions = ParseStreamOptions(httpRequest.Query);
+ if (httpRequest.Path.Value == null)
+ {
+ throw new ResourceNotFoundException(nameof(httpRequest.Path));
+ }
- var url = httpRequest.Path.Value.Split('.').Last();
+ var url = httpRequest.Path.Value.Split('.')[^1];
if (string.IsNullOrEmpty(streamingRequest.AudioCodec))
{
@@ -165,7 +169,9 @@ namespace Jellyfin.Api.Helpers
state.DirectStreamProvider = liveStreamInfo.Item2;
}
- encodingHelper.AttachMediaSourceInfo(state, mediaSource, url);
+ var encodingOptions = serverConfigurationManager.GetEncodingOptions();
+
+ encodingHelper.AttachMediaSourceInfo(state, encodingOptions, mediaSource, url);
string? containerInternal = Path.GetExtension(state.RequestedUrl);
@@ -183,7 +189,7 @@ namespace Jellyfin.Api.Helpers
state.OutputContainer = (containerInternal ?? string.Empty).TrimStart('.');
- state.OutputAudioBitrate = encodingHelper.GetAudioBitrateParam(streamingRequest.AudioBitRate, state.AudioStream);
+ state.OutputAudioBitrate = encodingHelper.GetAudioBitrateParam(streamingRequest.AudioBitRate, streamingRequest.AudioCodec, state.AudioStream);
state.OutputAudioCodec = streamingRequest.AudioCodec;
@@ -196,20 +202,41 @@ namespace Jellyfin.Api.Helpers
encodingHelper.TryStreamCopy(state);
- if (state.OutputVideoBitrate.HasValue && !EncodingHelper.IsCopyCodec(state.OutputVideoCodec))
+ if (!EncodingHelper.IsCopyCodec(state.OutputVideoCodec) && state.OutputVideoBitrate.HasValue)
{
- var resolution = ResolutionNormalizer.Normalize(
- state.VideoStream?.BitRate,
- state.VideoStream?.Width,
- state.VideoStream?.Height,
- state.OutputVideoBitrate.Value,
- state.VideoStream?.Codec,
- state.OutputVideoCodec,
- state.VideoRequest.MaxWidth,
- state.VideoRequest.MaxHeight);
-
- state.VideoRequest.MaxWidth = resolution.MaxWidth;
- state.VideoRequest.MaxHeight = resolution.MaxHeight;
+ var isVideoResolutionNotRequested = !state.VideoRequest.Width.HasValue
+ && !state.VideoRequest.Height.HasValue
+ && !state.VideoRequest.MaxWidth.HasValue
+ && !state.VideoRequest.MaxHeight.HasValue;
+
+ if (isVideoResolutionNotRequested
+ && state.VideoRequest.VideoBitRate.HasValue
+ && state.VideoStream.BitRate.HasValue
+ && state.VideoRequest.VideoBitRate.Value >= state.VideoStream.BitRate.Value)
+ {
+ // Don't downscale the resolution if the width/height/MaxWidth/MaxHeight is not requested,
+ // and the requested video bitrate is higher than source video bitrate.
+ if (state.VideoStream.Width.HasValue || state.VideoStream.Height.HasValue)
+ {
+ state.VideoRequest.MaxWidth = state.VideoStream?.Width;
+ state.VideoRequest.MaxHeight = state.VideoStream?.Height;
+ }
+ }
+ else
+ {
+ var resolution = ResolutionNormalizer.Normalize(
+ state.VideoStream?.BitRate,
+ state.VideoStream?.Width,
+ state.VideoStream?.Height,
+ state.OutputVideoBitrate.Value,
+ state.VideoStream?.Codec,
+ state.OutputVideoCodec,
+ state.VideoRequest.MaxWidth,
+ state.VideoRequest.MaxHeight);
+
+ state.VideoRequest.MaxWidth = resolution.MaxWidth;
+ state.VideoRequest.MaxHeight = resolution.MaxHeight;
+ }
}
}