remotion-dev/remotion · error · Error

Unexpected PES packet start code: ${ident.toString(16)}

Error message

Unexpected PES packet start code: ${ident.toString(16)}

What it means

Thrown by parsePes at parse-pes.ts:20 when the first three bytes of a PES packet (the 'packet_start_code_prefix') are not 0x000001. ISO/IEC 13818-1 mandates every PES packet begin with this 24-bit prefix; any other value means the iterator is not aligned on a PES boundary.

Source

Thrown at packages/media-parser/src/containers/transport-stream/parse-pes.ts:20

export type PacketPes = {
	streamId: number;
	dts: number | null;
	pts: number;
	priority: number;
	offset: number;
};

export const parsePes = ({
	iterator,
	offset,
}: {
	iterator: BufferIterator;
	offset: number;
}) => {
	const ident = iterator.getUint24();
	if (ident !== 0x000001) {
		throw new Error(`Unexpected PES packet start code: ${ident.toString(16)}`);
	}

	const streamId = iterator.getUint8();
	iterator.getUint16(); // PES packet length, is most of the time 0, so useless
	iterator.startReadingBits();
	const markerBits = iterator.getBits(2);
	if (markerBits !== 0b10) {
		throw new Error(`Invalid marker bits: ${markerBits}`);
	}

	const scrambled = iterator.getBits(2);
	if (scrambled !== 0b00) {
		throw new Error(`Only supporting non-scrambled streams`);
	}

	const priority = iterator.getBits(1);
	iterator.getBits(1); // data alignment indicator
	iterator.getBits(1); // copy right

View on GitHub (pinned to 78fe4bb3fd)

Solutions

  1. Re-mux with ffmpeg -i in.ts -c copy out.ts to rebuild PES framing.
  2. If you control the source, ensure the muxer emits the standard 0x000001 start code prefix.
  3. Validate the file with ffprobe before parsing; if ffprobe also fails, the file is damaged.
  4. Report a bug to @remotion/media-parser if ffprobe parses the file cleanly but Remotion does not.
Defensive patterns

Strategy: try-catch

Try / catch

try { await parseMedia({src: tsUrl}); }
catch (e) {
  if (e instanceof Error && e.message.startsWith('Unexpected PES packet start code')) {
    // PES framing is broken - re-mux and retry
    await runFfmpeg(['-i', tsUrl, '-c', 'copy', tsUrl + '.remux.ts']);
    await parseMedia({src: tsUrl + '.remux.ts'});
  } else throw e;
}

Prevention

When it happens

Trigger: parsePes calls iterator.getUint24() and compares to 0x000001; mismatch throws. Triggered when the wrong PID is routed to PES parsing, when a PES payload is fed instead of the header, or when transport-stream buffering has desynchronized the byte cursor.

Common situations: Truncated or partially written .ts files; bit-for-bit corruption of the start code; an internal library bug where discardRestOfPacket left the iterator at the wrong offset; switching audio/video PIDs in a multi-program transport stream.

Related errors


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