Skip to content

feat(wasm): Live Viewer に配信開始からの経過時間を表示する - #372

Open
yuki-uchida wants to merge 5 commits into
codex/live-viewer-seekbarfrom
codex/live-viewer-media-timeline
Open

feat(wasm): Live Viewer に配信開始からの経過時間を表示する#372
yuki-uchida wants to merge 5 commits into
codex/live-viewer-seekbarfrom
codex/live-viewer-media-timeline

Conversation

@yuki-uchida

@yuki-uchida yuki-uchida commented Sep 10, 2026

Copy link
Copy Markdown
Collaborator

概要

シークバーがライブ端からの相対位置しか示さず、配信開始から何分経ったのか分かりませんでした。MSF の media timeline track(draft-ietf-moq-msf-00 §7)を実装し、スライダー下に シーク位置 / 配信経過 を表示します。

やったこと

  • media-streaming-format に §7.1 のレコード型を追加する。序数で意味が決まる3要素配列なので tuple struct にした
  • live-ingest が timeline トラックを publish する。keyframe group ごとに presentation time / location / encode wallclock を記録し、mediatimeline packaging と主 video トラックへの depends を付ける。保持は relay のキャッシュ相当の窓で、group ID が連番でなくなったら再パブリッシュと判断して破棄する。自分の location を書くために TrackWriter に書き込み先 group ID の読み取りを追加した
  • viewer が catalog から §7.2 の packaging(fallback は §5.1.14 の role)で timeline トラックを見つけて購読し、capture timestamp を直前レコードからのオフセットで presentation time に変換する

やらないこと

  • §7.3 の増分更新と §7.1 の GZIP 圧縮。どちらも MAY で、group 先頭に完全版を置く MUST だけを満たす

影響範囲

  • moqt は追加のみの API 拡張

テスト

  • cargo test -p media-streaming-format -p moqt-bridge-live-ingest -p moqt(moqt は 154 件)、cargo clippycargo fmt --checknpm --prefix examples/browser run lint、prettier: pass
  • npm run e2e:live-viewer: pass。ライブで 1:48 / 1:48、Home シークで 1:36 / 1:54(差 18 秒 = 表示の -17.7s と一致)、360p 切り替え後も 2:06 / 2:06

備考

depends は §7.2 の MUST なので出しますが、値はレコードの Location が解決できる主 video トラックだけに絞っています。live-ingest は SUBSCRIBE ごとにトラック別の writer を作って group ID を再採番するため、rendition を同じタイムラインでは表せません。トラックごとに timeline を publish して depends で選ばせる形は、必要になってから入れます。

@yuki-uchida
yuki-uchida added this pull request to stack #377 September 10, 2026 10:26
draft-ietf-moq-msf-00 section 7.1 defines a media timeline as an array of
three-item records whose ordinal position defines their type. Model the
record as a tuple struct so serde emits that array shape, and name the
items through accessors.

serde_json joins the dev-dependencies to assert the wire format against the
example document in the draft.
A publisher that also has to describe its own locations, such as an MSF
media timeline, needs the group id it just wrote. Only the group count was
reachable, which does not resolve to a location without the seed the writer
was constructed with.
Nothing in the catalog told a subscriber where the broadcast started, so a
player could only measure time from the moment it joined. The bridge now
publishes a "timeline" track carrying the media presentation timestamp, the
location and the encode wallclock of every keyframe group, declared with
mediatimeline packaging and depending on every media track.

Records are held for as long as the relay caches objects, and are dropped
when a group id stops continuing the sequence, which is how a resubscribe
reseeds the numbering and invalidates the recorded locations.
The slider only said how far behind the live edge a position was, so there
was no way to tell how long the broadcast had been running. The viewer now
subscribes to the MSF media timeline track it finds in the catalog and reads
`position / broadcast` off it.

A capture timestamp resolves to a presentation time by offsetting from the
newest record at or before it, rather than by matching the recorded group
id, because renditions number their groups independently of the track the
records point at.

The catalog reader gained media timeline discovery, keyed on the packaging
of section 7.2 with the optional role of section 5.1.14 as a fallback, and
excludes those tracks from the video and audio lists.
…it indexes

Listing every media track claimed the records resolve against renditions
too. Each track gets its own writer, seeded when it is subscribed, so a
rendition numbers its groups independently of the locations the records
carry, and only the primary video track is actually indexed.
@yuki-uchida
yuki-uchida force-pushed the codex/live-viewer-media-timeline branch from c1ba4c6 to 27c2b90 Compare September 10, 2026 10:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant