aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorgnattu <gnattuoc@me.com>2024-05-06 12:48:50 +0800
committergnattu <gnattuoc@me.com>2024-07-17 21:27:35 +0800
commit0381c5a288bc56e20aa5def05e3d41bacf3519a7 (patch)
treecee14ca1ff941d7d1234f8f7d4f0aa321d8edce1
parent78929418cc3aa783db3abaf99d15ba55e41cc2ac (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>
-rw-r--r--Jellyfin.Api/Controllers/AudioController.cs14
-rw-r--r--Jellyfin.Api/Controllers/DynamicHlsController.cs53
-rw-r--r--Jellyfin.Api/Controllers/VideosController.cs14
-rw-r--r--MediaBrowser.Controller/MediaEncoding/BaseEncodingJobOptions.cs2
-rw-r--r--MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs4
-rw-r--r--MediaBrowser.Controller/MediaEncoding/EncodingJobInfo.cs8
-rw-r--r--MediaBrowser.Model/Dlna/StreamBuilder.cs1
-rw-r--r--MediaBrowser.Model/Dlna/StreamInfo.cs4
-rw-r--r--MediaBrowser.Model/Dlna/TranscodingProfile.cs4
9 files changed, 78 insertions, 26 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);
}
}
diff --git a/MediaBrowser.Controller/MediaEncoding/BaseEncodingJobOptions.cs b/MediaBrowser.Controller/MediaEncoding/BaseEncodingJobOptions.cs
index 29dd190ab..03ec6c658 100644
--- a/MediaBrowser.Controller/MediaEncoding/BaseEncodingJobOptions.cs
+++ b/MediaBrowser.Controller/MediaEncoding/BaseEncodingJobOptions.cs
@@ -191,6 +191,8 @@ namespace MediaBrowser.Controller.MediaEncoding
public Dictionary<string, string> StreamOptions { get; set; }
+ public bool EnableAudioVbrEncoding { get; set; }
+
public string GetOption(string qualifier, string name)
{
var value = GetOption(qualifier + "-" + name);
diff --git a/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs b/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs
index a122f3d19..ce2414cd1 100644
--- a/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs
+++ b/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs
@@ -6976,7 +6976,7 @@ namespace MediaBrowser.Controller.MediaEncoding
if (bitrate.HasValue && !LosslessAudioCodecs.Contains(codec, StringComparison.OrdinalIgnoreCase))
{
var vbrParam = GetAudioVbrModeParam(codec, bitrate.Value, channels ?? 2);
- if (encodingOptions.EnableAudioVbr && vbrParam is not null)
+ if (encodingOptions.EnableAudioVbr && state.EnableAudioVbrEncoding && vbrParam is not null)
{
args += vbrParam;
}
@@ -7007,7 +7007,7 @@ namespace MediaBrowser.Controller.MediaEncoding
if (bitrate.HasValue && !LosslessAudioCodecs.Contains(outputCodec, StringComparison.OrdinalIgnoreCase))
{
var vbrParam = GetAudioVbrModeParam(GetAudioEncoder(state), bitrate.Value, channels ?? 2);
- if (encodingOptions.EnableAudioVbr && vbrParam is not null)
+ if (encodingOptions.EnableAudioVbr && state.EnableAudioVbrEncoding && vbrParam is not null)
{
audioTranscodeParams.Add(vbrParam);
}
diff --git a/MediaBrowser.Controller/MediaEncoding/EncodingJobInfo.cs b/MediaBrowser.Controller/MediaEncoding/EncodingJobInfo.cs
index f2a0b906d..526aa8f99 100644
--- a/MediaBrowser.Controller/MediaEncoding/EncodingJobInfo.cs
+++ b/MediaBrowser.Controller/MediaEncoding/EncodingJobInfo.cs
@@ -508,6 +508,14 @@ namespace MediaBrowser.Controller.MediaEncoding
}
}
+ public bool EnableAudioVbrEncoding
+ {
+ get
+ {
+ return BaseRequest.EnableAudioVbrEncoding;
+ }
+ }
+
public int HlsListSize => 0;
public bool EnableBreakOnNonKeyFrames(string videoCodec)
diff --git a/MediaBrowser.Model/Dlna/StreamBuilder.cs b/MediaBrowser.Model/Dlna/StreamBuilder.cs
index 55d1c3d51..ba958c030 100644
--- a/MediaBrowser.Model/Dlna/StreamBuilder.cs
+++ b/MediaBrowser.Model/Dlna/StreamBuilder.cs
@@ -542,6 +542,7 @@ namespace MediaBrowser.Model.Dlna
playlistItem.EnableMpegtsM2TsMode = transcodingProfile.EnableMpegtsM2TsMode;
playlistItem.BreakOnNonKeyFrames = transcodingProfile.BreakOnNonKeyFrames;
+ playlistItem.EnableAudioVbrEncoding = transcodingProfile.EnableAudioVbrEncoding;
if (transcodingProfile.MinSegments > 0)
{
diff --git a/MediaBrowser.Model/Dlna/StreamInfo.cs b/MediaBrowser.Model/Dlna/StreamInfo.cs
index 75e5b6d18..c8a341d41 100644
--- a/MediaBrowser.Model/Dlna/StreamInfo.cs
+++ b/MediaBrowser.Model/Dlna/StreamInfo.cs
@@ -108,6 +108,8 @@ namespace MediaBrowser.Model.Dlna
public string? MediaSourceId => MediaSource?.Id;
+ public bool EnableAudioVbrEncoding { get; set; }
+
public bool IsDirectStream => MediaSource?.VideoType is not (VideoType.Dvd or VideoType.BluRay)
&& PlayMethod is PlayMethod.DirectStream or PlayMethod.DirectPlay;
@@ -768,6 +770,8 @@ namespace MediaBrowser.Model.Dlna
}
list.Add(new NameValuePair("RequireAvc", item.RequireAvc.ToString(CultureInfo.InvariantCulture).ToLowerInvariant()));
+
+ list.Add(new NameValuePair("EnableAudioVbrEncoding", item.EnableAudioVbrEncoding.ToString(CultureInfo.InvariantCulture).ToLowerInvariant()));
}
list.Add(new NameValuePair("Tag", item.MediaSource?.ETag ?? string.Empty));
diff --git a/MediaBrowser.Model/Dlna/TranscodingProfile.cs b/MediaBrowser.Model/Dlna/TranscodingProfile.cs
index 891448c66..d535e8c18 100644
--- a/MediaBrowser.Model/Dlna/TranscodingProfile.cs
+++ b/MediaBrowser.Model/Dlna/TranscodingProfile.cs
@@ -70,6 +70,10 @@ namespace MediaBrowser.Model.Dlna
public ProfileCondition[] Conditions { get; set; }
+ [DefaultValue(true)]
+ [XmlAttribute("enableAudioVbrEncoding")]
+ public bool EnableAudioVbrEncoding { get; set; }
+
public string[] GetAudioCodecs()
{
return ContainerProfile.SplitValue(AudioCodec);