{"record":{"id":"b45056719d9a5ade","repo":"remotion-dev/remotion","slug":"no-video-stream-found-in-file-path-is-this-a-v","errorCode":null,"errorMessage":"No video stream found in ${file_path}. Is this a video file?","messagePattern":"No video stream found in (.+?)\\. Is this a video file\\?","errorType":"error_code","errorClass":"std::io::Error","httpStatus":null,"severity":"error","filePath":"packages/compositor/rust/get_video_metadata.rs","lineNumber":23,"sourceCode":"};\n\nuse crate::{\n    errors::ErrorWithBacktrace,\n    payloads::payloads::{KnownAudioCodecs, KnownCodecs, KnownColorSpaces, VideoMetadata},\n};\n\n// https://docs.rs/ffmpeg-next/6.0.0/src/metadata/metadata.rs.html#35\npub fn get_video_metadata(file_path: &str) -> Result<VideoMetadata, ErrorWithBacktrace> {\n    // Initialize the FFmpeg library\n    remotionffmpeg::init().map_err(|e| e.to_string())?;\n\n    // Open the input file\n    let input = remotionffmpeg::format::input(&file_path)?;\n\n    // Find the video stream\n    let video_stream = match input.streams().best(remotionffmpeg::media::Type::Video) {\n        Some(video_stream) => video_stream,\n        None => Err(std::io::Error::new(\n            ErrorKind::Other,\n            format!(\n                \"No video stream found in {}. Is this a video file?\",\n                file_path\n            ),\n        ))?,\n    };\n\n    // Audio stream, only if has one\n\n    let audio_stream = input.streams().best(remotionffmpeg::media::Type::Audio);\n\n    let video_codec_id = unsafe { (*(*(video_stream).as_ptr()).codecpar).codec_id };\n    let color_space = unsafe { (*(*(video_stream).as_ptr()).codecpar).color_space };\n    let audio_codec_id = match audio_stream {\n        Some(audio_stream) => unsafe { (*(*(audio_stream).as_ptr()).codecpar).codec_id },\n        None => remotionffmpeg::ffi::AVCodecID::AV_CODEC_ID_NONE,\n    };","sourceCodeStart":5,"sourceCodeEnd":41,"githubUrl":"https://github.com/remotion-dev/remotion/blob/78fe4bb3fdb5a2cd68724393d63cb223db333fa7/packages/compositor/rust/get_video_metadata.rs#L5-L41","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Verify the file with `ffprobe <file_path>` and confirm a video stream is reported.","Use the correct media file containing a video stream, or use an audio-only API for audio assets.","Install a full ffmpeg build with the relevant demuxer/decoder enabled."],"exampleFix":"// before\nconst meta = await getVideoMetadata(filePath);\n\n// after\nconst probe = await getVideoMetadata(filePath).catch(() => null);\nif (!probe) {\n  throw new Error(`${filePath} has no playable video stream`);\n}","handlingStrategy":"validation","validationCode":"fn has_video_stream(path: &str) -> Result<bool, String> {\n    let input = remotionffmpeg::format::input(path).map_err(|e| e.to_string())?;\n    Ok(input.streams().best(remotionffmpeg::media::Type::Video).is_some())\n}","typeGuard":"null","tryCatchPattern":"null","preventionTips":["Run ffprobe on user-supplied paths before passing to get_video_metadata.","Use audio-specific APIs for audio-only assets.","Install a full ffmpeg build with needed demuxers."],"tags":["rust","ffmpeg","video","missing-stream","media-metadata"],"backgroundTag":null,"analyzedSha":"78fe4bb3fdb5a2cd68724393d63cb223db333fa7","analyzedAt":"2026-08-12T17:18:50.444Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}