diff options
| author | Christophe Besson <cbesson@gmail.com> | 2026-09-17 11:23:36 +0200 |
|---|---|---|
| committer | Christophe Besson <cbesson@gmail.com> | 2026-09-17 11:23:36 +0200 |
| commit | 677775266217b08044fe734be78f0e1bc874d708 (patch) | |
| tree | 3e2ff74e5d2df4a5143fed49bac4c76a67c98954 /docs/MESHBAY_NODE_PROTOCOL.md | |
| parent | 1fd284dbe33d05fd5037b172fe652a8a98f7b68d (diff) | |
| download | meshbay-677775266217b08044fe734be78f0e1bc874d708.tar.gz | |
fix(node): a seek left the audio a GOP behind the picture
-ss before -i cannot trim copied video, which must begin on a keyframe, but
accurate_seek did trim the re-encoded audio to the exact request. Every seek
on a copied stream therefore opened with a GOP-wide hole in the audio and ran
a GOP out of sync afterwards — 9.979s on a real film with a 10s keyframe
interval. Accurate seeking is now off wherever video is copied, and stays on
where it is re-encoded, which is the only path that could already begin where
it was asked to.
Every timestamp was correct throughout, which is why nothing caught it; the
tests assert on decoded audio and on frames compared against the source.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Diffstat (limited to 'docs/MESHBAY_NODE_PROTOCOL.md')
| -rw-r--r-- | docs/MESHBAY_NODE_PROTOCOL.md | 5 |
1 files changed, 4 insertions, 1 deletions
diff --git a/docs/MESHBAY_NODE_PROTOCOL.md b/docs/MESHBAY_NODE_PROTOCOL.md index 19cced9..d4b9552 100644 --- a/docs/MESHBAY_NODE_PROTOCOL.md +++ b/docs/MESHBAY_NODE_PROTOCOL.md @@ -1636,7 +1636,9 @@ array while MediaSource consumes it a segment at a time. | | ffprobe: codec, duration, the | | audio tracks | | spawn ffmpeg - | | -ss before -i (index seek) + | | -ss before -i (index seek), + | | -noaccurate_seek when the + | | video is copied | | video: copy, or libx264 when | | the browser cannot decode | | audio: always AAC, 2 ch, @@ -1667,6 +1669,7 @@ array while MediaSource consumes it a segment at a time. | `n == 0` | keepalive: a viewer buffered 90 s ahead grants nothing and must still be able to say it is there | | Concurrent transcodes | 8 node-wide, semaphore on the transport context | | Seeking | a new `stream_req` with `start`; the previous stream is retired first, ffmpeg respawned with `-ss` | +| Accurate seek | **off when the video is copied, on when it is re-encoded.** Copied video has to begin on a keyframe and cannot be trimmed to the request; re-encoded audio can, and is. Leaving both at the default put a whole GOP of silence at the head of every seek and left sound and picture a GOP apart — with correct timestamps throughout, so nothing downstream could detect it | | `start` in `stream_init` | the value actually used — seeking lands on the keyframe at or before the request, and the client adds it back as `SourceBuffer.timestampOffset` | | `audio_tracks` in `stream_init` | every audio track: `i` (the **audio ordinal**, what `-map 0:a:<n>` takes, never the container stream index), `lang`, `title`, `codec`, `ch`. Empty for a file with no audio | | `audio_track` in `stream_req` | which ordinal to map. Absent, out of range or malformed is the first track | |