From b897d3c8c1cd4ac2eb6200724f538f412b913f0f Mon Sep 17 00:00:00 2001 From: Rob Walch Date: Mon, 8 May 2023 13:45:56 -0400 Subject: [PATCH] Fix AV desync regression in v1.4.0 when mp4 audio track timestamps start before video track timestamps Fixes #5452 --- src/remux/passthrough-remuxer.ts | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/src/remux/passthrough-remuxer.ts b/src/remux/passthrough-remuxer.ts index b9bf783334f..df1023e0901 100644 --- a/src/remux/passthrough-remuxer.ts +++ b/src/remux/passthrough-remuxer.ts @@ -167,20 +167,25 @@ class PassThroughRemuxer implements Remuxer { this.emitInitSegment = false; } + const duration = getDuration(data, initData); const startDTS = getStartDTS(initData, data); const decodeTime = startDTS === null ? timeOffset : startDTS; if ( - isInvalidInitPts(initPTS, decodeTime, timeOffset) || + isInvalidInitPts(initPTS, decodeTime, timeOffset, duration) || (initSegment.timescale !== initPTS.timescale && accurateTimeOffset) ) { initSegment.initPTS = decodeTime - timeOffset; + if (initPTS && initPTS.timescale === 1) { + logger.warn( + `Adjusting initPTS by ${initSegment.initPTS - initPTS.baseTime}` + ); + } this.initPTS = initPTS = { baseTime: initSegment.initPTS, timescale: 1, }; } - const duration = getDuration(data, initData); const startTime = audioTrack ? decodeTime - initPTS.baseTime / initPTS.timescale : (lastEndTime as number); @@ -244,14 +249,16 @@ class PassThroughRemuxer implements Remuxer { function isInvalidInitPts( initPTS: RationalTimestamp | null, startDTS: number, - timeOffset: number + timeOffset: number, + duration: number ): initPTS is null { if (initPTS === null) { return true; } - // InitPTS is invalid when it would cause start time to be negative, or distance from time offset to be more than 1 second + // InitPTS is invalid when distance from program would be more than segment duration or a minimum of one second + const minDuration = Math.max(duration, 1); const startTime = startDTS - initPTS.baseTime / initPTS.timescale; - return startTime < 0 && Math.abs(startTime - timeOffset) > 1; + return Math.abs(startTime - timeOffset) > minDuration; } function getParsedTrackCodec(