Skip to content

Duplicate media element ids across nested compositions collapse the render media pipeline #3340

Description

@valeriangalliat

Describe the bug

Nested compositions that reuse the same media element id are legal per file and lint-clean. At export, those files are inlined into one document. Id-keyed stages of the media pipeline then collide: extract/dedupe collapses to one entry, and frame injection resolves document.getElementById(id) to the first match in document order. The visible scene’s <video> never receives frames — scene chrome still paints; footage does not.

Preview often looks correct because each scene loads in isolation (no single inlined document).

Link to reproduction

https://github.com/ArcadeHQ/hyperframes-repros/tree/patch/unique-media-render-keys

Steps to reproduce

  1. Clone https://github.com/ArcadeHQ/hyperframes-repros and check out patch/unique-media-render-keys.
  2. Run npx hyperframes lint (expect 0 errors — duplicate ids across files are allowed).
  3. Preview / editor: both scenes show the long-take (SMPTE bars).
  4. Run npm run render (or npx hyperframes@0.8.3 render -f 10).
  5. Watch the compile log: videoCount: 1 (should be 2). Open the MP4: green panel then purple panel (scene backgrounds + labels), no color bars.

The project has two 3s nested scenes that each declare <video id="clip"> with different data-media-start (5 vs 50).

Expected behavior

Both halves show footage (different source slices). Extract should report two videos. Inject should target each scene’s own element. It should match the preview.

Actual behavior

On hyperframes@0.8.3:

  • videoCount: 1, totalFramesExtracted: 30 at 10fps (one 3s window, not two).
  • Rendered MP4 is scene chrome only (green → purple). Source frames at 5s / 50s are SMPTE color bars.

Environment

  ✓ Version          0.8.3 (latest)
  ✓ Node.js          v24.19.0 (darwin arm64)
  ✓ CPU              10 cores · Apple M1 Pro @ 2400MHz
  ✓ Memory           16.0 GB total · 3.0 GB available
  ✓ Disk             345.3 GB free
  ✓ Frames cache     /var/folders/bl/c4hk6r7n34g1d81txd99gsgr0000gn/T/hyperframes-extract-cache-501 · 345.3 GB free at /var/folders/bl/c4hk6r7n34g1d81txd99gsgr0000gn/T/hyperframes-extract-cache-501 · default
  ✓ Archive extractor unzip
  ✓ Environment      Native terminal
  ✗ whisper-cpp      Not found (optional — needed for transcription)
                     brew install whisper-cpp
  ✗ TTS (Kokoro)     Not installed (optional — local voice fallback)
                     pip install kokoro-onnx soundfile
  ✗ BGM (MusicGen)   Not installed (optional — local music fallback)
                     pip install transformers torch soundfile numpy
  ✓ 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-150.0.7871.24/chrome-headless-shell-mac-arm64/chrome-headless-shell
  ✗ Docker           Not found
                     https://docs.docker.com/get-docker/
  ✗ Docker running   Not running
                     Start Docker Desktop or run: sudo systemctl start docker

Metadata

Metadata

Assignees

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