mediabunny 1.34.1 → 1.34.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -34,15 +34,15 @@ Mediabunny is a JavaScript library for reading, writing, and converting media fi
34
34
  <a href="https://kino.ai/" target="_blank" rel="sponsored">
35
35
  <img src="./docs/public/sponsors/kino.jpg" width="60" height="60" alt="Kino">
36
36
  </a>
37
+ &nbsp;&nbsp;&nbsp;&nbsp;
38
+ <a href="https://screen.studio/" target="_blank" rel="sponsored">
39
+ <img src="./docs/public/sponsors/screen-studio.webp" width="60" height="60" alt="Screen Studio">
40
+ </a>
37
41
  </div>
38
42
 
39
43
  ### Silver sponsors
40
44
 
41
45
  <div align="center">
42
- <a href="https://pqina.nl/pintura/" target="_blank" rel="sponsored">
43
- <img src="./docs/public/sponsors/pintura-labs.png" width="50" height="50" alt="Pintura Labs">
44
- </a>
45
- &nbsp;&nbsp;&nbsp;&nbsp;
46
46
  <a href="https://ponder.ai/" target="_blank" rel="sponsored">
47
47
  <img src="./docs/public/sponsors/ponder.png" width="50" height="50" alt="Ponder">
48
48
  </a>
@@ -14057,8 +14057,12 @@ var Mediabunny = (() => {
14057
14057
  if (!slice) return;
14058
14058
  const id3V2Header = readId3V2Header(slice);
14059
14059
  if (id3V2Header) {
14060
- const contentSlice = slice.slice(startPos + 10, id3V2Header.size);
14061
- parseId3V2Tag(contentSlice, id3V2Header, this.metadataTags);
14060
+ const availableSize = size - ID3_V2_HEADER_SIZE;
14061
+ id3V2Header.size = Math.min(id3V2Header.size, availableSize);
14062
+ if (id3V2Header.size > 0) {
14063
+ const contentSlice = slice.slice(startPos + ID3_V2_HEADER_SIZE, id3V2Header.size);
14064
+ parseId3V2Tag(contentSlice, id3V2Header, this.metadataTags);
14065
+ }
14062
14066
  }
14063
14067
  }
14064
14068
  getCodec() {
@@ -24334,9 +24338,6 @@ ${cue.notes ?? ""}`;
24334
24338
  this.allTracksKnown = promiseWithResolvers();
24335
24339
  this.videoTrackIndex = 0;
24336
24340
  this.audioTrackIndex = 0;
24337
- this.pesHeaderBuffer = new Uint8Array(14);
24338
- this.pesHeaderView = toDataView(this.pesHeaderBuffer);
24339
- this.ptsBitstream = new Bitstream(this.pesHeaderBuffer.subarray(9, 14));
24340
24341
  this.adaptationFieldBuffer = new Uint8Array(184);
24341
24342
  this.payloadBuffer = new Uint8Array(184);
24342
24343
  this.format = format;
@@ -24367,6 +24368,7 @@ ${cue.notes ?? ""}`;
24367
24368
  streamType,
24368
24369
  streamId,
24369
24370
  codecString: meta.decoderConfig.codec,
24371
+ timestampProcessingQueue: [],
24370
24372
  packetQueue: [],
24371
24373
  inputIsAnnexB: null,
24372
24374
  inputIsAdts: null,
@@ -24430,6 +24432,7 @@ ${cue.notes ?? ""}`;
24430
24432
  streamType,
24431
24433
  streamId,
24432
24434
  codecString: meta.decoderConfig.codec,
24435
+ timestampProcessingQueue: [],
24433
24436
  packetQueue: [],
24434
24437
  inputIsAnnexB: null,
24435
24438
  inputIsAdts: null,
@@ -24455,12 +24458,15 @@ ${cue.notes ?? ""}`;
24455
24458
  packet.type === "key"
24456
24459
  );
24457
24460
  const preparedData = this.prepareVideoPacket(trackData, packet, meta);
24458
- trackData.packetQueue.push({
24461
+ if (packet.type === "key") {
24462
+ await this.flushTimestampQueue(trackData);
24463
+ }
24464
+ trackData.timestampProcessingQueue.push({
24459
24465
  data: preparedData,
24460
- timestamp,
24466
+ presentationTimestamp: timestamp,
24467
+ decodeTimestamp: null,
24461
24468
  isKeyframe: packet.type === "key"
24462
24469
  });
24463
- await this.interleavePackets();
24464
24470
  } finally {
24465
24471
  release();
24466
24472
  }
@@ -24475,12 +24481,15 @@ ${cue.notes ?? ""}`;
24475
24481
  packet.type === "key"
24476
24482
  );
24477
24483
  const preparedData = this.prepareAudioPacket(trackData, packet, meta);
24478
- trackData.packetQueue.push({
24484
+ if (packet.type === "key") {
24485
+ await this.flushTimestampQueue(trackData);
24486
+ }
24487
+ trackData.timestampProcessingQueue.push({
24479
24488
  data: preparedData,
24480
- timestamp,
24489
+ presentationTimestamp: timestamp,
24490
+ decodeTimestamp: null,
24481
24491
  isKeyframe: packet.type === "key"
24482
24492
  });
24483
- await this.interleavePackets();
24484
24493
  } finally {
24485
24494
  release();
24486
24495
  }
@@ -24606,6 +24615,21 @@ ${cue.notes ?? ""}`;
24606
24615
  }
24607
24616
  return true;
24608
24617
  }
24618
+ async flushTimestampQueue(trackData, alsoInterleave = true) {
24619
+ if (trackData.timestampProcessingQueue.length === 0) {
24620
+ return;
24621
+ }
24622
+ const sortedTimestamps = trackData.timestampProcessingQueue.map((packet) => packet.presentationTimestamp).sort((a, b) => a - b);
24623
+ for (let i = 0; i < trackData.timestampProcessingQueue.length; i++) {
24624
+ const queuedPacket = trackData.timestampProcessingQueue[i];
24625
+ queuedPacket.decodeTimestamp = sortedTimestamps[i];
24626
+ trackData.packetQueue.push(queuedPacket);
24627
+ }
24628
+ trackData.timestampProcessingQueue.length = 0;
24629
+ if (alsoInterleave) {
24630
+ await this.interleavePackets();
24631
+ }
24632
+ }
24609
24633
  async interleavePackets(isFinalCall = false) {
24610
24634
  if (!this.tablesWritten) {
24611
24635
  if (!this.allTracksAreKnown() && !isFinalCall) {
@@ -24621,9 +24645,9 @@ ${cue.notes ?? ""}`;
24621
24645
  if (!isFinalCall && trackData.packetQueue.length === 0 && !trackData.track.source._closed) {
24622
24646
  break outer;
24623
24647
  }
24624
- if (trackData.packetQueue.length > 0 && trackData.packetQueue[0].timestamp < minTimestamp) {
24648
+ if (trackData.packetQueue.length > 0 && trackData.packetQueue[0].presentationTimestamp < minTimestamp) {
24625
24649
  trackWithMinTimestamp = trackData;
24626
- minTimestamp = trackData.packetQueue[0].timestamp;
24650
+ minTimestamp = trackData.packetQueue[0].presentationTimestamp;
24627
24651
  }
24628
24652
  }
24629
24653
  if (!trackWithMinTimestamp) {
@@ -24664,24 +24688,39 @@ ${cue.notes ?? ""}`;
24664
24688
  }
24665
24689
  }
24666
24690
  writePesPacket(trackData, queuedPacket) {
24667
- const pesView = this.pesHeaderView;
24691
+ const includeDts = trackData.track.type === "video";
24692
+ const headerDataLength = includeDts ? 10 : 5;
24693
+ const pesHeaderBuffer = new Uint8Array(9 + headerDataLength);
24694
+ const pesView = toDataView(pesHeaderBuffer);
24695
+ const ptsDtsBitstream = new Bitstream(pesHeaderBuffer.subarray(9));
24668
24696
  setUint24(pesView, 0, 1, false);
24669
- this.pesHeaderBuffer[3] = trackData.streamId;
24697
+ pesHeaderBuffer[3] = trackData.streamId;
24670
24698
  const pesPacketLength = trackData.track.type === "video" ? 0 : Math.min(8 + queuedPacket.data.length, 65535);
24671
24699
  pesView.setUint16(4, pesPacketLength, false);
24672
24700
  pesView.setUint8(6, 132);
24673
- pesView.setUint8(7, 128);
24674
- pesView.setUint8(8, 5);
24675
- const pts = Math.round(queuedPacket.timestamp * TIMESCALE);
24676
- this.ptsBitstream.pos = 0;
24677
- this.ptsBitstream.writeBits(4, 2);
24678
- this.ptsBitstream.writeBits(3, pts >>> 30 & 7);
24679
- this.ptsBitstream.writeBits(1, 1);
24680
- this.ptsBitstream.writeBits(15, pts >>> 15 & 32767);
24681
- this.ptsBitstream.writeBits(1, 1);
24682
- this.ptsBitstream.writeBits(15, pts & 32767);
24683
- this.ptsBitstream.writeBits(1, 1);
24684
- const totalLength = this.pesHeaderBuffer.length + queuedPacket.data.length;
24701
+ pesView.setUint8(7, includeDts ? 192 : 128);
24702
+ pesView.setUint8(8, headerDataLength);
24703
+ const pts = Math.round(queuedPacket.presentationTimestamp * TIMESCALE);
24704
+ ptsDtsBitstream.pos = 0;
24705
+ ptsDtsBitstream.writeBits(4, includeDts ? 3 : 2);
24706
+ ptsDtsBitstream.writeBits(3, pts >>> 30 & 7);
24707
+ ptsDtsBitstream.writeBits(1, 1);
24708
+ ptsDtsBitstream.writeBits(15, pts >>> 15 & 32767);
24709
+ ptsDtsBitstream.writeBits(1, 1);
24710
+ ptsDtsBitstream.writeBits(15, pts & 32767);
24711
+ ptsDtsBitstream.writeBits(1, 1);
24712
+ if (includeDts) {
24713
+ assert(queuedPacket.decodeTimestamp !== null);
24714
+ const dts = Math.round(queuedPacket.decodeTimestamp * TIMESCALE);
24715
+ ptsDtsBitstream.writeBits(4, 1);
24716
+ ptsDtsBitstream.writeBits(3, dts >>> 30 & 7);
24717
+ ptsDtsBitstream.writeBits(1, 1);
24718
+ ptsDtsBitstream.writeBits(15, dts >>> 15 & 32767);
24719
+ ptsDtsBitstream.writeBits(1, 1);
24720
+ ptsDtsBitstream.writeBits(15, dts & 32767);
24721
+ ptsDtsBitstream.writeBits(1, 1);
24722
+ }
24723
+ const totalLength = pesHeaderBuffer.length + queuedPacket.data.length;
24685
24724
  let offset = 0;
24686
24725
  let isFirstTsPacket = true;
24687
24726
  while (offset < totalLength) {
@@ -24711,12 +24750,12 @@ ${cue.notes ?? ""}`;
24711
24750
  const payloadSize = Math.min(184 - adaptationFieldSize, remainingData);
24712
24751
  const payload = this.payloadBuffer.subarray(0, payloadSize);
24713
24752
  let payloadOffset = 0;
24714
- if (offset < this.pesHeaderBuffer.length) {
24715
- const headerBytes = Math.min(this.pesHeaderBuffer.length - offset, payloadSize);
24716
- payload.set(this.pesHeaderBuffer.subarray(offset, offset + headerBytes), 0);
24753
+ if (offset < pesHeaderBuffer.length) {
24754
+ const headerBytes = Math.min(pesHeaderBuffer.length - offset, payloadSize);
24755
+ payload.set(pesHeaderBuffer.subarray(offset, offset + headerBytes), 0);
24717
24756
  payloadOffset = headerBytes;
24718
24757
  }
24719
- const dataStart = Math.max(0, offset - this.pesHeaderBuffer.length);
24758
+ const dataStart = Math.max(0, offset - pesHeaderBuffer.length);
24720
24759
  const dataEnd = dataStart + (payloadSize - payloadOffset);
24721
24760
  if (payloadOffset < payloadSize) {
24722
24761
  payload.set(queuedPacket.data.subarray(dataStart, dataEnd), payloadOffset);
@@ -24754,17 +24793,24 @@ ${cue.notes ?? ""}`;
24754
24793
  }
24755
24794
  }
24756
24795
  // eslint-disable-next-line @typescript-eslint/no-misused-promises
24757
- async onTrackClose() {
24796
+ async onTrackClose(track) {
24758
24797
  const release = await this.mutex.acquire();
24759
24798
  if (this.allTracksAreKnown()) {
24760
24799
  this.allTracksKnown.resolve();
24761
24800
  }
24801
+ const trackData = this.trackDatas.find((x) => x.track === track);
24802
+ if (trackData) {
24803
+ await this.flushTimestampQueue(trackData, false);
24804
+ }
24762
24805
  await this.interleavePackets();
24763
24806
  release();
24764
24807
  }
24765
24808
  async finalize() {
24766
24809
  const release = await this.mutex.acquire();
24767
24810
  this.allTracksKnown.resolve();
24811
+ for (const trackData of this.trackDatas) {
24812
+ await this.flushTimestampQueue(trackData, false);
24813
+ }
24768
24814
  await this.interleavePackets(true);
24769
24815
  release();
24770
24816
  }