gpac / mp4box.js

JavaScript version of GPAC's MP4Box tool
https://gpac.github.io/mp4box.js/
BSD 3-Clause "New" or "Revised" License
1.92k stars 325 forks source link

Audio track start time not as expected #336

Closed hughfenghen closed 1 year ago

hughfenghen commented 1 year ago

I'm merge video using the WebCodecs API, The video track works fine, but the audio track of the second file starts playing at the 0th second (the first file has no audio track).

data flow: AudioData -> AudioEncoder -> EncodecAudioChunk -> mp4box.js addSample

I checked that the timestamp property of EncodecAudioChunk is correct, but the generated mp4 file, the audio track is not offset.

const encoder = new AudioEncoder({
    error: console.error,
    output: (chunk) => {
      const buf = new ArrayBuffer(chunk.byteLength)
      chunk.copyTo(buf)
      // The first `chunk.timestamp` is equal to the duration of the first video
      const dts = chunk.timestamp
      mp4File.addSample(trackId, buf, {
        duration: chunk.duration ?? 0,
        dts,
        cts: dts,
        is_sync: chunk.type === 'key'
      })
    }
  })

In the end I had to create an empty AudioData placeholder for the first video to solve the problem.

function createAudioPlaceholder (ts: number, duration: number): AudioData {
  const frameCnt = Math.floor(48000 * duration / 1e6)
  return new AudioData({
    timestamp: ts,
    numberOfChannels: 1,
    numberOfFrames: frameCnt,
    sampleRate: 48000,
    format: 'f32-planar',
    data: new Float32Array(frameCnt)
  })
}

Is there any better solution?