`@remotion/player`: persistent audio/video offset after a brief audio-clock stall is never corrected#11439
Package: @remotion/player (setGlobalTimeAnchor, src/set-global-time-anchor.ts)
Affected versions: 4.0.516 â 4.0.526 (current)
Problem
When the Web Audio clock briefly stalls at the start of playback (observed ~100â180 ms on first play after idle, and on some devices with high output latency), audioContext.currentTime stops while frames keep advancing. Once the clock resumes, video and audio stay offset by that amount for the rest of playback.
setGlobalTimeAnchor skips re-anchoring when
Math.abs(shift) < ALLOWED_GLOBAL_TIME_ANCHOR_SHIFT + latency // 0.1 + baseLatency + outputLatency
With outputLatency of 0.2 s+ (Bluetooth headphones, some Android/Windows outputs; and 0.3 s is substituted when outputLatency is 0), the threshold is 0.3â0.6 s. A 100â180 ms offset never crosses it, so it's never corrected. The skip is right for per-frame jitter, but it also swallows a sustained mismatch.
Reproduction
Captured from a real replay at 25 fps â relative audioContext.currentTime vs. the frame being shown. Audio time is stuck at 0.1067 while frames 3â5 advance, then resumes ~100 ms behind:
const replay = [
[0, 0], [0.064, 0], [0.1067, 3], [0.1067, 5], [0.128, 7], [0.2347, 10],
[0.3413, 12], [0.4267, 15], [0.5333, 17], [0.64, 20], [0.7467, 22],
[0.832, 25], [0.9387, 27],
];
const audioSyncAnchor = { value: 0 };
for (const [audioTime, frame] of replay) {
setGlobalTimeAnchor({
audioContext: { currentTime: audioTime, baseLatency: 1024 / 48000, outputLatency: 0.2, state: 'running' },
audioSyncAnchor,
absoluteTimeInSeconds: frame / 25,
globalPlaybackRate: 1,
logLevel: 'error',
force: false,
});
}
// final error: (audioTime - anchor) - frame/25 â -0.10 s, and it never gets corrected