remotion-dev/remotion · error · Error

Unknown codec: ${codec.value}

Error message

Unknown codec: ${codec.value}

What it means

Thrown by `getMatroskaVideoCodecEnum` (make-track.ts:76) when the `CodecID` string of a video track is not one of V_VP8, V_VP9, V_MPEG4/ISO/AVC, V_AV1, V_MPEGH/ISO/HEVC. The parser enumerates only those five Matroska video codecs; any other CodecID is unsupported.

Source

Thrown at packages/media-parser/src/containers/webm/make-track.ts:76

	}

	if (codec.value === 'V_VP9') {
		return 'vp9';
	}

	if (codec.value === 'V_MPEG4/ISO/AVC') {
		return 'h264';
	}

	if (codec.value === 'V_AV1') {
		return 'av1';
	}

	if (codec.value === 'V_MPEGH/ISO/HEVC') {
		return 'h265';
	}

	throw new Error(`Unknown codec: ${codec.value}`);
};

const getMatroskaVideoCodecString = ({
	track,
	codecSegment: codec,
}: {
	track: TrackEntry;
	codecSegment: CodecIdSegment;
}): string | null => {
	if (codec.value === 'V_VP8') {
		return 'vp8';
	}

	if (codec.value === 'V_VP9') {
		const priv = getPrivateData(track);
		if (priv) {
			throw new Error(
				'@remotion/media-parser cannot handle the private data for VP9. Do you have an example file you could send so we can implement it? https://remotion.dev/report',

View on GitHub (pinned to 78fe4bb3fd)

Solutions

  1. Transcode the video to a supported codec: `ffmpeg -i in.mkv -c:v libx264 out.mkv` (H.264) or `-c:v libvpx-vp9 out.webm`.
  2. If you only need metadata that doesn't require decoding this track, request narrower fields and skip the offending track.
  3. Report the codec at https://remotion.dev/report if you believe it should be supported.
  4. Catch the error and present 'unsupported codec' feedback to the end user.

Example fix

// before
const { tracks } = await parseMedia({ src: 'legacy.mkv', fields: { tracks: true } });

// after — transcode first
// $ ffmpeg -i legacy.mkv -c:v libx264 -c:a aac supported.mkv
const { tracks } = await parseMedia({ src: 'supported.mkv', fields: { tracks: true } });
Defensive patterns

Strategy: validation

Validate before calling

// Probe the file's codecs before handing it to parseMedia.
// Uses ffprobe (must be on PATH). Returns the list of video codec names.
import { execFile } from 'node:child_process';
import { promisify } from 'node:util';
const exec = promisify(execFile);
async function getVideoCodecs(filePath) {
  const { stdout } = await exec('ffprobe', ['-v', 'error', '-select_entries', 'stream=codec_name', '-of', 'csv=p=0', filePath]);
  return stdout.trim().split('\n').filter(Boolean);
}
const SUPPORTED = new Set(['h264', 'vp8', 'vp9', 'av1', 'hevc']);
async function isSupportedVideo(filePath) {
  const codecs = await getVideoCodecs(filePath);
  return codecs.every((c) => SUPPORTED.has(c));
}

Try / catch

try {
  await parseMedia({ src, fields: { tracks: true } });
} catch (err) {
  if (err instanceof Error && err.message.startsWith('Unknown codec: V_')) {
    console.error('Unsupported video codec:', err.message);
    // Transcode with ffmpeg to H.264/AV1/VP9 and retry.
  }
  throw err;
}

Prevention

When it happens

Trigger: A WebM/MKV whose video track uses a CodecID outside the supported set — e.g. `V_THEORA`, `V_MPEG4/ISO/ASP`, `V_MPEG4/ISO/SP`, `V_MS/VFW/FOURCC`, `V_REAL/RV10`, or a custom/fourcc codec. Fires during the tracks pass of `parseMedia({ fields: { tracks: true } })`.

Common situations: Legacy MKV files (Theora, DivX, Xvid, WMV, RealVideo); MKVs created by older muxers; mislabelled test fixtures. WebM strictly allows VP8/VP9/AV1, so this is far more common with .mkv than .webm.

Related errors


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