mirror of
https://github.com/arcodange-org/mediabunny.git
synced 2026-09-27 02:43:48 +02:00
Fix AudioResampler emitting timestamps before startTimestamp (fixes #366)
This commit is contained in:
+6
-3
@@ -96,7 +96,8 @@
|
||||
input,
|
||||
output,
|
||||
audio: {
|
||||
discard: true,
|
||||
codec: 'aac',
|
||||
forceTranscode: true,
|
||||
//forceTranscode: true,
|
||||
//sampleFormat: 's16',
|
||||
},
|
||||
@@ -125,7 +126,7 @@
|
||||
},
|
||||
*/
|
||||
video: {
|
||||
//discard: true,
|
||||
discard: true,
|
||||
},
|
||||
tags: {} ?? {
|
||||
title: 'Bigggy',
|
||||
@@ -145,7 +146,9 @@
|
||||
}
|
||||
},
|
||||
trim: {
|
||||
end: 10,
|
||||
start: 300.14984567374756 - 100,
|
||||
end: 310.1548298151939 - 100,
|
||||
//end: 10,
|
||||
//start: startTime,
|
||||
//end: startTime + 2,
|
||||
},
|
||||
|
||||
@@ -1889,6 +1889,7 @@ export class Conversion {
|
||||
startTime: this._startTimestamp,
|
||||
endTime: this._endTimestamp,
|
||||
onSample: async (sample) => {
|
||||
assert(sample.timestamp >= this._startTimestamp);
|
||||
sample.setTimestamp(sample.timestamp - this._startTimestamp);
|
||||
|
||||
await this._registerAudioSample(trackOptions, outputTrackId, source, sample);
|
||||
|
||||
+7
-4
@@ -20,7 +20,6 @@ export class AudioResampler {
|
||||
targetSampleRate: number;
|
||||
sourceNumberOfChannels: number | null = null;
|
||||
targetNumberOfChannels: number;
|
||||
startTime: number;
|
||||
endTime: number;
|
||||
onSample: (sample: AudioSample) => Promise<void>;
|
||||
|
||||
@@ -33,6 +32,7 @@ export class AudioResampler {
|
||||
maxWrittenFrame: number | null = null;
|
||||
channelMixer!: (sourceData: Float32Array, sourceFrameIndex: number, targetChannelIndex: number) => number;
|
||||
tempSourceBuffer!: Float32Array;
|
||||
timestampOffset: number;
|
||||
|
||||
constructor(options: {
|
||||
targetSampleRate: number;
|
||||
@@ -43,7 +43,6 @@ export class AudioResampler {
|
||||
}) {
|
||||
this.targetSampleRate = options.targetSampleRate;
|
||||
this.targetNumberOfChannels = options.targetNumberOfChannels;
|
||||
this.startTime = options.startTime;
|
||||
this.endTime = options.endTime;
|
||||
this.onSample = options.onSample;
|
||||
|
||||
@@ -51,7 +50,11 @@ export class AudioResampler {
|
||||
this.bufferSizeInSamples = this.bufferSizeInFrames * this.targetNumberOfChannels;
|
||||
|
||||
this.outputBuffer = new Float32Array(this.bufferSizeInSamples);
|
||||
this.bufferStartFrame = Math.floor(this.startTime * this.targetSampleRate);
|
||||
|
||||
this.bufferStartFrame = Math.floor(options.startTime * this.targetSampleRate);
|
||||
// Set to ensure that if the buffer start frame lands on a fractional sample, that the first timestamp still
|
||||
// comes out as exactly startTime
|
||||
this.timestampOffset = options.startTime - this.bufferStartFrame / this.targetSampleRate;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -273,7 +276,7 @@ export class AudioResampler {
|
||||
format: 'f32',
|
||||
sampleRate: this.targetSampleRate,
|
||||
numberOfChannels: this.targetNumberOfChannels,
|
||||
timestamp: timestampSeconds,
|
||||
timestamp: timestampSeconds + this.timestampOffset,
|
||||
data: outputData,
|
||||
});
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { ALL_FORMATS } from '../../src/input-format.js';
|
||||
import { Input } from '../../src/input.js';
|
||||
import { AdtsOutputFormat, HlsOutputFormat, Mp4OutputFormat, MpegTsOutputFormat } from '../../src/output-format.js';
|
||||
import { AdtsOutputFormat, HlsOutputFormat, Mp4OutputFormat, MpegTsOutputFormat, WavOutputFormat } from '../../src/output-format.js';
|
||||
import { Output, OutputTrackGroup } from '../../src/output.js';
|
||||
import { BufferSource, CustomPathedSource, UrlSource } from '../../src/source.js';
|
||||
import { expect, test } from 'vitest';
|
||||
@@ -369,3 +369,30 @@ test('HLS track assignability can be overridden', async () => {
|
||||
expect(newMasterPlayist).not.toBe(masterPlayist);
|
||||
expect(newMasterPlayist.match(/\.m3u8/g)?.length).toBe(1);
|
||||
});
|
||||
|
||||
test('Fractional audio sample boundary', async () => {
|
||||
using input = new Input({
|
||||
source: new UrlSource('/trim-buck-bunny-ffmpeg.ts'),
|
||||
formats: ALL_FORMATS,
|
||||
});
|
||||
|
||||
const output = new Output({
|
||||
format: new WavOutputFormat(),
|
||||
target: new BufferTarget(),
|
||||
});
|
||||
|
||||
const conversion = await Conversion.init({
|
||||
input,
|
||||
output,
|
||||
video: {
|
||||
discard: true,
|
||||
},
|
||||
audio: {
|
||||
forceTranscode: true,
|
||||
},
|
||||
trim: {
|
||||
start: 0.4 / 48000,
|
||||
},
|
||||
});
|
||||
await conversion.execute();
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user