{"record":{"id":"5b5b8cbba834b5da","repo":"remotion-dev/remotion","slug":"invalid-marker-bits-markerbits","errorCode":null,"errorMessage":"Invalid marker bits: ${markerBits}","messagePattern":"Invalid marker bits: (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/media-parser/src/containers/transport-stream/parse-pes.ts","lineNumber":28,"sourceCode":"\nexport const parsePes = ({\n\titerator,\n\toffset,\n}: {\n\titerator: BufferIterator;\n\toffset: number;\n}) => {\n\tconst ident = iterator.getUint24();\n\tif (ident !== 0x000001) {\n\t\tthrow new Error(`Unexpected PES packet start code: ${ident.toString(16)}`);\n\t}\n\n\tconst streamId = iterator.getUint8();\n\titerator.getUint16(); // PES packet length, is most of the time 0, so useless\n\titerator.startReadingBits();\n\tconst markerBits = iterator.getBits(2);\n\tif (markerBits !== 0b10) {\n\t\tthrow new Error(`Invalid marker bits: ${markerBits}`);\n\t}\n\n\tconst scrambled = iterator.getBits(2);\n\tif (scrambled !== 0b00) {\n\t\tthrow new Error(`Only supporting non-scrambled streams`);\n\t}\n\n\tconst priority = iterator.getBits(1);\n\titerator.getBits(1); // data alignment indicator\n\titerator.getBits(1); // copy right\n\titerator.getBits(1); // original or copy\n\tconst ptsPresent = iterator.getBits(1);\n\tconst dtsPresent = iterator.getBits(1);\n\tif (!ptsPresent && dtsPresent) {\n\t\tthrow new Error(\n\t\t\t`DTS is present but not PTS, this is not allowed in the spec`,\n\t\t);\n\t}","sourceCodeStart":10,"sourceCodeEnd":46,"githubUrl":"https://github.com/remotion-dev/remotion/blob/78fe4bb3fdb5a2cd68724393d63cb223db333fa7/packages/media-parser/src/containers/transport-stream/parse-pes.ts#L10-L46","documentation":"Thrown at parse-pes.ts:28 when the two 'marker_bits' of a PES header (the first two bits after the PES_packet_length) are not equal to binary '10'. Per ISO/IEC 13818-1 these bits are fixed at '10' in MPEG-2; any deviation means the bytes are not a valid MPEG-2 PES header (possibly an MPEG-1 stream or corrupted data).","triggerScenarios":"parsePes reads getBits(2) and compares to 0b10; mismatch throws. Triggered by MPEG-1 system streams (which use different marker conventions), by feeding a non-PES payload to parsePes, or by bit corruption in the PES header.","commonSituations":"Source files muxed as MPEG-1 instead of MPEG-2; corrupt captures from faulty encoders; misrouted elementary-stream bytes; partial files where the header bytes are missing.","solutions":["Re-mux as MPEG-2 transport stream: ffmpeg -i in.mp4 -c copy -f mpegts out.ts.","If the source is genuinely MPEG-1, transcode to a supported container/codec.","Verify the PES header bytes with a hex dump or dvbsnoop.","If the file parses in ffprobe but not here, file a bug with the sample attached."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try { await parseMedia({src: tsUrl}); }\ncatch (e) {\n  if (e instanceof Error && e.message.startsWith('Invalid marker bits')) {\n    // not a valid MPEG-2 PES - re-encode\n    await runFfmpeg(['-i', tsUrl, '-c:v', 'libx264', '-c:a', 'aac', '-f', 'mpegts', outUrl]);\n    await parseMedia({src: outUrl});\n  } else throw e;\n}","preventionTips":["Ensure sources are muxed as MPEG-2 (not MPEG-1) transport streams.","Re-encode legacy MPEG-1 content to MPEG-2/H.264 transport streams.","Validate with ffprobe -show_format to confirm format=mpegts."],"tags":["media-parser","transport-stream","mpegts","pes","validation"],"backgroundTag":null,"analyzedSha":"78fe4bb3fdb5a2cd68724393d63cb223db333fa7","analyzedAt":"2026-08-12T17:18:50.444Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}