fix: aresample requires hz, so convert from khz (#1745)

* fix: aresample requires hz, so convert from khz

* fix: always send khz to loudnorm filter; convert inside
This commit is contained in:
Jason Dove
2026-03-26 18:35:19 -05:00
committed by GitHub
parent e76528ef69
commit 29b635e89c
3 changed files with 61 additions and 67 deletions

View File

@@ -14,6 +14,6 @@ export class LoudnormFilter extends FilterOption {
const gain = isDefined(this.loudnormConfig.offsetGain)
? `:offset=${this.loudnormConfig.offsetGain}`
: '';
return `loudnorm=I=${this.loudnormConfig.i}:LRA=${this.loudnormConfig.lra}:TP=${this.loudnormConfig.tp}${gain},aresample=${this.sampleRate}`;
return `loudnorm=I=${this.loudnormConfig.i}:LRA=${this.loudnormConfig.lra}:TP=${this.loudnormConfig.tp}${gain},aresample=${this.sampleRate * 1000}`;
}
}

View File

@@ -215,7 +215,7 @@ describe('BasePipelineBuilder', () => {
audioBitrate: 192,
audioBufferSize: 192 * 2,
audioChannels: 2,
audioSampleRate: 44100,
audioSampleRate: 44.1,
loudnormConfig: { i: -24, lra: 7, tp: -2 },
}),
);
@@ -280,42 +280,39 @@ describe('BasePipelineBuilder', () => {
{ desc: 'lra too high', config: { i: -24, lra: 50.1, tp: -2 } },
{ desc: 'tp too low', config: { i: -24, lra: 7, tp: -9.1 } },
{ desc: 'tp too high', config: { i: -24, lra: 7, tp: 0.1 } },
])(
'do not add loudnorm filter when $desc',
({ config }) => {
const audio = AudioInputSource.withStream(
new FileStreamSource('/path/to/song.flac'),
AudioStream.create({
channels: 2,
codec: 'flac',
index: 0,
}),
AudioState.create({
audioBitrate: 192,
audioBufferSize: 192 * 2,
audioChannels: 2,
loudnormConfig: config,
}),
);
])('do not add loudnorm filter when $desc', ({ config }) => {
const audio = AudioInputSource.withStream(
new FileStreamSource('/path/to/song.flac'),
AudioStream.create({
channels: 2,
codec: 'flac',
index: 0,
}),
AudioState.create({
audioBitrate: 192,
audioBufferSize: 192 * 2,
audioChannels: 2,
loudnormConfig: config,
}),
);
const pipeline = new NoopPipelineBuilder(
video,
audio,
null,
null,
null,
EmptyFfmpegCapabilities,
);
const pipeline = new NoopPipelineBuilder(
video,
audio,
null,
null,
null,
EmptyFfmpegCapabilities,
);
const result = pipeline.build(state, frameState, DefaultPipelineOptions);
const result = pipeline.build(state, frameState, DefaultPipelineOptions);
const loudnormFilter = result.inputs.audioInput?.filterSteps.find(
(step) => step instanceof LoudnormFilter,
);
const loudnormFilter = result.inputs.audioInput?.filterSteps.find(
(step) => step instanceof LoudnormFilter,
);
expect(loudnormFilter).toBeUndefined();
},
);
expect(loudnormFilter).toBeUndefined();
});
test.each([
{ desc: 'i at lower bound', config: { i: -70, lra: 7, tp: -2 } },
@@ -324,42 +321,39 @@ describe('BasePipelineBuilder', () => {
{ desc: 'lra at upper bound', config: { i: -24, lra: 50, tp: -2 } },
{ desc: 'tp at lower bound', config: { i: -24, lra: 7, tp: -9 } },
{ desc: 'tp at upper bound', config: { i: -24, lra: 7, tp: 0 } },
])(
'add loudnorm filter when $desc',
({ config }) => {
const audio = AudioInputSource.withStream(
new FileStreamSource('/path/to/song.flac'),
AudioStream.create({
channels: 2,
codec: 'flac',
index: 0,
}),
AudioState.create({
audioBitrate: 192,
audioBufferSize: 192 * 2,
audioChannels: 2,
loudnormConfig: config,
}),
);
])('add loudnorm filter when $desc', ({ config }) => {
const audio = AudioInputSource.withStream(
new FileStreamSource('/path/to/song.flac'),
AudioStream.create({
channels: 2,
codec: 'flac',
index: 0,
}),
AudioState.create({
audioBitrate: 192,
audioBufferSize: 192 * 2,
audioChannels: 2,
loudnormConfig: config,
}),
);
const pipeline = new NoopPipelineBuilder(
video,
audio,
null,
null,
null,
EmptyFfmpegCapabilities,
);
const pipeline = new NoopPipelineBuilder(
video,
audio,
null,
null,
null,
EmptyFfmpegCapabilities,
);
const result = pipeline.build(state, frameState, DefaultPipelineOptions);
const result = pipeline.build(state, frameState, DefaultPipelineOptions);
const loudnormFilter = result.inputs.audioInput?.filterSteps.find(
(step) => step instanceof LoudnormFilter,
);
const loudnormFilter = result.inputs.audioInput?.filterSteps.find(
(step) => step instanceof LoudnormFilter,
);
expect(loudnormFilter).toBeDefined();
},
);
expect(loudnormFilter).toBeDefined();
});
test('do not add loudnorm filter when loudnormConfig is not set', () => {
const audio = AudioInputSource.withStream(

View File

@@ -677,7 +677,7 @@ export abstract class BasePipelineBuilder implements PipelineBuilder {
this.audioInputSource?.filterSteps.push(
new LoudnormFilter(
this.desiredAudioState.loudnormConfig,
this.desiredAudioState.audioSampleRate ?? 48_000,
this.desiredAudioState.audioSampleRate ?? 48,
),
);
}