diff --git a/dev/demux.html b/dev/demux.html
index f22e924..84fe728 100644
--- a/dev/demux.html
+++ b/dev/demux.html
@@ -14,11 +14,11 @@
source: new Mediabunny.BufferSource(await file.arrayBuffer()),
});
- const track = await input.getPrimaryAudioTrack();
+ const track = await input.getPrimaryVideoTrack();
const sink = new Mediabunny.EncodedPacketSink(track);
for await (const packet of sink.packets()) {
- console.log(packet.timestamp, packet.duration, packet.type);
+ //console.log(packet.timestamp, packet.duration, packet.type);
}
/*
diff --git a/src/mpeg-ts/mpeg-ts-demuxer.ts b/src/mpeg-ts/mpeg-ts-demuxer.ts
index e1d6318..d54ef02 100644
--- a/src/mpeg-ts/mpeg-ts-demuxer.ts
+++ b/src/mpeg-ts/mpeg-ts-demuxer.ts
@@ -638,10 +638,6 @@ const readPesPacketHeader = (section: Section): PesPacketHeader | null => {
bitstream.skipBits(14);
- if (ptsDtsFlags !== 0b10 && ptsDtsFlags !== 0b11) {
- return null; // Support only timestamped packets
- }
-
let pts = 0;
if (ptsDtsFlags === 0b10 || ptsDtsFlags === 0b11) {
bitstream.skipBits(4);
@@ -651,7 +647,10 @@ const readPesPacketHeader = (section: Section): PesPacketHeader | null => {
bitstream.skipBits(1);
pts += bitstream.readBits(15);
} else {
- return null; // Support only timestamped packets
+ throw new Error(
+ 'PES packets without PTS are not currently supported. If you think this file should be supported,'
+ + ' please report it.',
+ );
}
return {
diff --git a/src/mpeg-ts/mpeg-ts-muxer.ts b/src/mpeg-ts/mpeg-ts-muxer.ts
index 8f4ee62..22a3fcc 100644
--- a/src/mpeg-ts/mpeg-ts-muxer.ts
+++ b/src/mpeg-ts/mpeg-ts-muxer.ts
@@ -52,6 +52,7 @@ type MpegTsTrackData = {
hevcDecoderConfig: HevcDecoderConfigurationRecord | null;
adtsHeader: Uint8Array | null;
adtsHeaderBitstream: Bitstream | null;
+ firstPacketWritten: boolean;
};
type QueuedPacket = {
@@ -128,6 +129,7 @@ export class MpegTsMuxer extends Muxer {
hevcDecoderConfig: null,
adtsHeader: null,
adtsHeaderBitstream: null,
+ firstPacketWritten: false,
};
this.trackDatas.push(newTrackData);
@@ -168,6 +170,7 @@ export class MpegTsMuxer extends Muxer {
hevcDecoderConfig: null,
adtsHeader: null,
adtsHeaderBitstream: null,
+ firstPacketWritten: false,
};
this.trackDatas.push(newTrackData);
@@ -518,18 +521,19 @@ export class MpegTsMuxer extends Muxer {
const totalLength = this.pesHeaderBuffer.length + queuedPacket.data.length;
let offset = 0;
- let isFirst = true;
+ let isFirstTsPacket = true;
while (offset < totalLength) {
- const pusi = isFirst;
+ const pusi = isFirstTsPacket;
const remainingData = totalLength - offset;
- const needsRandomAccessIndicator = isFirst && queuedPacket.isKeyframe;
+ const randomAccessIndicator = isFirstTsPacket && queuedPacket.isKeyframe;
+ const discontinuityIndicator = isFirstTsPacket && !trackData.firstPacketWritten;
const basePaddingNeeded = Math.max(0, 184 - remainingData);
let adaptationFieldSize: number;
- if (needsRandomAccessIndicator) {
- // Random access indicator requires at least 2 bytes
+ if (randomAccessIndicator || discontinuityIndicator) {
+ // We need at least two bytes
adaptationFieldSize = Math.max(2, basePaddingNeeded);
} else {
adaptationFieldSize = basePaddingNeeded;
@@ -543,7 +547,9 @@ export class MpegTsMuxer extends Muxer {
buf[0] = 0; // adaptation_field_length
} else {
buf[0] = adaptationFieldSize - 1; // adaptation_field_length
- buf[1] = Number(needsRandomAccessIndicator) << 6; // flags (random_access_indicator in bit 6)
+ buf[1]
+ = (Number(discontinuityIndicator) << 7) // discontinuity_indicator
+ | (Number(randomAccessIndicator) << 6); // random_access_indicator
buf.fill(0xFF, 2, adaptationFieldSize); // stuffing_bytes
}
@@ -569,8 +575,10 @@ export class MpegTsMuxer extends Muxer {
this.writeTsPacket(trackData.pid, pusi, adaptationField, payload);
offset += payloadSize;
- isFirst = false;
+ isFirstTsPacket = false;
}
+
+ trackData.firstPacketWritten = true;
}
private writeTsPacket(