Skip to content

<video> / <audio> with only <source src> children skip extract and mix #3495

Description

@valeriangalliat

Describe the bug

A <video> or <audio> that supplies its URL only via a child <source src> (no parent src) plays in preview and is skipped at export.

The runtime already resolves el.currentSrc || el.src. Engine extract and mix still query video[src] / audio[src], so those elements are never extracted or mixed. Lint media_missing_src agrees with the engine and tells you to put src on the parent.

Common HTML multi-format pattern. Parent src can stay preferred for Studio bind / variables; child <source> should still count as a resolvable src.

On 0.8.14 the skipped video is blank, not frozen. A native first-frame paint (frozen magenta) is the other face of the same skip — no frames extracted or injected. Audio is always missing.

Link to reproduction

https://github.com/ArcadeHQ/hyperframes-repros/tree/patch/video-source

Steps to reproduce

  1. Clone https://github.com/ArcadeHQ/hyperframes-repros and check out patch/video-source.
  2. Run npx hyperframes@latest checkmedia_missing_src on #source-only.
  3. Run npx hyperframes@latest render --output renders/source-only.mp4.
  4. Grab frames: ffmpeg -y -ss 0.3 -i renders/source-only.mp4 -frames:v 1 snapshots/frame-00-at-0.3s.png and the same at 1.5s.
  5. Run ffprobe -hide_banner renders/source-only.mp4.

Same 2s clip twice (magenta 0–1s, cyan 1–2s, 440 Hz). Left: parent src, muted. Right: <source> only, audible.

Expected behavior

  • t=0.3s: both panes magenta
  • t=1.5s: both panes cyan
  • Output has an audio stream (~440 Hz)

Actual behavior

  • t=0.3s: left magenta; right black
  • t=1.5s: left cyan; right still black
  • ffprobe: video stream only — no audio
  • Compile: videoCount: 1, audioCount: 0 with authoredTimedClipCount: 3

See snapshots/frame-00-at-0.3s.png and snapshots/frame-01-at-1.5s.png.

hyperframes snapshot (browser path) plays both panes. The gap is export.

Environment

hyperframes doctor

  ✓ Version          0.8.14 (latest)
  ✓ Node.js          v24.19.0 (darwin arm64)
  ✓ CPU              10 cores · Apple M1 Pro @ 2400MHz
  ✓ Memory           16.0 GB total · 4.9 GB available
  ✓ Disk             363.3 GB free
  ✓ Frames cache     /var/folders/bl/c4hk6r7n34g1d81txd99gsgr0000gn/T/hyperframes-extract-cache-501 · 363.3 GB free at /var/folders/bl/c4hk6r7n34g1d81txd99gsgr0000gn/T/hyperframes-extract-cache-501 · default
  ✓ Archive extractor unzip
  ✓ Environment      non-TTY
  ✗ whisper-cpp      Not found (optional — needed for transcription)
  ✗ TTS (Kokoro)     Not installed (optional — local voice fallback)
  ✗ BGM (MusicGen)   Not installed (optional — local music fallback)
  ✓ FFmpeg           ffmpeg 8.1.2 at /opt/homebrew/bin/ffmpeg
  ✓ FFprobe          ffprobe 8.1.2 at /opt/homebrew/bin/ffprobe
  ✓ Chrome           cache: /Users/val/.cache/puppeteer/chrome-headless-shell/mac_arm-152.0.7977.42/chrome-headless-shell-mac-arm64/chrome-headless-shell
  ✗ Docker           Not found
  ✗ Docker running   Not running

Additional context

Same over-narrow-selector family as tests/sub-composition-video and tests/video-hfid-no-id. Runtime half: mediaProxy.ts el.currentSrc || el.src.

Fix already in #3238 — this issue is so that PR can close it.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions