Skip to content

<Audio> at composition root resolves to duration=Infinity in ffmpeg filter graph #4

@thecodacus

Description

@thecodacus

Summary

A bare <Audio src={...} /> placed at the root of a <Composition> (no endAt prop, no wrapping <Sequence>) causes the renderer to emit duration=Infinity into the ffmpeg atrim filter, which crashes the render.

Reproduction

// MyChapter.tsx
import { CanvasElement, Audio, staticFile } from '@rendiv/core';

export const CHAPTER_DURATION = 3814;

export const MyChapter = () => (
  <CanvasElement id="MyChapter">
    <Audio src={staticFile('audio/chapter.mp3')} />
    {/* ...other content sized to CHAPTER_DURATION... */}
  </CanvasElement>
);

// index.tsx
<Composition
  id=\"MyChapter\"
  component={MyChapter}
  durationInFrames={CHAPTER_DURATION}
  fps={30}
  width={1920}
  height={1080}
/>

Run:

rendiv render src/index.tsx MyChapter out/MyChapter.mp4

Actual

FFmpeg exited with code 234:
[Parsed_atrim_0 @ 0x...] Unable to parse option value \"Infinity\" as duration
Error applying option 'duration' to filter 'atrim': Invalid argument
Failed to set value '[1:a]atrim=start=0.000000:duration=Infinity,asetpts=PTS-STARTPTS[aout]'
  for option 'filter_complex': Invalid argument

Expected

The renderer should treat `` without an explicit `endAt` as bounded by the parent composition's `durationInFrames` — same behavior as Remotion.

Workaround

Explicitly pass `endAt`:
```tsx
<Audio src={staticFile('audio/chapter.mp3')} endAt={CHAPTER_DURATION} />
```

This works, but every chapter master in the project needed the same one-line fix, and the failure mode (`duration=Infinity` from ffmpeg) was very far from the cause.

Suggested fixes (any one would help; all three would be ideal)

  1. Default `endAt` to composition duration. When `` has no `endAt` and no wrapping ``, treat it as `endAt = compositionDurationInFrames`.

  2. Guard the filter-graph emitter. Before serializing `atrim=duration=${value}`, `assert(Number.isFinite(value))` and throw with a useful message, e.g.:

    `Audio src="..." resolved to infinite duration. Pass endAt={N} or wrap in .`

  3. Mount-time lint. Walk the composition tree once and warn for any `` / `

Environment

  • `@rendiv/core`: ^0.1.0
  • `@rendiv/cli`: ^0.1.0
  • ffmpeg: 7.0.2-static
  • OS: Debian inside Docker container (headless)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions