remotion-dev/remotion · error · Error
PTS is required
Error message
PTS is required
What it means
Thrown at parse-pes.ts:58 when the PTS_DTS_flags indicate PTS is not present. Although the MPEG-TS spec allows PTS to be absent for some stream types, this library mandates PTS for every PES packet it processes so that timestamps can always be derived for samples.
Source
Thrown at packages/media-parser/src/containers/transport-stream/parse-pes.ts:58
const ptsPresent = iterator.getBits(1);
const dtsPresent = iterator.getBits(1);
if (!ptsPresent && dtsPresent) {
throw new Error(
`DTS is present but not PTS, this is not allowed in the spec`,
);
}
iterator.getBits(1); // escr flag
iterator.getBits(1); // es rate flag
iterator.getBits(1); // dsm trick mode flag
iterator.getBits(1); // additional copy info flag
iterator.getBits(1); // crc flag
iterator.getBits(1); // extension flag
const pesHeaderLength = iterator.getBits(8);
const offsetAfterHeader = iterator.counter.getOffset();
let pts: number | null = null;
if (!ptsPresent) {
throw new Error(`PTS is required`);
}
const fourBits = iterator.getBits(4);
if (fourBits !== 0b0011 && fourBits !== 0b0010) {
throw new Error(`Invalid PTS marker bits: ${fourBits}`);
}
const pts1 = iterator.getBits(3);
iterator.getBits(1); // marker bit
const pts2 = iterator.getBits(15);
iterator.getBits(1); // marker bit
const pts3 = iterator.getBits(15);
iterator.getBits(1); // marker bit
pts = (pts1 << 30) | (pts2 << 15) | pts3;
let dts: number | null = null;
if (dtsPresent) {
const _fourBits = iterator.getBits(4);View on GitHub (pinned to 78fe4bb3fd)
Solutions
- Re-mux with ffmpeg so every PES packet carries PTS: ffmpeg -i in.ts -c copy -mpegts_flags +resend_headers out.ts.
- Filter out non-AV PIDs before parsing if only audio/video is needed.
- Use a different source if the file is a damaged capture.
- If the stream type is genuinely PTS-less, transcode to a container that always carries timestamps (e.g. MP4).
Defensive patterns
Strategy: try-catch
Try / catch
try { await parseMedia({src}); }
catch (e) {
if (e instanceof Error && e.message === 'PTS is required') {
// re-encode to force PTS on every PES packet
await runFfmpeg(['-i', src, '-c:v', 'libx264', '-c:a', 'aac', '-f', 'mpegts', out]);
await parseMedia({src: out});
} else throw e;
} Prevention
- Filter out non-AV PIDs before parsing.
- Re-encode streams that omit PTS to MP4 or remuxed MPEG-TS.
- Avoid feeding private-stream/subtitle PES packets into the AV path.
When it happens
Trigger: After reading ptsPresent/dtsPresent, parsePes checks !ptsPresent and throws. Triggered by streams that legitimately omit PTS (e.g. some padding streams, program_stream_map, or low-overhead private streams) or by corruption that clears the flag.
Common situations: Elementary streams with sparse PTS; private-stream PES packets; non-AV streams (e.g. DVB subtitles, teletext) routed through the AV path; partial captures where the flag byte is wrong.
Related errors
- DTS is present but not PTS, this is not allowed in the spec
- Invalid PTS marker bits: ${fourBits}
- Unexpected PES packet start code: ${ident.toString(16)}
- Invalid marker bits: ${markerBits}
- Only supporting non-scrambled streams
AI-assisted analysis of remotion-dev/remotion@78fe4bb3fd (2026-08-12).
Data as JSON: /api/errors/244bfea1b3790535.
Report an issue: GitHub.