remotion-dev/remotion · error · Error

cannot process avc stream

Error message

cannot process avc stream

What it means

Thrown by the AVC (H.264) packet processing path at process-video.ts:56 when get2ndSubArrayIndex() returns -1 or 0. get2ndSubArrayIndex searches for the second occurrence of the NAL-unit start code [0,0,1,9] (AUD - Access Unit Delimiter); a -1 means only one (or zero) AUD has been buffered, and 0 means the buffer starts exactly on the second AUD with no payload in between. Both indicate the AVC stream cannot be cleanly split into access units.

Source

Thrown at packages/media-parser/src/containers/transport-stream/process-video.ts:56

	transportStream,
	makeSamplesStartAtZero,
	avcState,
}: {
	programId: number;
	structure: TransportStreamStructure;
	streamBuffer: TransportStreamPacketBuffer;
	sampleCallbacks: CallbacksState;
	logLevel: MediaParserLogLevel;
	onAudioTrack: MediaParserOnAudioTrack | null;
	onVideoTrack: MediaParserOnVideoTrack | null;
	transportStream: TransportStreamState;
	makeSamplesStartAtZero: boolean;
	avcState: AvcState;
}): Promise<Uint8Array> => {
	const indexOfSeparator = streamBuffer.get2ndSubArrayIndex();

	if (indexOfSeparator === -1 || indexOfSeparator === 0) {
		throw new Error('cannot process avc stream');
	}

	const buf = streamBuffer.getBuffer();
	const packet = buf.slice(0, indexOfSeparator);
	const rest = buf.slice(indexOfSeparator);

	await processStreamBuffer({
		streamBuffer: makeTransportStreamPacketBuffer({
			offset: streamBuffer.offset,
			pesHeader: streamBuffer.pesHeader,
			// Replace the regular 0x00000001 with 0x00000002 to avoid confusion with other 0x00000001 (?)
			buffers: packet,
		}),
		programId,
		structure,
		sampleCallbacks,
		logLevel,
		onAudioTrack,

View on GitHub (pinned to 78fe4bb3fd)

Solutions

  1. Re-encode with AUD insertion: ffmpeg -i in.ts -c:v libx264 -flags +aud -c:a copy out.ts.
  2. Re-mux to MP4 which does not rely on AUD framing: ffmpeg -i in.ts -c copy out.mp4.
  3. Ensure the input is complete before parsing.
  4. Verify with h264_parse or ffmpeg -loglevel debug that AUD NAL units are present.
Defensive patterns

Strategy: validation

Validate before calling

// Re-encode to insert AUD NAL units and/or remux to MP4
import {execSync} from 'node:child_process';
function ensureAudNalUnits(src: string): string {
  const out = src + '.aud.ts';
  execSync(`ffmpeg -y -i "${src}" -c:v libx264 -flags +aud -c:a copy "${out}"`);
  return out;
}

Try / catch

try { await parseMedia({src}); }
catch (e) {
  if (e instanceof Error && e.message === 'cannot process avc stream') {
    // either incomplete or no AUD - re-encode with AUDs or remux to MP4
    await runFfmpeg(['-i', src, '-c:v', 'libx264', '-flags', '+aud', '-c:a', 'copy', out]);
    await parseMedia({src: out});
  } else throw e;
}

Prevention

When it happens

Trigger: processVideo computes indexOfSeparator via get2ndSubArrayIndex and throws when it equals -1 or 0. Triggered when the buffered AVC bytes contain fewer than two AUD start codes (incomplete frame), when start codes are corrupted/misaligned, or when an encoder omits AUDs entirely.

Common situations: Partial captures; H.264 encoders that do not emit Access Unit Delimiter NAL units (common with some hardware encoders); bit corruption that destroys the 0x00000109 sequence; live streams parsed before enough data has accumulated.

Related errors


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