remotion-dev/remotion · error · std::io::Error

No video stream found in ${file_path}. Is this a video file?

Error message

No video stream found in ${file_path}. Is this a video file?

What it means

Thrown by get_video_metadata when ffmpeg's input context has no stream of media::Type::Video. Remotion needs a video stream to read codec, dimensions, duration, and playback metadata, so a file without one cannot be probed.

Source

Thrown at packages/compositor/rust/get_video_metadata.rs:23

};

use crate::{
    errors::ErrorWithBacktrace,
    payloads::payloads::{KnownAudioCodecs, KnownCodecs, KnownColorSpaces, VideoMetadata},
};

// https://docs.rs/ffmpeg-next/6.0.0/src/metadata/metadata.rs.html#35
pub fn get_video_metadata(file_path: &str) -> Result<VideoMetadata, ErrorWithBacktrace> {
    // Initialize the FFmpeg library
    remotionffmpeg::init().map_err(|e| e.to_string())?;

    // Open the input file
    let input = remotionffmpeg::format::input(&file_path)?;

    // Find the video stream
    let video_stream = match input.streams().best(remotionffmpeg::media::Type::Video) {
        Some(video_stream) => video_stream,
        None => Err(std::io::Error::new(
            ErrorKind::Other,
            format!(
                "No video stream found in {}. Is this a video file?",
                file_path
            ),
        ))?,
    };

    // Audio stream, only if has one

    let audio_stream = input.streams().best(remotionffmpeg::media::Type::Audio);

    let video_codec_id = unsafe { (*(*(video_stream).as_ptr()).codecpar).codec_id };
    let color_space = unsafe { (*(*(video_stream).as_ptr()).codecpar).color_space };
    let audio_codec_id = match audio_stream {
        Some(audio_stream) => unsafe { (*(*(audio_stream).as_ptr()).codecpar).codec_id },
        None => remotionffmpeg::ffi::AVCodecID::AV_CODEC_ID_NONE,
    };

View on GitHub (pinned to 78fe4bb3fd)

Solutions

  1. Verify the file with `ffprobe <file_path>` and confirm a video stream is reported.
  2. Use the correct media file containing a video stream, or use an audio-only API for audio assets.
  3. Install a full ffmpeg build with the relevant demuxer/decoder enabled.

Example fix

// before
const meta = await getVideoMetadata(filePath);

// after
const probe = await getVideoMetadata(filePath).catch(() => null);
if (!probe) {
  throw new Error(`${filePath} has no playable video stream`);
}
Defensive patterns

Strategy: validation

Validate before calling

fn has_video_stream(path: &str) -> Result<bool, String> {
    let input = remotionffmpeg::format::input(path).map_err(|e| e.to_string())?;
    Ok(input.streams().best(remotionffmpeg::media::Type::Video).is_some())
}

Type guard

null

Try / catch

null

Prevention

When it happens

Trigger: Passing an audio-only file (e.g. .mp3, .wav, .m4a), an image, or a corrupt/unrecognized container to get_video_metadata. Also triggered when the ffmpeg build lacks the demuxer for the container so no streams are exposed.

Common situations: Accidentally pointing a <Video>/<OffthreadVideo> src at an audio file; loading a file with an extension ffmpeg cannot parse; using a minimal ffmpeg build missing the needed demuxer.

Related errors


AI-assisted analysis of remotion-dev/remotion@78fe4bb3fd (2026-08-12). Data as JSON: /api/errors/b45056719d9a5ade. Report an issue: GitHub.