Repository navigation
quest: cut records-free HLS on a broadcast join interval #7041
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
393efb6
a239bf8
03ef320
2c6f706
fa30a01
82cef98
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -4,8 +4,9 @@ | |
|
|
||
| Every first-party consumer that numbered groups works by start timestamp, | ||
| in Rust and JS, and hang stops writing duration and discontinuity markers | ||
| that group ends and gaps now carry. The HLS/DASH export lists segments | ||
| straight from group starts and ends, so the HLS records go away. | ||
| that group ends and gaps now carry. The HLS/DASH export cuts segments | ||
| from group starts and ends on the broadcast's declared join interval, so the | ||
| HLS records go away. | ||
|
|
||
| ## Plan | ||
|
|
||
|
|
@@ -21,9 +22,49 @@ Decided 2026-10-25 (maintainer), from the spike: | |
| pause markers, which they already tolerate being absent. | ||
|
|
||
| Decided 2026-10-27 (maintainer): moq-mux publishes HLS records by default | ||
| until this lands. Then the `<track>.hls` record tracks, the catalog `hls` | ||
| field (hang draft and both catalog libraries), the `catalog::Config::with_hls` | ||
| opt-out, and any A/V segment alignment go away. | ||
| until this lands. Then the `<track>.hls` record tracks, the per-rendition | ||
| `hls` catalog field, and any A/V segment alignment go away. | ||
|
|
||
| Decided 2026-10-27 (maintainer, from an HLS audit): how the export | ||
| cuts segments without records. HLS numbers segments by position, so every | ||
| edge and every reload must derive the same consecutive numbers from | ||
| timestamps alone, and a pts grid is the only stateless rule that does. | ||
| Rejected: one platform grid (long-GOP publishers overrun it constantly), | ||
| per-edge counting (failover renumbers), and a publisher counter (per-producer | ||
| state again). | ||
|
|
||
| - **A catalog `media` section** holds what applies to every audio and video | ||
| track. `media.join.interval` promises that each one starts a group at least | ||
| that often outside a pause, and is the export's grid, so every rendition | ||
| shares segment numbers. It is fixed for the broadcast instance, since the | ||
| numbering depends on it. The root `clock` moves to `media.clock` in the same | ||
| break. Nested so a later join mechanism that is not a fixed grid can sit | ||
| beside it. | ||
| moq-mux declares the interval from its GOP hint, and `@moq/publish` does | ||
| too. A broadcast without one is not HLS-renderable. | ||
|
Comment on lines
+36
to
+44
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
| - **Each group belongs to one segment, numbered by grid line**: the first | ||
| line it contains, so an edge finds segment N from a `Time` start at pts | ||
| N × interval, the group that resolves to. A group containing no line | ||
| joins the segment of the group before it, or after a gap, the segment of | ||
| the line it starts after. The edge trims each segment to its own groups, | ||
| so ranges need no exclusive time end. The media sequence number is N. | ||
|
Comment on lines
+45
to
+50
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
| - **Whole groups only.** Never split a group: a segment starting mid-GOP is | ||
| not independent. | ||
| - **A segment with no groups is `EXT-X-GAP`**, so numbering never skips | ||
| across a pause or an overrun. A group overrunning the interval is listed | ||
| at its first line, so its `EXTINF` understates the media; document the | ||
| deviation beside | ||
| [fixed target duration](/quest/m1/archive/hls-target.md)'s overrun rule, | ||
| whose target then comes from the interval. | ||
|
Comment on lines
+51
to
+58
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
| - **Segments run under twice the interval** even without an overrun, since | ||
| the group containing a line can start up to one interval before it. Open | ||
| for the maintainer: a target of twice the interval (RFC 8216 compliant, | ||
| but players hold back twice as far) or the interval itself with longer | ||
| segments listed under the overrun rule. | ||
| - DASH lists the same segments by `$Time$`. | ||
|
coderabbitai[bot] marked this conversation as resolved.
Resolved
|
||
|
|
||
| Pin the segmentation with table-driven tests over pauses that end between | ||
| lines or past the next one, unequal GOPs, and overruns. | ||
|
|
||
| Convert each consumer that numbers groups: hang and moq-mux timelines, | ||
| HLS/DASH export, `seek` for GOP-aligned failover in moq-mux, HLS import's | ||
|
|
@@ -39,10 +80,11 @@ export reads media tracks directly, prove that an HLS-only viewer of an | |
| on-demand publisher starts capture and gets a playlist. | ||
|
|
||
| Public API: breaking where a consumer exposes group numbers (CLI | ||
| `--group`, archive keys), and `moq_mux::hls`, `hang::hls`, and | ||
| `catalog::Config::with_hls` are deleted. Wire: hang drops empty duration | ||
| frames, discontinuity marker groups, the `hls` catalog field, and the record | ||
| tracks. | ||
| `--group`, archive keys), `hang::hls` and the per-rendition `hls` field are | ||
| deleted, and `moq_mux::hls` shrinks to declaring the interval. Wire: hang | ||
| drops empty duration frames, discontinuity marker groups, the `hls` field, | ||
| and the record tracks, adds `media.join.interval`, and moves `clock` to | ||
| `media.clock`. | ||
|
|
||
| ## Required | ||
|
|
||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.