remotion-dev/remotion · error · Error

Unsupported bits per sample

Error message

Unsupported bits per sample: ${bitsPerSample}

What it means

After accepting the format tag, parseFmt maps bitsPerSample to a codec string: 16 -> pcm-s16, 32 -> pcm-s32, 24 -> pcm-s24. Any other bit depth has no mapping and is rejected because the WebCodecs decode path only covers those three. The thrown value is the raw bitsPerSample.

Solutions

  1. Inspect bitsPerSample via ffprobe or soxi.
  2. Convert to a supported depth: ffmpeg -i in.wav -c:a pcm_s16le out.wav (or pcm_s24le / pcm_s32le).
  3. For 8-bit sources, upscale to 16-bit with ffmpeg.
  4. Use Mediabunny; fall back in try/catch otherwise.

Example fix

# 8-bit WAV -> 16-bit PCM
ffmpeg -i in.wav -c:a pcm_s16le out.wav

await parseMedia({ src: 'out.wav' });
Defensive patterns

Strategy: try-catch

Validate before calling

// check bit depth first
// ffprobe -show_entries stream=bits_per_sample -of default=nw=1 in.wav
// must be 16, 24, or 32

Type guard

const SUPPORTED_BITS = new Set([16, 24, 32]);
const isSupportedBitDepth = (bits: number) => SUPPORTED_BITS.has(bits);

Try / catch

try {
  await parseMedia({ src: 'in.wav' });
} catch (err) {
  if (err instanceof Error && /bits per sample/i.test(err.message)) {
    // unsupported depth — convert with ffmpeg or skip
  } else throw err;
}

Prevention

When it happens

Trigger: A PCM WAV whose bitsPerSample is not 16/24/32: most often 8-bit PCM, 32-bit float mislabeled with wFormatTag 1, or unusual 12/20/48-bit depths.

Common situations: 8-bit WAVs from old games/samplers; 32-bit float files saved without the EXTENSIBLE wrapper; niche high-res audio.

Related errors


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

Appendix: source

Thrown at packages/media-parser/src/containers/wav/parse-fmt.ts:76

		);
	}

	const numberOfChannels = iterator.getUint16Le();
	const sampleRate = iterator.getUint32Le();
	const byteRate = iterator.getUint32Le();
	const blockAlign = iterator.getUint16Le();
	const bitsPerSample = iterator.getUint16Le();

	const format =
		bitsPerSample === 16
			? 'pcm-s16'
			: bitsPerSample === 32
				? 'pcm-s32'
				: bitsPerSample === 24
					? 'pcm-s24'
					: null;
	if (format === null) {
		throw new Error(`Unsupported bits per sample: ${bitsPerSample}`);
	}

	const wavHeader: WavFmt = {
		bitsPerSample,
		blockAlign,
		byteRate,
		numberOfChannels,
		sampleRate,
		type: 'wav-fmt',
	};

	state.structure.getWavStructure().boxes.push(wavHeader);

	if (audioFormat === 65534) {
		const extraSize = iterator.getUint16Le();
		if (extraSize !== 22) {
			throw new Error(
				`Only supporting WAVE with 22 extra bytes, but got ${extraSize} bytes extra size`,

View on GitHub (pinned to 78fe4bb3fd)