mediabunny 1.4.3 → 1.4.4

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.
@@ -13571,199 +13571,195 @@ ${cue.notes ?? ""}`;
13571
13571
  return firstPacket?.timestamp ?? 0;
13572
13572
  }
13573
13573
  async getFirstPacket(options) {
13574
- if (this.internalTrack.demuxer.isFragmented) {
13575
- return this.performFragmentedLookup(
13576
- () => {
13577
- const startFragment = this.internalTrack.demuxer.fragments[0] ?? null;
13578
- if (startFragment?.isKnownToBeFirstFragment) {
13579
- let currentFragment = startFragment;
13580
- while (currentFragment) {
13581
- const trackData = currentFragment.trackData.get(this.internalTrack.id);
13582
- if (trackData) {
13583
- return {
13584
- fragmentIndex: binarySearchExact(
13585
- this.internalTrack.fragments,
13586
- currentFragment.moofOffset,
13587
- (x) => x.moofOffset
13588
- ),
13589
- sampleIndex: 0,
13590
- correctSampleFound: true
13591
- };
13592
- }
13593
- currentFragment = currentFragment.nextFragment;
13574
+ const regularPacket = await this.fetchPacketForSampleIndex(0, options);
13575
+ if (regularPacket || !this.internalTrack.demuxer.isFragmented) {
13576
+ return regularPacket;
13577
+ }
13578
+ return this.performFragmentedLookup(
13579
+ () => {
13580
+ const startFragment = this.internalTrack.demuxer.fragments[0] ?? null;
13581
+ if (startFragment?.isKnownToBeFirstFragment) {
13582
+ let currentFragment = startFragment;
13583
+ while (currentFragment) {
13584
+ const trackData = currentFragment.trackData.get(this.internalTrack.id);
13585
+ if (trackData) {
13586
+ return {
13587
+ fragmentIndex: binarySearchExact(
13588
+ this.internalTrack.fragments,
13589
+ currentFragment.moofOffset,
13590
+ (x) => x.moofOffset
13591
+ ),
13592
+ sampleIndex: 0,
13593
+ correctSampleFound: true
13594
+ };
13594
13595
  }
13596
+ currentFragment = currentFragment.nextFragment;
13595
13597
  }
13596
- return {
13597
- fragmentIndex: -1,
13598
- sampleIndex: -1,
13599
- correctSampleFound: false
13600
- };
13601
- },
13602
- -Infinity,
13603
- // Use -Infinity as a search timestamp to avoid using the lookup entries
13604
- Infinity,
13605
- options
13606
- );
13607
- }
13608
- return this.fetchPacketForSampleIndex(0, options);
13598
+ }
13599
+ return {
13600
+ fragmentIndex: -1,
13601
+ sampleIndex: -1,
13602
+ correctSampleFound: false
13603
+ };
13604
+ },
13605
+ -Infinity,
13606
+ // Use -Infinity as a search timestamp to avoid using the lookup entries
13607
+ Infinity,
13608
+ options
13609
+ );
13609
13610
  }
13610
13611
  mapTimestampIntoTimescale(timestamp) {
13611
13612
  return roundToPrecision(timestamp * this.internalTrack.timescale, 14) + this.internalTrack.editListOffset;
13612
13613
  }
13613
13614
  async getPacket(timestamp, options) {
13614
13615
  const timestampInTimescale = this.mapTimestampIntoTimescale(timestamp);
13615
- if (this.internalTrack.demuxer.isFragmented) {
13616
- return this.performFragmentedLookup(
13617
- () => this.findSampleInFragmentsForTimestamp(timestampInTimescale),
13618
- timestampInTimescale,
13619
- timestampInTimescale,
13620
- options
13621
- );
13622
- } else {
13623
- const sampleTable = this.internalTrack.demuxer.getSampleTableForTrack(this.internalTrack);
13624
- const sampleIndex = getSampleIndexForTimestamp(sampleTable, timestampInTimescale);
13625
- return this.fetchPacketForSampleIndex(sampleIndex, options);
13616
+ const sampleTable = this.internalTrack.demuxer.getSampleTableForTrack(this.internalTrack);
13617
+ const sampleIndex = getSampleIndexForTimestamp(sampleTable, timestampInTimescale);
13618
+ const regularPacket = await this.fetchPacketForSampleIndex(sampleIndex, options);
13619
+ if (!sampleTableIsEmpty(sampleTable) || !this.internalTrack.demuxer.isFragmented) {
13620
+ return regularPacket;
13626
13621
  }
13622
+ return this.performFragmentedLookup(
13623
+ () => this.findSampleInFragmentsForTimestamp(timestampInTimescale),
13624
+ timestampInTimescale,
13625
+ timestampInTimescale,
13626
+ options
13627
+ );
13627
13628
  }
13628
13629
  async getNextPacket(packet, options) {
13629
- if (this.internalTrack.demuxer.isFragmented) {
13630
- const locationInFragment = this.packetToFragmentLocation.get(packet);
13631
- if (locationInFragment === void 0) {
13632
- throw new Error("Packet was not created from this track.");
13633
- }
13634
- const trackData = locationInFragment.fragment.trackData.get(this.internalTrack.id);
13635
- const fragmentSample = trackData.samples[locationInFragment.sampleIndex];
13636
- const fragmentIndex = binarySearchExact(
13637
- this.internalTrack.fragments,
13638
- locationInFragment.fragment.moofOffset,
13639
- (x) => x.moofOffset
13640
- );
13641
- assert(fragmentIndex !== -1);
13642
- return this.performFragmentedLookup(
13643
- () => {
13644
- if (locationInFragment.sampleIndex + 1 < trackData.samples.length) {
13645
- return {
13646
- fragmentIndex,
13647
- sampleIndex: locationInFragment.sampleIndex + 1,
13648
- correctSampleFound: true
13649
- };
13650
- } else {
13651
- let currentFragment = locationInFragment.fragment;
13652
- while (currentFragment.nextFragment) {
13653
- currentFragment = currentFragment.nextFragment;
13654
- const trackData2 = currentFragment.trackData.get(this.internalTrack.id);
13655
- if (trackData2) {
13656
- const fragmentIndex2 = binarySearchExact(
13657
- this.internalTrack.fragments,
13658
- currentFragment.moofOffset,
13659
- (x) => x.moofOffset
13660
- );
13661
- assert(fragmentIndex2 !== -1);
13662
- return {
13663
- fragmentIndex: fragmentIndex2,
13664
- sampleIndex: 0,
13665
- correctSampleFound: true
13666
- };
13667
- }
13668
- }
13669
- return {
13670
- fragmentIndex,
13671
- sampleIndex: -1,
13672
- correctSampleFound: false
13673
- };
13674
- }
13675
- },
13676
- fragmentSample.presentationTimestamp,
13677
- Infinity,
13678
- options
13679
- );
13630
+ const regularSampleIndex = this.packetToSampleIndex.get(packet);
13631
+ if (regularSampleIndex !== void 0) {
13632
+ return this.fetchPacketForSampleIndex(regularSampleIndex + 1, options);
13680
13633
  }
13681
- const sampleIndex = this.packetToSampleIndex.get(packet);
13682
- if (sampleIndex === void 0) {
13634
+ const locationInFragment = this.packetToFragmentLocation.get(packet);
13635
+ if (locationInFragment === void 0) {
13683
13636
  throw new Error("Packet was not created from this track.");
13684
13637
  }
13685
- return this.fetchPacketForSampleIndex(sampleIndex + 1, options);
13638
+ const trackData = locationInFragment.fragment.trackData.get(this.internalTrack.id);
13639
+ const fragmentSample = trackData.samples[locationInFragment.sampleIndex];
13640
+ const fragmentIndex = binarySearchExact(
13641
+ this.internalTrack.fragments,
13642
+ locationInFragment.fragment.moofOffset,
13643
+ (x) => x.moofOffset
13644
+ );
13645
+ assert(fragmentIndex !== -1);
13646
+ return this.performFragmentedLookup(
13647
+ () => {
13648
+ if (locationInFragment.sampleIndex + 1 < trackData.samples.length) {
13649
+ return {
13650
+ fragmentIndex,
13651
+ sampleIndex: locationInFragment.sampleIndex + 1,
13652
+ correctSampleFound: true
13653
+ };
13654
+ } else {
13655
+ let currentFragment = locationInFragment.fragment;
13656
+ while (currentFragment.nextFragment) {
13657
+ currentFragment = currentFragment.nextFragment;
13658
+ const trackData2 = currentFragment.trackData.get(this.internalTrack.id);
13659
+ if (trackData2) {
13660
+ const fragmentIndex2 = binarySearchExact(
13661
+ this.internalTrack.fragments,
13662
+ currentFragment.moofOffset,
13663
+ (x) => x.moofOffset
13664
+ );
13665
+ assert(fragmentIndex2 !== -1);
13666
+ return {
13667
+ fragmentIndex: fragmentIndex2,
13668
+ sampleIndex: 0,
13669
+ correctSampleFound: true
13670
+ };
13671
+ }
13672
+ }
13673
+ return {
13674
+ fragmentIndex,
13675
+ sampleIndex: -1,
13676
+ correctSampleFound: false
13677
+ };
13678
+ }
13679
+ },
13680
+ fragmentSample.presentationTimestamp,
13681
+ Infinity,
13682
+ options
13683
+ );
13686
13684
  }
13687
13685
  async getKeyPacket(timestamp, options) {
13688
13686
  const timestampInTimescale = this.mapTimestampIntoTimescale(timestamp);
13689
- if (this.internalTrack.demuxer.isFragmented) {
13690
- return this.performFragmentedLookup(
13691
- () => this.findKeySampleInFragmentsForTimestamp(timestampInTimescale),
13692
- timestampInTimescale,
13693
- timestampInTimescale,
13694
- options
13695
- );
13696
- }
13697
13687
  const sampleTable = this.internalTrack.demuxer.getSampleTableForTrack(this.internalTrack);
13698
13688
  const sampleIndex = getSampleIndexForTimestamp(sampleTable, timestampInTimescale);
13699
13689
  const keyFrameSampleIndex = sampleIndex === -1 ? -1 : getRelevantKeyframeIndexForSample(sampleTable, sampleIndex);
13700
- return this.fetchPacketForSampleIndex(keyFrameSampleIndex, options);
13690
+ const regularPacket = await this.fetchPacketForSampleIndex(keyFrameSampleIndex, options);
13691
+ if (!sampleTableIsEmpty(sampleTable) || !this.internalTrack.demuxer.isFragmented) {
13692
+ return regularPacket;
13693
+ }
13694
+ return this.performFragmentedLookup(
13695
+ () => this.findKeySampleInFragmentsForTimestamp(timestampInTimescale),
13696
+ timestampInTimescale,
13697
+ timestampInTimescale,
13698
+ options
13699
+ );
13701
13700
  }
13702
13701
  async getNextKeyPacket(packet, options) {
13703
- if (this.internalTrack.demuxer.isFragmented) {
13704
- const locationInFragment = this.packetToFragmentLocation.get(packet);
13705
- if (locationInFragment === void 0) {
13706
- throw new Error("Packet was not created from this track.");
13707
- }
13708
- const trackData = locationInFragment.fragment.trackData.get(this.internalTrack.id);
13709
- const fragmentSample = trackData.samples[locationInFragment.sampleIndex];
13710
- const fragmentIndex = binarySearchExact(
13711
- this.internalTrack.fragments,
13712
- locationInFragment.fragment.moofOffset,
13713
- (x) => x.moofOffset
13714
- );
13715
- assert(fragmentIndex !== -1);
13716
- return this.performFragmentedLookup(
13717
- () => {
13718
- const nextKeyFrameIndex = trackData.samples.findIndex(
13719
- (x, i) => x.isKeyFrame && i > locationInFragment.sampleIndex
13720
- );
13721
- if (nextKeyFrameIndex !== -1) {
13722
- return {
13723
- fragmentIndex,
13724
- sampleIndex: nextKeyFrameIndex,
13725
- correctSampleFound: true
13726
- };
13727
- } else {
13728
- let currentFragment = locationInFragment.fragment;
13729
- while (currentFragment.nextFragment) {
13730
- currentFragment = currentFragment.nextFragment;
13731
- const trackData2 = currentFragment.trackData.get(this.internalTrack.id);
13732
- if (trackData2 && trackData2.firstKeyFrameTimestamp !== null) {
13733
- const fragmentIndex2 = binarySearchExact(
13734
- this.internalTrack.fragments,
13735
- currentFragment.moofOffset,
13736
- (x) => x.moofOffset
13737
- );
13738
- assert(fragmentIndex2 !== -1);
13739
- const keyFrameIndex = trackData2.samples.findIndex((x) => x.isKeyFrame);
13740
- assert(keyFrameIndex !== -1);
13741
- return {
13742
- fragmentIndex: fragmentIndex2,
13743
- sampleIndex: keyFrameIndex,
13744
- correctSampleFound: true
13745
- };
13746
- }
13747
- }
13748
- return {
13749
- fragmentIndex,
13750
- sampleIndex: -1,
13751
- correctSampleFound: false
13752
- };
13753
- }
13754
- },
13755
- fragmentSample.presentationTimestamp,
13756
- Infinity,
13757
- options
13758
- );
13702
+ const regularSampleIndex = this.packetToSampleIndex.get(packet);
13703
+ if (regularSampleIndex !== void 0) {
13704
+ const sampleTable = this.internalTrack.demuxer.getSampleTableForTrack(this.internalTrack);
13705
+ const nextKeyFrameSampleIndex = getNextKeyframeIndexForSample(sampleTable, regularSampleIndex);
13706
+ return this.fetchPacketForSampleIndex(nextKeyFrameSampleIndex, options);
13759
13707
  }
13760
- const sampleIndex = this.packetToSampleIndex.get(packet);
13761
- if (sampleIndex === void 0) {
13708
+ const locationInFragment = this.packetToFragmentLocation.get(packet);
13709
+ if (locationInFragment === void 0) {
13762
13710
  throw new Error("Packet was not created from this track.");
13763
13711
  }
13764
- const sampleTable = this.internalTrack.demuxer.getSampleTableForTrack(this.internalTrack);
13765
- const nextKeyFrameSampleIndex = getNextKeyframeIndexForSample(sampleTable, sampleIndex);
13766
- return this.fetchPacketForSampleIndex(nextKeyFrameSampleIndex, options);
13712
+ const trackData = locationInFragment.fragment.trackData.get(this.internalTrack.id);
13713
+ const fragmentSample = trackData.samples[locationInFragment.sampleIndex];
13714
+ const fragmentIndex = binarySearchExact(
13715
+ this.internalTrack.fragments,
13716
+ locationInFragment.fragment.moofOffset,
13717
+ (x) => x.moofOffset
13718
+ );
13719
+ assert(fragmentIndex !== -1);
13720
+ return this.performFragmentedLookup(
13721
+ () => {
13722
+ const nextKeyFrameIndex = trackData.samples.findIndex(
13723
+ (x, i) => x.isKeyFrame && i > locationInFragment.sampleIndex
13724
+ );
13725
+ if (nextKeyFrameIndex !== -1) {
13726
+ return {
13727
+ fragmentIndex,
13728
+ sampleIndex: nextKeyFrameIndex,
13729
+ correctSampleFound: true
13730
+ };
13731
+ } else {
13732
+ let currentFragment = locationInFragment.fragment;
13733
+ while (currentFragment.nextFragment) {
13734
+ currentFragment = currentFragment.nextFragment;
13735
+ const trackData2 = currentFragment.trackData.get(this.internalTrack.id);
13736
+ if (trackData2 && trackData2.firstKeyFrameTimestamp !== null) {
13737
+ const fragmentIndex2 = binarySearchExact(
13738
+ this.internalTrack.fragments,
13739
+ currentFragment.moofOffset,
13740
+ (x) => x.moofOffset
13741
+ );
13742
+ assert(fragmentIndex2 !== -1);
13743
+ const keyFrameIndex = trackData2.samples.findIndex((x) => x.isKeyFrame);
13744
+ assert(keyFrameIndex !== -1);
13745
+ return {
13746
+ fragmentIndex: fragmentIndex2,
13747
+ sampleIndex: keyFrameIndex,
13748
+ correctSampleFound: true
13749
+ };
13750
+ }
13751
+ }
13752
+ return {
13753
+ fragmentIndex,
13754
+ sampleIndex: -1,
13755
+ correctSampleFound: false
13756
+ };
13757
+ }
13758
+ },
13759
+ fragmentSample.presentationTimestamp,
13760
+ Infinity,
13761
+ options
13762
+ );
13767
13763
  }
13768
13764
  async fetchPacketForSampleIndex(sampleIndex, options) {
13769
13765
  if (sampleIndex === -1) {
@@ -14159,6 +14155,9 @@ ${cue.notes ?? ""}`;
14159
14155
  const sinTheta = m21 / scaleX;
14160
14156
  return -Math.atan2(sinTheta, cosTheta) * (180 / Math.PI);
14161
14157
  };
14158
+ var sampleTableIsEmpty = (sampleTable) => {
14159
+ return sampleTable.sampleSizes.length === 0;
14160
+ };
14162
14161
 
14163
14162
  // src/matroska/matroska-demuxer.ts
14164
14163
  var METADATA_ELEMENTS = [