Skip to content

Commit

Permalink
Add support for OPUS and fixes for FLAC case issue in HLS
Browse files Browse the repository at this point in the history
Signed-off-by: nyanmisaka <[email protected]>
  • Loading branch information
nyanmisaka authored and dannymichel committed Nov 2, 2022
1 parent fdc457a commit 9dc878b
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 3 deletions.
42 changes: 40 additions & 2 deletions Jellyfin.Api/Helpers/DynamicHlsHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,13 @@ private async Task<ActionResult> GetMasterPlaylistInternal(

if (state.VideoStream != null && state.VideoRequest != null)
{
// Provide a workaround for the case issue between flac and fLaC.
var flacWaPlaylist = ApplyFlacCaseWorkaround(state, basicPlaylist.ToString());
if (!String.IsNullOrEmpty(flacWaPlaylist))
{
builder.Append(flacWaPlaylist);
}

// Provide SDR HEVC entrance for backward compatibility.
if (EncodingHelper.IsCopyCodec(state.OutputVideoCodec)
&& !string.IsNullOrEmpty(state.VideoStream.VideoRange)
Expand All @@ -215,7 +222,14 @@ private async Task<ActionResult> GetMasterPlaylistInternal(
var sdrOutputAudioBitrate = _encodingHelper.GetAudioBitrateParam(state.VideoRequest, state.AudioStream) ?? 0;
var sdrTotalBitrate = sdrOutputAudioBitrate + sdrOutputVideoBitrate;

AppendPlaylist(builder, state, sdrVideoUrl, sdrTotalBitrate, subtitleGroup);
var sdrPlaylist = AppendPlaylist(builder, state, sdrVideoUrl, sdrTotalBitrate, subtitleGroup);

// Provide a workaround for the case issue between flac and fLaC.
flacWaPlaylist = ApplyFlacCaseWorkaround(state, sdrPlaylist.ToString());
if (!String.IsNullOrEmpty(flacWaPlaylist))
{
builder.Append(flacWaPlaylist);
}

// Restore the video codec
state.OutputVideoCodec = "copy";
Expand Down Expand Up @@ -245,6 +259,13 @@ private async Task<ActionResult> GetMasterPlaylistInternal(
state.VideoStream.Level = originalLevel;
var newPlaylist = ReplacePlaylistCodecsField(basicPlaylist, playlistCodecsField, newPlaylistCodecsField);
builder.Append(newPlaylist);

// Provide a workaround for the case issue between flac and fLaC.
flacWaPlaylist = ApplyFlacCaseWorkaround(state, newPlaylist);
if (!String.IsNullOrEmpty(flacWaPlaylist))
{
builder.Append(flacWaPlaylist);
}
}
}

Expand Down Expand Up @@ -603,6 +624,11 @@ private string GetPlaylistAudioCodecs(StreamState state)
return HlsCodecStringHelpers.GetALACString();
}

if (string.Equals(state.ActualOutputAudioCodec, "opus", StringComparison.OrdinalIgnoreCase))
{
return HlsCodecStringHelpers.GetOPUSString();
}

return string.Empty;
}

Expand Down Expand Up @@ -701,7 +727,19 @@ private string ReplacePlaylistCodecsField(StringBuilder playlist, StringBuilder
return oldPlaylist.Replace(
oldValue.ToString(),
newValue.ToString(),
StringComparison.OrdinalIgnoreCase);
StringComparison.Ordinal);
}

private string ApplyFlacCaseWorkaround(StreamState state, string srcPlaylist)
{
if (!string.Equals(state.ActualOutputAudioCodec, "flac", StringComparison.OrdinalIgnoreCase))
{
return string.Empty;
}

var newPlaylist = srcPlaylist.Replace(",flac\"", ",fLaC\"", StringComparison.Ordinal);

return newPlaylist.Contains(",fLaC\"", StringComparison.Ordinal) ? newPlaylist : string.Empty;
}
}
}
16 changes: 15 additions & 1 deletion Jellyfin.Api/Helpers/HlsCodecStringHelpers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,18 @@ public static class HlsCodecStringHelpers
/// <summary>
/// Codec name for FLAC.
/// </summary>
public const string FLAC = "fLaC";
public const string FLAC = "flac";

/// <summary>
/// Codec name for ALAC.
/// </summary>
public const string ALAC = "alac";

/// <summary>
/// Codec name for OPUS.
/// </summary>
public const string OPUS = "opus";

/// <summary>
/// Gets a MP3 codec string.
/// </summary>
Expand Down Expand Up @@ -101,6 +106,15 @@ public static string GetALACString()
return ALAC;
}

/// <summary>
/// Gets an OPUS codec string.
/// </summary>
/// <returns>OPUS codec string.</returns>
public static string GetOPUSString()
{
return OPUS;
}

/// <summary>
/// Gets a H.264 codec string.
/// </summary>
Expand Down

0 comments on commit 9dc878b

Please sign in to comment.