Skip to content

feat: add DASH, Mux, and Vimeo as installation source types (UI + CLI)#1732

Draft
decepulis wants to merge 8 commits into
mainfrom
claude/kind-bell-kpriad
Draft

feat: add DASH, Mux, and Vimeo as installation source types (UI + CLI)#1732
decepulis wants to merge 8 commits into
mainfrom
claude/kind-bell-kpriad

Conversation

@decepulis

@decepulis decepulis commented Jun 23, 2026

Copy link
Copy Markdown
Collaborator

Closes #1255.

Surfaces the DASH, Mux (video + audio), and Vimeo media elements as source-type choices in the installation guide's renderer picker, and brings both surfaces — the docs UI and @videojs/cli — to parity for them. (Sub-issue of #727; the AI-generated issue body is stale in both directions, so this implements what the codebase actually supports rather than the issue's literal list.)

Note

Stacked on #1737 (the CDN-manifest seam). Merge #1737 first; this then rebases onto main and its diff collapses to the new-engine work below. Until that rebase, the diff here also shows #1737's manifest machinery and CLI gating plumbing.

Scope & philosophy

The picker is an opinionated source-type / hosting-service chooser, not an engine chooser. So:

  • Added: dash (.mpd), mux-video + mux-audio (hosting), vimeo (hosting).
  • Deliberately left out: the HLS engine variants native-hls-video, simple-hls-video, simple-hls-audio-only. They aren't different sources — they're different playback engines for HLS the picker already offers — so they'd muddy a "what kind of media do you have?" choice. (They remain available as media elements; just not in this picker.)

All three new renderers are src-based — the videojs Mux element takes a stream.mux.com source and extracts the playback ID internally, so there's no playback-id codegen fork.

What's in here

  • Renderer wiring — extend the Renderer union and the per-renderer maps (tags, React components, media subpaths, default sample sources, labels, articles, isVideoLike so Vimeo's iframe doesn't get a bogus playsinline). New default-video order: html5-video, hls, dash, mux-video, vimeo; default-audio: html5-audio, mux-audio.
  • Detection.mpddash, vimeo.comvimeo, and Mux-first host rules (stream.mux.commux-video/mux-audio by use case) that take precedence over the generic .m3u8 rule. The detection loop now continues past a host match that's invalid for the use case (so a Mux URL in an audio context falls through to mux-audio). Net effect: uploading via the Mux panel now lands on a real <mux-video> (with Mux Data) instead of generic HLS — no uploader changes needed.
  • Sectioned dropdownSelect gains an optional, backward-compatible groups API (Base UI Group/GroupLabel). The renderer dropdown groups into Files / Streaming formats / Hosting services, but only when grouping earns its keep (≥2 sections, ≥1 with multiple items) — so audio/background stay flat.
  • UI + CLI parity — the renderer labels, options, and grouping live in a shared, pure renderer-options.ts consumed by both the install-page dropdown and the @videojs/cli prompt, so the two can't drift. The CLI's --media flag accepts the new values and generates matching code. (The CDN-availability gating that both surfaces apply comes from feat: add a CDN media-availability manifest and read it across install surfaces #1737.)

Tests & verification

  • Unit coverage for detection (Mux precedence, .mpd, Vimeo, use-case fallthrough), codegen (HTML/React/CDN output per new renderer), dropdown grouping, and CLI generation for the new renderers. Grouping/label logic lives in the pure renderer-options.ts so it's testable without introducing testing-library (no .test.tsx precedent in the site).
  • Verified via the deploy previews (build green) and the site + CLI unit suites.

Out of scope (follow-ups)

  • The html5-audio default sample currently points at a video .mp4 (pre-existing quirk; needs a real audio asset).
  • Unifying the remaining pickers (use-case, skin, install-method) into shared option builders like renderer-options.ts — they still duplicate their option lists across the CLI prompt and the UI pickers (skin labels have already drifted: "No Skin" vs "None (headless)").
  • An SSR-stubs reassurance note was intentionally not added to the install page (applies to all media imports; belongs in a concepts/SSR guide if anywhere).

🤖 Generated with Claude Code

https://claude.ai/code/session_01Kd5A9UsSz5Ka7nYhEik3Fd

claude added 2 commits June 23, 2026 22:46
Surface the DASH, Mux (video + audio), and Vimeo media elements as
source-type choices in the installation guide's renderer picker. Engine
variants of HLS (native-hls, simple-hls) are intentionally left out — the
picker is a source-type/hosting-service chooser, not an engine chooser.

- Extend the Renderer union and per-renderer maps (tags, components, media
  subpaths, default sources, articles, labels).
- Mux-first detection: stream.mux.com resolves to mux-video/mux-audio
  (by use case) ahead of the generic .m3u8 rule; the detection loop now
  continues past use-case-invalid host matches. Add .mpd -> dash and
  vimeo.com -> vimeo rules.
- Group the renderer dropdown into Files / Streaming formats / Hosting
  services via a new optional `groups` API on Select.
- Vimeo has no CDN build: generate a cdn-media manifest (content collection)
  from the built CDN bundles and hide the CDN install option (falling back
  to npm with a note) for renderers without one.

WIP: implementation complete; verification (install/typecheck/test/build)
and the final testing approach still pending.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Kd5A9UsSz5Ka7nYhEik3Fd
Move RENDERER_LABELS, the section map, buildOptions, and buildGroups out of
RendererSelect into utils/installation/renderer-options.ts so the grouping
logic is unit-testable without rendering React/Base UI (no testing-library
precedent in the site). Only group the dropdown when it earns its keep — at
least two sections and one with more than one item — so audio (HTML5 Audio +
Mux) and background stay flat instead of stacking lone headers.

Adds pure tests for buildOptions/buildGroups and keeps the install-tabs
observer re-attaching across CDN-tab visibility changes (documented
biome-ignore for the intentional effect dependency).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Kd5A9UsSz5Ka7nYhEik3Fd
@netlify

netlify Bot commented Jun 23, 2026

Copy link
Copy Markdown

Deploy Preview for vjs10-site ready!

Name Link
🔨 Latest commit 06cc121
🔍 Latest deploy log https://app.netlify.com/projects/vjs10-site/deploys/6a3c41516490e700088ce732
😎 Deploy Preview https://deploy-preview-1732--vjs10-site.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.
🤖 Make changes Run an agent on this branch

To edit notification comments on pull requests, go to your Netlify project configuration.

@vercel

vercel Bot commented Jun 23, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
v10-sandbox Ready Ready Preview, Comment Jun 24, 2026 8:43pm

Request Review

@github-actions

github-actions Bot commented Jun 23, 2026

Copy link
Copy Markdown
Contributor

📦 Bundle Size Report

🎨 @videojs/html — no changes
Presets (7)
Entry Initial
/video (default) 44.32 kB
/video (default + hls) 183.79 kB
/video (minimal) 43.98 kB
/video (minimal + hls) 183.63 kB
/audio (default) 37.83 kB
/audio (minimal) 36.61 kB
/background 4.20 kB
Media (10)
Entry Initial
/media/background-video 1.14 kB
/media/container 1.72 kB
/media/dash-video 214.74 kB
/media/hls-video 141.27 kB
/media/mux-audio 163.91 kB
/media/mux-video 163.68 kB
/media/native-hls-video 9.05 kB
/media/simple-hls-audio-only 17.15 kB
/media/simple-hls-video 18.69 kB
/media/vimeo-video 12.31 kB
Players (5)
Entry Initial
/video/player 8.07 kB
/audio/player 5.38 kB
/background/player 3.92 kB
/live-video/player 7.64 kB
/live-audio/player 5.39 kB
Skins (30)
Entry Type Initial
/video/minimal-skin.css css 5.45 kB
/video/skin.css css 5.43 kB
/video/minimal-skin js 44.01 kB
/video/minimal-skin.tailwind js 44.58 kB
/video/skin js 44.28 kB
/video/skin.tailwind js 44.98 kB
/audio/minimal-skin.css css 3.60 kB
/audio/skin.css css 3.53 kB
/audio/minimal-skin js 36.62 kB
/audio/minimal-skin.tailwind js 37.04 kB
/audio/skin js 37.80 kB
/audio/skin.tailwind js 38.25 kB
/background/skin.css css 133 B
/background/skin js 1.14 kB
/live-video/minimal-skin.css css 5.45 kB
/live-video/skin.css css 5.43 kB
/live-video/minimal-skin js 43.12 kB
/live-video/minimal-skin.tailwind js 43.58 kB
/live-video/skin js 43.08 kB
/live-video/skin.tailwind js 43.58 kB
/live-audio/minimal-skin.css css 3.60 kB
/live-audio/skin.css css 3.53 kB
/live-audio/minimal-skin js 29.73 kB
/live-audio/minimal-skin.tailwind js 29.20 kB
/live-audio/skin js 31.04 kB
/live-audio/skin.tailwind js 30.66 kB
/global.css css 176 B
/shared.css css 88 B
/tailwind.css css 228 B
/skin-element js 1.44 kB
UI Components (38)
Entry Initial
/ui/airplay-button 2.29 kB
/ui/alert-dialog 2.45 kB
/ui/alert-dialog-close 2.15 kB
/ui/alert-dialog-description 2.18 kB
/ui/alert-dialog-title 2.17 kB
/ui/buffering-indicator 2.24 kB
/ui/captions-button 2.37 kB
/ui/captions-radio-group 2.73 kB
/ui/cast-button 2.25 kB
/ui/compounds 2.85 kB
/ui/controls 2.58 kB
/ui/error-dialog 2.61 kB
/ui/fullscreen-button 2.29 kB
/ui/hotkey 2.31 kB
/ui/menu 2.63 kB
/ui/mute-button 2.27 kB
/ui/pip-button 2.28 kB
/ui/play-button 2.28 kB
/ui/playback-rate-button 2.36 kB
/ui/playback-rate-radio-group 2.78 kB
/ui/popover 2.64 kB
/ui/poster 2.14 kB
/ui/quality-radio-group 2.75 kB
/ui/seek-button 2.27 kB
/ui/seek-indicator 2.29 kB
/ui/seek-indicator-value 465 B
/ui/slider 2.62 kB
/ui/status-announcer 2.28 kB
/ui/status-indicator 2.36 kB
/ui/status-indicator-value 467 B
/ui/thumbnail 2.09 kB
/ui/time 2.60 kB
/ui/time-slider 2.64 kB
/ui/tooltip 2.59 kB
/ui/volume-indicator 2.36 kB
/ui/volume-indicator-fill 410 B
/ui/volume-indicator-value 426 B
/ui/volume-slider 2.64 kB

Sizes are marginal over the root entry point.

⚛️ @videojs/react — no changes
Presets (7)
Entry Initial
/video (default) 36.83 kB
/video (default + hls) 175.18 kB
/video (minimal) 36.91 kB
/video (minimal + hls) 175.13 kB
/audio (default) 29.97 kB
/audio (minimal) 30.04 kB
/background 754 B
Media (9)
Entry Initial
/media/background-video 575 B
/media/dash-video 213.24 kB
/media/hls-video 139.80 kB
/media/mux-audio 162.26 kB
/media/mux-video 162.26 kB
/media/native-hls-video 7.39 kB
/media/simple-hls-audio-only 15.56 kB
/media/simple-hls-video 17.15 kB
/media/vimeo-video 10.58 kB
Skins (27)
Entry Type Initial
/tailwind.css css 228 B
/video/minimal-skin.css css 5.37 kB
/video/skin.css css 5.34 kB
/video/minimal-skin js 36.81 kB
/video/minimal-skin.tailwind js 42.58 kB
/video/skin js 36.73 kB
/video/skin.tailwind js 42.51 kB
/audio/minimal-skin.css css 3.47 kB
/audio/skin.css css 3.39 kB
/audio/minimal-skin js 29.98 kB
/audio/minimal-skin.tailwind js 31.76 kB
/audio/skin js 29.91 kB
/audio/skin.tailwind js 33.75 kB
/background/skin.css css 90 B
/background/skin js 272 B
/live-video/minimal-skin.css css 5.37 kB
/live-video/skin.css css 5.34 kB
/live-video/minimal-skin js 32.56 kB
/live-video/minimal-skin.tailwind js 38.22 kB
/live-video/skin js 32.58 kB
/live-video/skin.tailwind js 38.24 kB
/live-audio/minimal-skin.css css 3.47 kB
/live-audio/skin.css css 3.39 kB
/live-audio/minimal-skin js 21.74 kB
/live-audio/minimal-skin.tailwind js 24.64 kB
/live-audio/skin js 21.78 kB
/live-audio/skin.tailwind js 24.78 kB
UI Components (32)
Entry Initial
/ui/airplay-button 2.23 kB
/ui/alert-dialog 2.20 kB
/ui/buffering-indicator 2.10 kB
/ui/captions-button 2.16 kB
/ui/captions-radio-group 2.09 kB
/ui/cast-button 2.19 kB
/ui/controls 2.05 kB
/ui/error-dialog 2.24 kB
/ui/fullscreen-button 2.26 kB
/ui/gesture 2.25 kB
/ui/hotkey 2.27 kB
/ui/live-button 2.12 kB
/ui/menu 2.43 kB
/ui/mute-button 2.24 kB
/ui/pip-button 2.26 kB
/ui/play-button 2.19 kB
/ui/playback-rate 2.06 kB
/ui/playback-rate-button 2.25 kB
/ui/popover 2.64 kB
/ui/poster 2.09 kB
/ui/quality 2.10 kB
/ui/seek-button 2.20 kB
/ui/seek-indicator 2.19 kB
/ui/slider 2.26 kB
/ui/status-announcer 2.11 kB
/ui/status-indicator 2.15 kB
/ui/thumbnail 2.00 kB
/ui/time 2.05 kB
/ui/time-slider 2.29 kB
/ui/tooltip 2.59 kB
/ui/volume-indicator 2.18 kB
/ui/volume-slider 2.30 kB

Sizes are marginal over the root entry point.

🧩 @videojs/core — no changes
Entries (14)
Entry Initial
. 9.08 kB
/dom 17.02 kB
/dom/media/custom-media-element 2.09 kB
/dom/media/dash 209.07 kB
/dom/media/google-cast 4.04 kB
/dom/media/hls 135.63 kB
/dom/media/media-host 1.25 kB
/dom/media/media-played-ranges 576 B
/dom/media/mux 151.26 kB
/dom/media/native-hls 3.05 kB
/dom/media/simple-hls 16.47 kB
/dom/media/simple-hls-audio-only 14.92 kB
/dom/media/vimeo 9.86 kB
/media/predicate 573 B
🏷️ @videojs/element — no changes
Entries (2)
Entry Initial
. 996 B
/context 943 B
📦 @videojs/store — no changes
Entries (3)
Entry Initial
. 1.39 kB
/html 696 B
/react 360 B
🔧 @videojs/utils — no changes
Entries (10)
Entry Initial
/array 104 B
/dom 2.26 kB
/events 319 B
/function 327 B
/object 275 B
/predicate 265 B
/string 231 B
/style 190 B
/time 478 B
/number 158 B
📦 @videojs/spf — no changes
Entries (4)
Entry Initial
. 4.45 kB
/dom 6.33 kB
/hls 15.37 kB
/background-video 12.85 kB

ℹ️ How to interpret

JS sizes are initial static graph totals (minified + brotli). Lazy dynamic chunks are shown separately when present.

Icon Meaning
No change
🔺 Increased ≤ 10%
🔴 Increased > 10%
🔽 Decreased
🆕 New (no baseline)

Run pnpm size locally to check current initial sizes.

Smaller text, top/bottom borders, and sentence case (drop uppercase) for
the Select group labels used by the installation renderer picker.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Kd5A9UsSz5Ka7nYhEik3Fd
The `docs how-to/installation` command shared the site's codegen,
detection, and source defaults but kept its own presentation layer,
which lagged behind the new media renderers and CDN gating.

- Reuse the site's `renderer-options` (RENDERER_LABELS, buildOptions)
  so labels and ordering (files → streaming formats → hosting services)
  stay in lockstep with the install page; accepted `--media` values are
  now derived from the shared label map instead of a hardcoded list.
- Gate CDN by the generated `cdn-media` manifest via `rendererSupportsCdn`
  — same source of truth as the install page. The interactive prompt
  hides CDN for renderers without a CDN build (e.g. Vimeo), and the
  non-interactive flag path errors instead of emitting a broken snippet.
- Extend the bundled-site type shim with the new Renderer union members,
  the cdn-code and renderer-options modules, and the cdn-media.json import;
  alias the manifest and shared module in tsdown and vitest configs.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Kd5A9UsSz5Ka7nYhEik3Fd
The CLI's `test` turbo task is intentionally dependency-free, so the
generated `site/src/content/cdn-media.json` (a `cdn-manifest` output) is
never produced in the test job — `prompts.ts` importing it failed CI with
`ERR_MODULE_NOT_FOUND`.

Point the vitest alias at a committed fixture that mirrors the manifest's
shape and contents, keeping CLI tests hermetic and fast. The tsdown build
still bundles the real generated manifest, which `^build` produces.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Kd5A9UsSz5Ka7nYhEik3Fd
@decepulis decepulis changed the title docs(site): add DASH, Mux, and Vimeo to the installation renderer picker feat: add DASH, Mux, and Vimeo as installation source types (UI + CLI) Jun 24, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: No status

Development

Successfully merging this pull request may close these issues.

Docs: Add Missing Media Elements to Installation Page

2 participants