Skip to content

Commit

Permalink
Remux overlapping AAC samples so that they are appended over earlier …
Browse files Browse the repository at this point in the history
…samples segment rather them dropping them
  • Loading branch information
Rob Walch committed May 16, 2021
1 parent ed9bb15 commit ef8c166
Showing 1 changed file with 9 additions and 26 deletions.
35 changes: 9 additions & 26 deletions src/remux/mp4-remuxer.ts
Expand Up @@ -747,8 +747,9 @@ export default class MP4Remuxer implements Remuxer {
// frame.

if (track.isAAC) {
const alignedWithVideo = videoTimeOffset !== undefined;
const maxAudioFramesDrift = this.config.maxAudioFramesDrift;
for (let i = 0, nextPts = nextAudioPts; i < inputSamples.length; ) {
for (let i = 0, nextPts = nextAudioPts; i < inputSamples.length; i++) {
// First, let's see how far off this frame is from where we expect it to be
const sample = inputSamples[i];
const pts = sample.pts;
Expand All @@ -758,29 +759,19 @@ export default class MP4Remuxer implements Remuxer {
// When remuxing with video, if we're overlapping by more than a duration, drop this sample to stay in sync
if (
delta <= -maxAudioFramesDrift * inputSampleDuration &&
videoTimeOffset !== undefined
alignedWithVideo
) {
if (contiguous || i > 0) {
logger.warn(
`[mp4-remuxer]: Dropping 1 audio frame @ ${(
nextPts / inputTimeScale
).toFixed(3)}s due to ${Math.round(duration)} ms overlap.`
);
inputSamples.splice(i, 1);
// Don't touch nextPtsNorm or i
} else {
// When changing qualities we can't trust that audio has been appended up to nextAudioPts
// Warn about the overlap but do not drop samples as that can introduce buffer gaps
if (i === 0) {
logger.warn(
`Audio frame @ ${(pts / inputTimeScale).toFixed(
3
)}s overlaps nextAudioPts by ${Math.round(
(1000 * delta) / inputTimeScale
)} ms.`
);
nextPts = pts + inputSampleDuration;
i++;
this.nextAudioPts = nextAudioPts = pts;
}
nextPts = pts;
} // eslint-disable-line brace-style

// Insert missing frames if:
Expand All @@ -791,7 +782,7 @@ export default class MP4Remuxer implements Remuxer {
else if (
delta >= maxAudioFramesDrift * inputSampleDuration &&
duration < MAX_SILENT_FRAME_DURATION &&
videoTimeOffset !== undefined
alignedWithVideo
) {
const missing = Math.floor(delta / inputSampleDuration);
// Adjust nextPts so that silent samples are aligned with media pts. This will prevent media samples from
Expand Down Expand Up @@ -824,17 +815,9 @@ export default class MP4Remuxer implements Remuxer {
nextPts += inputSampleDuration;
i++;
}

// Adjust sample to next expected pts
sample.pts = sample.dts = nextPts;
nextPts += inputSampleDuration;
i++;
} else {
// Otherwise, just adjust pts
sample.pts = sample.dts = nextPts;
nextPts += inputSampleDuration;
i++;
}
sample.pts = sample.dts = nextPts;
nextPts += inputSampleDuration;
}
}
let firstPTS: number | null = null;
Expand Down

0 comments on commit ef8c166

Please sign in to comment.