Browse Source

downmix ac3 to stereo to match output layout (#2774)

pull/2775/head
Jason Dove 4 months ago committed by GitHub
parent
commit
343a4619a6
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 1
      CHANGELOG.md
  2. 35
      ErsatzTV.FFmpeg/Decoder/DecoderAc3Downmix.cs
  3. 6
      ErsatzTV.FFmpeg/Format/AudioLayout.cs
  4. 12
      ErsatzTV.FFmpeg/Pipeline/PipelineBuilderBase.cs

1
CHANGELOG.md

@ -18,6 +18,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). @@ -18,6 +18,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
- Use configured searching log level on startup, instead of the default log level of `Information`
- MySql: fix searching for shows and seasons in schedule items editor
- Fix 500 errors when serving XMLTV due to concurrent file reads and writes
- Fix playback of AC3 audio when targeting stereo output and input layout changes mid-stream
## [26.1.1] - 2026-01-08
### Fixed

35
ErsatzTV.FFmpeg/Decoder/DecoderAc3Downmix.cs

@ -0,0 +1,35 @@ @@ -0,0 +1,35 @@
using ErsatzTV.FFmpeg.Environment;
using ErsatzTV.FFmpeg.Format;
namespace ErsatzTV.FFmpeg.Decoder;
public class DecoderAc3Downmix(int sourceChannels, int desiredChannels) : IDecoder
{
public string Name => "ac3";
public EnvironmentVariable[] EnvironmentVariables => [];
public string[] GlobalOptions => [];
public string[] FilterOptions => [];
public string[] OutputOptions => [];
public string[] InputOptions(InputFile inputFile)
{
if (sourceChannels >= 2 && desiredChannels == 2)
{
return ["-c:a", "ac3", "-downmix", AudioLayout.Stereo];
}
// unsupported downmix; hopefully the layout doesn't change
return [];
}
public FrameState NextState(FrameState currentState) => currentState;
public bool AppliesTo(AudioInputFile audioInputFile) => true;
public bool AppliesTo(VideoInputFile videoInputFile) => false;
public bool AppliesTo(ConcatInputFile concatInputFile) => false;
public bool AppliesTo(GraphicsEngineInput graphicsEngineInput) => false;
}

6
ErsatzTV.FFmpeg/Format/AudioLayout.cs

@ -0,0 +1,6 @@ @@ -0,0 +1,6 @@
namespace ErsatzTV.FFmpeg.Format;
public static class AudioLayout
{
public const string Stereo = "stereo";
}

12
ErsatzTV.FFmpeg/Pipeline/PipelineBuilderBase.cs

@ -466,6 +466,18 @@ public abstract class PipelineBuilderBase : IPipelineBuilder @@ -466,6 +466,18 @@ public abstract class PipelineBuilderBase : IPipelineBuilder
}
}
// workaround for ac3 audio layout changes
// downmix from decoder so filter doesn't need to reinit (it can't, it will fail)
// this only really works when the desired output format matches the minimal input format
foreach (var audioInputStream in audioInputFile.Streams.OfType<AudioStream>()
.Where(s => s.Codec == AudioFormat.Ac3).HeadOrNone())
{
foreach (int desiredAudioChannels in audioInputFile.DesiredState.AudioChannels)
{
audioInputFile.AddOption(new DecoderAc3Downmix(audioInputStream.Channels, desiredAudioChannels));
}
}
// always need to specify audio codec so ffmpeg doesn't default to a codec we don't want
foreach (IEncoder step in AvailableEncoders.ForAudioFormat(ffmpegState, audioInputFile.DesiredState, _logger))
{

Loading…
Cancel
Save