diff options
| author | gnattu <gnattuoc@me.com> | 2024-05-06 12:48:50 +0800 |
|---|---|---|
| committer | gnattu <gnattuoc@me.com> | 2024-07-17 21:27:35 +0800 |
| commit | 0381c5a288bc56e20aa5def05e3d41bacf3519a7 (patch) | |
| tree | cee14ca1ff941d7d1234f8f7d4f0aa321d8edce1 /Jellyfin.Api/Controllers | |
| parent | 78929418cc3aa783db3abaf99d15ba55e41cc2ac (diff) | |
Add EnableAudioVbrEncoding to TranscodingProfile
This will allow the client selectively disable VBR audio when it causes problems.
Signed-off-by: gnattu <gnattuoc@me.com>
Diffstat (limited to 'Jellyfin.Api/Controllers')
| -rw-r--r-- | Jellyfin.Api/Controllers/AudioController.cs | 14 | ||||
| -rw-r--r-- | Jellyfin.Api/Controllers/DynamicHlsController.cs | 53 | ||||
| -rw-r--r-- | Jellyfin.Api/Controllers/VideosController.cs | 14 |
3 files changed, 57 insertions, 24 deletions
diff --git a/Jellyfin.Api/Controllers/AudioController.cs b/Jellyfin.Api/Controllers/AudioController.cs index 72be55513..06b7e6c9f 100644 --- a/Jellyfin.Api/Controllers/AudioController.cs +++ b/Jellyfin.Api/Controllers/AudioController.cs @@ -83,6 +83,7 @@ public class AudioController : BaseJellyfinApiController /// <param name="videoStreamIndex">Optional. The index of the video stream to use. If omitted the first video stream will be used.</param> /// <param name="context">Optional. The <see cref="EncodingContext"/>.</param> /// <param name="streamOptions">Optional. The streaming options.</param> + /// <param name="enableAudioVbrEncoding">Optional. Whether to enable Audio Encoding.</param> /// <response code="200">Audio stream returned.</response> /// <returns>A <see cref="FileResult"/> containing the audio file.</returns> [HttpGet("{itemId}/stream", Name = "GetAudioStream")] @@ -138,7 +139,8 @@ public class AudioController : BaseJellyfinApiController [FromQuery] int? audioStreamIndex, [FromQuery] int? videoStreamIndex, [FromQuery] EncodingContext? context, - [FromQuery] Dictionary<string, string>? streamOptions) + [FromQuery] Dictionary<string, string>? streamOptions, + [FromQuery] bool? enableAudioVbrEncoding) { StreamingRequestDto streamingRequest = new StreamingRequestDto { @@ -189,7 +191,8 @@ public class AudioController : BaseJellyfinApiController AudioStreamIndex = audioStreamIndex, VideoStreamIndex = videoStreamIndex, Context = context ?? EncodingContext.Static, - StreamOptions = streamOptions + StreamOptions = streamOptions, + EnableAudioVbrEncoding = enableAudioVbrEncoding ?? true }; return await _audioHelper.GetAudioStream(_transcodingJobType, streamingRequest).ConfigureAwait(false); @@ -247,6 +250,7 @@ public class AudioController : BaseJellyfinApiController /// <param name="videoStreamIndex">Optional. The index of the video stream to use. If omitted the first video stream will be used.</param> /// <param name="context">Optional. The <see cref="EncodingContext"/>.</param> /// <param name="streamOptions">Optional. The streaming options.</param> + /// <param name="enableAudioVbrEncoding">Optional. Whether to enable Audio Encoding.</param> /// <response code="200">Audio stream returned.</response> /// <returns>A <see cref="FileResult"/> containing the audio file.</returns> [HttpGet("{itemId}/stream.{container}", Name = "GetAudioStreamByContainer")] @@ -302,7 +306,8 @@ public class AudioController : BaseJellyfinApiController [FromQuery] int? audioStreamIndex, [FromQuery] int? videoStreamIndex, [FromQuery] EncodingContext? context, - [FromQuery] Dictionary<string, string>? streamOptions) + [FromQuery] Dictionary<string, string>? streamOptions, + [FromQuery] bool? enableAudioVbrEncoding) { StreamingRequestDto streamingRequest = new StreamingRequestDto { @@ -353,7 +358,8 @@ public class AudioController : BaseJellyfinApiController AudioStreamIndex = audioStreamIndex, VideoStreamIndex = videoStreamIndex, Context = context ?? EncodingContext.Static, - StreamOptions = streamOptions + StreamOptions = streamOptions, + EnableAudioVbrEncoding = enableAudioVbrEncoding ?? true }; return await _audioHelper.GetAudioStream(_transcodingJobType, streamingRequest).ConfigureAwait(false); diff --git a/Jellyfin.Api/Controllers/DynamicHlsController.cs b/Jellyfin.Api/Controllers/DynamicHlsController.cs index 1e99a9ee3..a7fc9928e 100644 --- a/Jellyfin.Api/Controllers/DynamicHlsController.cs +++ b/Jellyfin.Api/Controllers/DynamicHlsController.cs @@ -156,6 +156,7 @@ public class DynamicHlsController : BaseJellyfinApiController /// <param name="maxWidth">Optional. The max width.</param> /// <param name="maxHeight">Optional. The max height.</param> /// <param name="enableSubtitlesInManifest">Optional. Whether to enable subtitles in the manifest.</param> + /// <param name="enableAudioVbrEncoding">Optional. Whether to enable Audio Encoding.</param> /// <response code="200">Hls live stream retrieved.</response> /// <returns>A <see cref="FileResult"/> containing the hls file.</returns> [HttpGet("Videos/{itemId}/live.m3u8")] @@ -213,7 +214,8 @@ public class DynamicHlsController : BaseJellyfinApiController [FromQuery] Dictionary<string, string> streamOptions, [FromQuery] int? maxWidth, [FromQuery] int? maxHeight, - [FromQuery] bool? enableSubtitlesInManifest) + [FromQuery] bool? enableSubtitlesInManifest, + [FromQuery] bool? enableAudioVbrEncoding) { VideoRequestDto streamingRequest = new VideoRequestDto { @@ -267,7 +269,8 @@ public class DynamicHlsController : BaseJellyfinApiController StreamOptions = streamOptions, MaxHeight = maxHeight, MaxWidth = maxWidth, - EnableSubtitlesInManifest = enableSubtitlesInManifest ?? true + EnableSubtitlesInManifest = enableSubtitlesInManifest ?? true, + EnableAudioVbrEncoding = enableAudioVbrEncoding ?? true }; // CTS lifecycle is managed internally. @@ -393,6 +396,7 @@ public class DynamicHlsController : BaseJellyfinApiController /// <param name="streamOptions">Optional. The streaming options.</param> /// <param name="enableAdaptiveBitrateStreaming">Enable adaptive bitrate streaming.</param> /// <param name="enableTrickplay">Enable trickplay image playlists being added to master playlist.</param> + /// <param name="enableAudioVbrEncoding">Whether to enable Audio Encoding.</param> /// <response code="200">Video stream returned.</response> /// <returns>A <see cref="FileResult"/> containing the playlist file.</returns> [HttpGet("Videos/{itemId}/master.m3u8")] @@ -451,7 +455,8 @@ public class DynamicHlsController : BaseJellyfinApiController [FromQuery] EncodingContext? context, [FromQuery] Dictionary<string, string> streamOptions, [FromQuery] bool enableAdaptiveBitrateStreaming = true, - [FromQuery] bool enableTrickplay = true) + [FromQuery] bool enableTrickplay = true, + [FromQuery] bool enableAudioVbrEncoding = true) { var streamingRequest = new HlsVideoRequestDto { @@ -505,7 +510,8 @@ public class DynamicHlsController : BaseJellyfinApiController Context = context ?? EncodingContext.Streaming, StreamOptions = streamOptions, EnableAdaptiveBitrateStreaming = enableAdaptiveBitrateStreaming, - EnableTrickplay = enableTrickplay + EnableTrickplay = enableTrickplay, + EnableAudioVbrEncoding = enableAudioVbrEncoding }; return await _dynamicHlsHelper.GetMasterHlsPlaylist(TranscodingJobType, streamingRequest, enableAdaptiveBitrateStreaming).ConfigureAwait(false); @@ -564,6 +570,7 @@ public class DynamicHlsController : BaseJellyfinApiController /// <param name="context">Optional. The <see cref="EncodingContext"/>.</param> /// <param name="streamOptions">Optional. The streaming options.</param> /// <param name="enableAdaptiveBitrateStreaming">Enable adaptive bitrate streaming.</param> + /// <param name="enableAudioVbrEncoding">Optional. Whether to enable Audio Encoding.</param> /// <response code="200">Audio stream returned.</response> /// <returns>A <see cref="FileResult"/> containing the playlist file.</returns> [HttpGet("Audio/{itemId}/master.m3u8")] @@ -620,7 +627,8 @@ public class DynamicHlsController : BaseJellyfinApiController [FromQuery] int? videoStreamIndex, [FromQuery] EncodingContext? context, [FromQuery] Dictionary<string, string> streamOptions, - [FromQuery] bool enableAdaptiveBitrateStreaming = true) + [FromQuery] bool enableAdaptiveBitrateStreaming = true, + [FromQuery] bool enableAudioVbrEncoding = true) { var streamingRequest = new HlsAudioRequestDto { @@ -671,7 +679,8 @@ public class DynamicHlsController : BaseJellyfinApiController VideoStreamIndex = videoStreamIndex, Context = context ?? EncodingContext.Streaming, StreamOptions = streamOptions, - EnableAdaptiveBitrateStreaming = enableAdaptiveBitrateStreaming + EnableAdaptiveBitrateStreaming = enableAdaptiveBitrateStreaming, + EnableAudioVbrEncoding = enableAudioVbrEncoding }; return await _dynamicHlsHelper.GetMasterHlsPlaylist(TranscodingJobType, streamingRequest, enableAdaptiveBitrateStreaming).ConfigureAwait(false); @@ -730,6 +739,7 @@ public class DynamicHlsController : BaseJellyfinApiController /// <param name="videoStreamIndex">Optional. The index of the video stream to use. If omitted the first video stream will be used.</param> /// <param name="context">Optional. The <see cref="EncodingContext"/>.</param> /// <param name="streamOptions">Optional. The streaming options.</param> + /// <param name="enableAudioVbrEncoding">Optional. Whether to enable Audio Encoding.</param> /// <response code="200">Video stream returned.</response> /// <returns>A <see cref="FileResult"/> containing the audio file.</returns> [HttpGet("Videos/{itemId}/main.m3u8")] @@ -785,7 +795,8 @@ public class DynamicHlsController : BaseJellyfinApiController [FromQuery] int? audioStreamIndex, [FromQuery] int? videoStreamIndex, [FromQuery] EncodingContext? context, - [FromQuery] Dictionary<string, string> streamOptions) + [FromQuery] Dictionary<string, string> streamOptions, + [FromQuery] bool? enableAudioVbrEncoding) { using var cancellationTokenSource = new CancellationTokenSource(); var streamingRequest = new VideoRequestDto @@ -838,7 +849,8 @@ public class DynamicHlsController : BaseJellyfinApiController AudioStreamIndex = audioStreamIndex, VideoStreamIndex = videoStreamIndex, Context = context ?? EncodingContext.Streaming, - StreamOptions = streamOptions + StreamOptions = streamOptions, + EnableAudioVbrEncoding = enableAudioVbrEncoding ?? true }; return await GetVariantPlaylistInternal(streamingRequest, cancellationTokenSource) @@ -897,6 +909,7 @@ public class DynamicHlsController : BaseJellyfinApiController /// <param name="videoStreamIndex">Optional. The index of the video stream to use. If omitted the first video stream will be used.</param> /// <param name="context">Optional. The <see cref="EncodingContext"/>.</param> /// <param name="streamOptions">Optional. The streaming options.</param> + /// <param name="enableAudioVbrEncoding">Optional. Whether to enable Audio Encoding.</param> /// <response code="200">Audio stream returned.</response> /// <returns>A <see cref="FileResult"/> containing the audio file.</returns> [HttpGet("Audio/{itemId}/main.m3u8")] @@ -951,7 +964,8 @@ public class DynamicHlsController : BaseJellyfinApiController [FromQuery] int? audioStreamIndex, [FromQuery] int? videoStreamIndex, [FromQuery] EncodingContext? context, - [FromQuery] Dictionary<string, string> streamOptions) + [FromQuery] Dictionary<string, string> streamOptions, + [FromQuery] bool? enableAudioVbrEncoding) { using var cancellationTokenSource = new CancellationTokenSource(); var streamingRequest = new StreamingRequestDto @@ -1002,7 +1016,8 @@ public class DynamicHlsController : BaseJellyfinApiController AudioStreamIndex = audioStreamIndex, VideoStreamIndex = videoStreamIndex, Context = context ?? EncodingContext.Streaming, - StreamOptions = streamOptions + StreamOptions = streamOptions, + EnableAudioVbrEncoding = enableAudioVbrEncoding ?? true }; return await GetVariantPlaylistInternal(streamingRequest, cancellationTokenSource) @@ -1067,6 +1082,7 @@ public class DynamicHlsController : BaseJellyfinApiController /// <param name="videoStreamIndex">Optional. The index of the video stream to use. If omitted the first video stream will be used.</param> /// <param name="context">Optional. The <see cref="EncodingContext"/>.</param> /// <param name="streamOptions">Optional. The streaming options.</param> + /// <param name="enableAudioVbrEncoding">Optional. Whether to enable Audio Encoding.</param> /// <response code="200">Video stream returned.</response> /// <returns>A <see cref="FileResult"/> containing the audio file.</returns> [HttpGet("Videos/{itemId}/hls1/{playlistId}/{segmentId}.{container}")] @@ -1128,7 +1144,8 @@ public class DynamicHlsController : BaseJellyfinApiController [FromQuery] int? audioStreamIndex, [FromQuery] int? videoStreamIndex, [FromQuery] EncodingContext? context, - [FromQuery] Dictionary<string, string> streamOptions) + [FromQuery] Dictionary<string, string> streamOptions, + [FromQuery] bool? enableAudioVbrEncoding) { var streamingRequest = new VideoRequestDto { @@ -1183,7 +1200,8 @@ public class DynamicHlsController : BaseJellyfinApiController AudioStreamIndex = audioStreamIndex, VideoStreamIndex = videoStreamIndex, Context = context ?? EncodingContext.Streaming, - StreamOptions = streamOptions + StreamOptions = streamOptions, + EnableAudioVbrEncoding = enableAudioVbrEncoding ?? true }; return await GetDynamicSegment(streamingRequest, segmentId) @@ -1247,6 +1265,7 @@ public class DynamicHlsController : BaseJellyfinApiController /// <param name="videoStreamIndex">Optional. The index of the video stream to use. If omitted the first video stream will be used.</param> /// <param name="context">Optional. The <see cref="EncodingContext"/>.</param> /// <param name="streamOptions">Optional. The streaming options.</param> + /// <param name="enableAudioVbrEncoding">Optional. Whether to enable Audio Encoding.</param> /// <response code="200">Video stream returned.</response> /// <returns>A <see cref="FileResult"/> containing the audio file.</returns> [HttpGet("Audio/{itemId}/hls1/{playlistId}/{segmentId}.{container}")] @@ -1307,7 +1326,8 @@ public class DynamicHlsController : BaseJellyfinApiController [FromQuery] int? audioStreamIndex, [FromQuery] int? videoStreamIndex, [FromQuery] EncodingContext? context, - [FromQuery] Dictionary<string, string> streamOptions) + [FromQuery] Dictionary<string, string> streamOptions, + [FromQuery] bool? enableAudioVbrEncoding) { var streamingRequest = new StreamingRequestDto { @@ -1360,7 +1380,8 @@ public class DynamicHlsController : BaseJellyfinApiController AudioStreamIndex = audioStreamIndex, VideoStreamIndex = videoStreamIndex, Context = context ?? EncodingContext.Streaming, - StreamOptions = streamOptions + StreamOptions = streamOptions, + EnableAudioVbrEncoding = enableAudioVbrEncoding ?? true }; return await GetDynamicSegment(streamingRequest, segmentId) @@ -1672,7 +1693,7 @@ public class DynamicHlsController : BaseJellyfinApiController if (audioBitrate.HasValue && !EncodingHelper.LosslessAudioCodecs.Contains(state.ActualOutputAudioCodec, StringComparison.OrdinalIgnoreCase)) { var vbrParam = _encodingHelper.GetAudioVbrModeParam(audioCodec, audioBitrate.Value, audioChannels ?? 2); - if (_encodingOptions.EnableAudioVbr && vbrParam is not null) + if (_encodingOptions.EnableAudioVbr && state.EnableAudioVbrEncoding && vbrParam is not null) { audioTranscodeParams += vbrParam; } @@ -1725,7 +1746,7 @@ public class DynamicHlsController : BaseJellyfinApiController if (bitrate.HasValue && !EncodingHelper.LosslessAudioCodecs.Contains(actualOutputAudioCodec, StringComparison.OrdinalIgnoreCase)) { var vbrParam = _encodingHelper.GetAudioVbrModeParam(audioCodec, bitrate.Value, channels ?? 2); - if (_encodingOptions.EnableAudioVbr && vbrParam is not null) + if (_encodingOptions.EnableAudioVbr && state.EnableAudioVbrEncoding && vbrParam is not null) { args += vbrParam; } diff --git a/Jellyfin.Api/Controllers/VideosController.cs b/Jellyfin.Api/Controllers/VideosController.cs index a9e1d4484..f6050bdf7 100644 --- a/Jellyfin.Api/Controllers/VideosController.cs +++ b/Jellyfin.Api/Controllers/VideosController.cs @@ -306,6 +306,7 @@ public class VideosController : BaseJellyfinApiController /// <param name="videoStreamIndex">Optional. The index of the video stream to use. If omitted the first video stream will be used.</param> /// <param name="context">Optional. The <see cref="EncodingContext"/>.</param> /// <param name="streamOptions">Optional. The streaming options.</param> + /// <param name="enableAudioVbrEncoding">Optional. Whether to enable Audio Encoding.</param> /// <response code="200">Video stream returned.</response> /// <returns>A <see cref="FileResult"/> containing the audio file.</returns> [HttpGet("{itemId}/stream")] @@ -363,7 +364,8 @@ public class VideosController : BaseJellyfinApiController [FromQuery] int? audioStreamIndex, [FromQuery] int? videoStreamIndex, [FromQuery] EncodingContext? context, - [FromQuery] Dictionary<string, string> streamOptions) + [FromQuery] Dictionary<string, string> streamOptions, + [FromQuery] bool? enableAudioVbrEncoding) { var isHeadRequest = Request.Method == System.Net.WebRequestMethods.Http.Head; // CTS lifecycle is managed internally. @@ -419,7 +421,8 @@ public class VideosController : BaseJellyfinApiController AudioStreamIndex = audioStreamIndex, VideoStreamIndex = videoStreamIndex, Context = context ?? EncodingContext.Streaming, - StreamOptions = streamOptions + StreamOptions = streamOptions, + EnableAudioVbrEncoding = enableAudioVbrEncoding ?? true }; var state = await StreamingHelpers.GetStreamingState( @@ -544,6 +547,7 @@ public class VideosController : BaseJellyfinApiController /// <param name="videoStreamIndex">Optional. The index of the video stream to use. If omitted the first video stream will be used.</param> /// <param name="context">Optional. The <see cref="EncodingContext"/>.</param> /// <param name="streamOptions">Optional. The streaming options.</param> + /// <param name="enableAudioVbrEncoding">Optional. Whether to enable Audio Encoding.</param> /// <response code="200">Video stream returned.</response> /// <returns>A <see cref="FileResult"/> containing the audio file.</returns> [HttpGet("{itemId}/stream.{container}")] @@ -601,7 +605,8 @@ public class VideosController : BaseJellyfinApiController [FromQuery] int? audioStreamIndex, [FromQuery] int? videoStreamIndex, [FromQuery] EncodingContext? context, - [FromQuery] Dictionary<string, string> streamOptions) + [FromQuery] Dictionary<string, string> streamOptions, + [FromQuery] bool? enableAudioVbrEncoding) { return GetVideoStream( itemId, @@ -654,6 +659,7 @@ public class VideosController : BaseJellyfinApiController audioStreamIndex, videoStreamIndex, context, - streamOptions); + streamOptions, + enableAudioVbrEncoding); } } |
