Align track starts at the relay so DASH output carries no video edit list#53
Merged
Merged
Conversation
There was a problem hiding this comment.
Pull request overview
Updates the nginx-rtmp “live” application configuration used by Earshot’s ffmpeg DASH transcoding relay so that relayed streams begin on a video keyframe and audio is held until video is available, preventing the DASH muxer from writing a leading empty video edit list that causes A/V desync in Chromium/Safari MSE.
Changes:
- Enable
wait_key on;so subscribers start receiving video at a keyframe boundary. - Enable
wait_video on;so audio delivery is delayed until video is flowing. - Apply the same settings to both SSL and no-SSL nginx config variants.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
| nginx-transcoder/nginx.conf | Adds wait_key and wait_video to align audio/video track start for the transcoding relay. |
| nginx-transcoder/nginx-no-ssl.conf | Mirrors the same wait_key/wait_video alignment behavior in the no-SSL config variant. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
mormegil6
force-pushed
the
align-track-starts
branch
from
July 22, 2026 09:02
d2bc80c to
ae2a7d6
Compare
roddylindsay
approved these changes
Jul 22, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What this fixes
Earshot's DASH output desyncs audio and video by up to one GOP on Chromium and Safari whenever the transcoder (re)starts against a live stream. The offset is different after every restart, so it cannot be tuned away downstream.
Mechanism
The transcoder is an nginx-rtmp
execffmpeg that subscribes to the internalliveapplication. A subscriber joining a live stream receives audio immediately, but no decodable video until the next keyframe arrives, up to one GOP later. ffmpeg therefore sees the video track start later than the audio track, and the DASH muxer faithfully records that skew as a leading empty edit (elst,media_time = -1) on the video track in the init segment.Firefox applies that edit through MSE and stays in sync. Chromium and Safari do not apply it through MSE, so they present video early by the edit amount. The divergence is documented with a minimal repro here:
Since most MSE players land on the dropping side, an Earshot deployment feeding dash.js/Shaka/hls.js on Chrome inherits an A/V desync that changes size on every encoder restart.
Fix
Two stock nginx-rtmp directives on the
liveapplication, in both conf variants:With these, both tracks genuinely start together, so there is no skew for the muxer to record and no edit list is written at all. Every player then behaves identically because there is nothing left to interpret.
Measurements
Restart drill with a flash/beep marker contribution (flash and beep co-timed in the source; H.264 + 16-ch AAC, 2 s GOP,
-c:v copytranscode):[(0, 0)]on 20 of 20 runsThe second column is measured by decoding the output media directly (frame brightness and beep onset), independent of the edit list, which verifies the edit disappears because the tracks align, not because it was suppressed.
Why not
-use_editlist 0Suppressing the edit list would leave the tracks skewed and delete the metadata Firefox correctly honours, desyncing Firefox to match the others. Aligning the track starts fixes the cause instead of hiding the symptom.
Trade-off
wait_videodelays the transcoder's input until the first keyframe after the join, so DASH output begins up to one GOP later than before. For a transcoding relay this is a startup cost only; steady-state latency is unchanged.