ITADN

Architecture: Custom Media Element Track Children Are Cloned, So Programmatic Track Use Silently Diverges From Native Video

#2303Opencjpillsbury 创建于 7 天前
needs discussionapipkg:coremedia
C
cjpillsburycommented
`CustomMediaElement` forwards `<track>` (and `<source>`) host children to the inner native element by shallow `cloneNode()` (`#syncMediaChildren`, `packages/media/src/dom/custom-media-element/custom-media-element.ts`). The `TextTrack` that joins the live `textTracks` list is the **clone's**; the host child's own `.track` object is inert. Only attributes are synced (one-way, via `MutationObserver`). That implicitly defines track children as declarative, src-bearing configuration. Everything the repo ships today stays inside that contract, so nothing is broken right now — but the contract is undocumented, and patterns that are idiomatic on a native `<video>` fail silently on the host: - A srcless `<track>` child plus `trackEl.track.addCue(...)` — the cues land on the inert host-side track and never appear in `media.textTracks`. This is the likeliest real-world victim: building cues programmatically while attaching declaratively. - `trackEl.track.mode = ...` on the child — no-op on the live track (mode is not an attribute). - `load` / `error` on the child element and `cuechange` on its track — never fire; the clone does the loading. The store's own `load` listeners on host-level tracks (`packages/core/src/dom/store/features/text-track.ts`) are dead code for custom media elements; the feature works only via the shadow-root query that finds the clones. - `trackEl.readyState` stays `NONE` on the child. The gap is already half-known: `#enableDefaultTrack` exists to patch one specific clone divergence (browsers ignore `default` on JS-inserted tracks) and covers nothing else. Programmatic consumers do have a working path — `host.addTextTrack()` and `host.textTracks` are prototype-delegated to the native element — but nothing steers them to it. ## Why now - #1268 (programmatic chapters) will pick an authoring surface; if it lands on "write cues into a track child", it hits this head-on. - The planned Shaka in-manifest chapters/thumbnails bridge synthesizes cue-populated tracks and had to discover this by inspection; the next feature shouldn't have to. ## Acceptance criteria - The supported contract for track children is decided and documented: declarative and src-bearing only (with `host.textTracks` / `host.addTextTrack()` as the programmatic surface), or a defined level of native parity. - If the contract stays declarative-only, the unsupported pattern fails loudly: a `__DEV__` warning when a srcless `<track>` child is slotted. Related: #1268, #1843.
0 条评论