remotion-dev/remotion · error · Error

No video sample

Error message

No video sample

What it means

Thrown by makeBaseMediaTrack() for a track identified as video. getStsdVideoConfig(trakBox) returned a falsy value, so no video sample description (dimensions + coded size from stsd) could be read. Without it the parser cannot establish width/height/coded dimensions, so it aborts.

Source

Thrown at packages/media-parser/src/containers/iso-base-media/make-track.ts:120

	if (!trakBoxContainsVideo(trakBox)) {
		return {
			type: 'other',
			trackId: tkhdBox.trackId,
			originalTimescale: timescaleAndDuration.timescale,
			trakBox,
			startInSeconds: startTimeInSeconds,
			timescale: WEBCODECS_TIMESCALE,
			trackMediaTimeOffsetInTrackTimescale:
				findTrackMediaTimeOffsetInTrackTimescale({
					trakBox,
				}),
		};
	}

	const videoSample = getStsdVideoConfig(trakBox);
	if (!videoSample) {
		throw new Error('No video sample');
	}

	const sampleAspectRatio = getSampleAspectRatio(trakBox);

	const aspectRatioApplied = applyAspectRatios({
		dimensions: videoSample,
		sampleAspectRatio,
		displayAspectRatio: getDisplayAspectRatio({
			sampleAspectRatio,
			nativeDimensions: videoSample,
		}),
	});

	const {displayAspectHeight, displayAspectWidth, height, rotation, width} =
		applyTkhdBox(aspectRatioApplied, tkhdBox);

	const codec = getVideoCodecString(trakBox);

View on GitHub (pinned to 78fe4bb3fd)

Solutions

  1. Validate with ffprobe <file> to confirm a video stream with dimensions is reported.
  2. Re-mux: ffmpeg -i in.mp4 -c:v copy out.mp4; if the codec is unsupported, transcode to H.264: ffmpeg -i in.mp4 -c:v libx264 -crf 20 out.mp4.
  3. Use @remotion/mediabunny, which may recognise more sample-entry types.
  4. Confirm the track is genuinely video and not a cover/hint track before parsing.

Example fix

// before
const {dimensions} = await parseMedia({src, reader: nodeReader});

// after
const dim = await parseMedia({src, reader: nodeReader}).then(
  (r) => r.dimensions,
  (err) => {
    if (err instanceof Error && /No video sample/.test(err.message)) {
      console.warn('Video sample description unreadable; re-mux or transcode with ffmpeg');
      return null;
    }
    throw err;
  },
);
Defensive patterns

Strategy: try-catch

Validate before calling

// Confirm a video stream with dimensions is reported before parsing:
//   ffprobe -v error -select_streams v:0 -show_entries stream=width,height -of csv=s=x:p=0 in.mp4
import {execFileSync} from 'node:child_process';
function videoSampleReadable(file: string): boolean {
  try {
    const out = execFileSync('ffprobe',
      ['-v','error','-select_streams','v:0','-show_entries','stream=width,height','-of','csv=s=x:p=0', file],
      {encoding: 'utf8'});
    return /^\d+x\d+$/.test(out.trim());
  } catch { return false; }
}

Type guard

// No caller-side type guard: the stsd video sample entry is a deep binary
// structure. parseMedia() input is a URL/File/Uint8Array.
// => typeGuard: null

Try / catch

let dimensions: {width: number; height: number} | null = null;
try {
  ({dimensions} = await parseMedia({src, reader: nodeReader}));
} catch (err) {
  if (err instanceof Error && /No video sample/.test(err.message)) {
    dimensions = null; // video sample description unreadable
  } else {
    throw err;
  }
}

Prevention

When it happens

Trigger: parseMedia({src}) on a video MP4/MOV whose trak has a corrupted, empty, or unsupported stsd video entry. Also fires when trakBoxContainsVideo is true but the stsd sample description box is missing or its FourCC is not one the parser recognises when extracting the video sample config.

Common situations: Files where the video track header exists but the sample description is stripped/truncated; 'video' tracks that are actually cover-art/hint/metadata tracks; non-standard or very new video codecs.

Related errors


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