diff --git a/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs b/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs
index ce25676ff5..9071ef18fd 100644
--- a/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs
+++ b/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs
@@ -722,11 +722,37 @@ namespace MediaBrowser.Api.Playback.Hls
//return state.VideoRequest.VideoBitRate.HasValue;
}
+ ///
+ /// Get the H.26X level of the output video stream.
+ ///
+ /// StreamState of the current stream.
+ /// H.26X level of the output video stream.
+ private int? GetOutputVideoCodecLevel(StreamState state)
+ {
+ string levelString;
+ if (string.Equals(state.OutputVideoCodec, "copy", StringComparison.OrdinalIgnoreCase)
+ && state.VideoStream.Level.HasValue)
+ {
+ levelString = state.VideoStream?.Level.ToString();
+ }
+ else
+ {
+ levelString = state.GetRequestedLevel(state.ActualOutputVideoCodec);
+ }
+
+ if (int.TryParse(levelString, NumberStyles.Integer, CultureInfo.InvariantCulture, out var parsedLevel))
+ {
+ return parsedLevel;
+ }
+
+ return null;
+ }
+
///
/// Gets a formatted string of the output audio codec, for use in the CODECS field.
///
///
- ///
+ ///
/// StreamState of the current stream.
/// Formatted audio codec string.
private string GetPlaylistAudioCodecs(StreamState state)
@@ -761,18 +787,24 @@ namespace MediaBrowser.Api.Playback.Hls
///
/// StreamState of the current stream.
/// Formatted video codec string.
- private string GetPlaylistVideoCodecs(StreamState state)
+ private string GetPlaylistVideoCodecs(StreamState state, string codec, int level)
{
- int level = Convert.ToInt32(state.GetRequestedLevel(state.ActualOutputVideoCodec));
+ if (level == 0)
+ {
+ // This is 0 when there's no requested H.26X level in the device profile
+ // and the source is not encoded in H.26X
+ Logger.LogError("Got invalid H.26X level when building CODECS field for HLS master playlist");
+ return string.Empty;
+ }
- if (string.Equals(state.ActualOutputVideoCodec, "h264", StringComparison.OrdinalIgnoreCase))
+ if (string.Equals(codec, "h264", StringComparison.OrdinalIgnoreCase))
{
string profile = state.GetRequestedProfiles("h264").FirstOrDefault();
return HlsCodecStringFactory.GetH264String(profile, level);
}
- else if (string.Equals(state.ActualOutputVideoCodec, "h265", StringComparison.OrdinalIgnoreCase)
- || string.Equals(state.ActualOutputVideoCodec, "hevc", StringComparison.OrdinalIgnoreCase))
+ else if (string.Equals(codec, "h265", StringComparison.OrdinalIgnoreCase)
+ || string.Equals(codec, "hevc", StringComparison.OrdinalIgnoreCase))
{
string profile = state.GetRequestedProfiles("h265").FirstOrDefault();
@@ -787,7 +819,7 @@ namespace MediaBrowser.Api.Playback.Hls
/// the active streams output video and audio codecs.
///
///
- ///
+ ///
///
/// StringBuilder to append the field to.
/// StreamState of the current stream.
@@ -795,9 +827,10 @@ namespace MediaBrowser.Api.Playback.Hls
{
// Video
string videoCodecs = string.Empty;
- if (!string.IsNullOrEmpty(state.ActualOutputVideoCodec))
+ int? videoCodecLevel = GetOutputVideoCodecLevel(state);
+ if (!string.IsNullOrEmpty(state.ActualOutputVideoCodec) && videoCodecLevel.HasValue)
{
- videoCodecs = GetPlaylistVideoCodecs(state);
+ videoCodecs = GetPlaylistVideoCodecs(state, state.ActualOutputVideoCodec, videoCodecLevel.Value);
}
// Audio
@@ -807,26 +840,17 @@ namespace MediaBrowser.Api.Playback.Hls
audioCodecs = GetPlaylistAudioCodecs(state);
}
- if (!string.IsNullOrEmpty(videoCodecs) || !string.IsNullOrEmpty(audioCodecs))
- {
- builder.Append(",CODECS=\"");
+ StringBuilder codecs = new StringBuilder();
- if (!string.IsNullOrEmpty(videoCodecs) && !string.IsNullOrEmpty(audioCodecs))
- {
- builder.Append(videoCodecs)
- .Append(',')
- .Append(audioCodecs);
- }
- else if (!string.IsNullOrEmpty(videoCodecs))
- {
- builder.Append(videoCodecs);
- }
- else if (!string.IsNullOrEmpty(audioCodecs))
- {
- builder.Append(audioCodecs);
- }
+ codecs.Append(videoCodecs)
+ .Append(',')
+ .Append(audioCodecs);
- builder.Append('"');
+ if (codecs.Length > 1)
+ {
+ builder.Append(",CODECS=\"")
+ .Append(codecs)
+ .Append('"');
}
}