mediabunny 1.32.2 → 1.33.0

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.
Files changed (58) hide show
  1. package/dist/bundles/mediabunny.cjs +684 -23
  2. package/dist/bundles/mediabunny.min.cjs +8 -8
  3. package/dist/bundles/mediabunny.min.mjs +8 -8
  4. package/dist/bundles/mediabunny.mjs +684 -23
  5. package/dist/mediabunny.d.ts +27 -6
  6. package/dist/modules/src/adts/adts-muxer.d.ts.map +1 -1
  7. package/dist/modules/src/adts/adts-muxer.js +1 -4
  8. package/dist/modules/src/codec-data.d.ts +94 -0
  9. package/dist/modules/src/codec-data.d.ts.map +1 -1
  10. package/dist/modules/src/codec-data.js +266 -0
  11. package/dist/modules/src/codec.d.ts +3 -3
  12. package/dist/modules/src/codec.d.ts.map +1 -1
  13. package/dist/modules/src/codec.js +37 -3
  14. package/dist/modules/src/conversion.d.ts.map +1 -1
  15. package/dist/modules/src/conversion.js +7 -6
  16. package/dist/modules/src/encode.d.ts +2 -2
  17. package/dist/modules/src/encode.d.ts.map +1 -1
  18. package/dist/modules/src/encode.js +2 -0
  19. package/dist/modules/src/isobmff/isobmff-boxes.d.ts.map +1 -1
  20. package/dist/modules/src/isobmff/isobmff-boxes.js +66 -2
  21. package/dist/modules/src/isobmff/isobmff-demuxer.d.ts.map +1 -1
  22. package/dist/modules/src/isobmff/isobmff-demuxer.js +48 -1
  23. package/dist/modules/src/isobmff/isobmff-muxer.d.ts +1 -0
  24. package/dist/modules/src/isobmff/isobmff-muxer.d.ts.map +1 -1
  25. package/dist/modules/src/isobmff/isobmff-muxer.js +2 -1
  26. package/dist/modules/src/matroska/ebml.d.ts.map +1 -1
  27. package/dist/modules/src/matroska/ebml.js +2 -0
  28. package/dist/modules/src/matroska/matroska-demuxer.d.ts.map +1 -1
  29. package/dist/modules/src/matroska/matroska-demuxer.js +8 -0
  30. package/dist/modules/src/mpeg-ts/mpeg-ts-demuxer.d.ts.map +1 -1
  31. package/dist/modules/src/mpeg-ts/mpeg-ts-demuxer.js +156 -2
  32. package/dist/modules/src/mpeg-ts/mpeg-ts-misc.d.ts +3 -0
  33. package/dist/modules/src/mpeg-ts/mpeg-ts-misc.d.ts.map +1 -1
  34. package/dist/modules/src/mpeg-ts/mpeg-ts-muxer.d.ts.map +1 -1
  35. package/dist/modules/src/mpeg-ts/mpeg-ts-muxer.js +62 -8
  36. package/dist/modules/src/output-format.d.ts +15 -0
  37. package/dist/modules/src/output-format.d.ts.map +1 -1
  38. package/dist/modules/src/output-format.js +26 -2
  39. package/dist/modules/src/packet.d.ts +8 -2
  40. package/dist/modules/src/packet.d.ts.map +1 -1
  41. package/dist/modules/src/packet.js +4 -1
  42. package/dist/modules/src/tsconfig.tsbuildinfo +1 -1
  43. package/package.json +1 -1
  44. package/src/adts/adts-muxer.ts +1 -4
  45. package/src/codec-data.ts +364 -0
  46. package/src/codec.ts +31 -3
  47. package/src/conversion.ts +7 -6
  48. package/src/encode.ts +4 -2
  49. package/src/isobmff/isobmff-boxes.ts +79 -1
  50. package/src/isobmff/isobmff-demuxer.ts +54 -0
  51. package/src/isobmff/isobmff-muxer.ts +3 -1
  52. package/src/matroska/ebml.ts +2 -0
  53. package/src/matroska/matroska-demuxer.ts +6 -0
  54. package/src/mpeg-ts/mpeg-ts-demuxer.ts +186 -1
  55. package/src/mpeg-ts/mpeg-ts-misc.ts +3 -0
  56. package/src/mpeg-ts/mpeg-ts-muxer.ts +56 -7
  57. package/src/output-format.ts +43 -2
  58. package/src/packet.ts +4 -1
@@ -937,7 +937,9 @@ var Mediabunny = (() => {
937
937
  "opus",
938
938
  "mp3",
939
939
  "vorbis",
940
- "flac"
940
+ "flac",
941
+ "ac3",
942
+ "eac3"
941
943
  ];
942
944
  var AUDIO_CODECS = [
943
945
  ...NON_PCM_AUDIO_CODECS,
@@ -1340,6 +1342,10 @@ var Mediabunny = (() => {
1340
1342
  return "vorbis";
1341
1343
  } else if (codec === "flac") {
1342
1344
  return "flac";
1345
+ } else if (codec === "ac3") {
1346
+ return "ac-3";
1347
+ } else if (codec === "eac3") {
1348
+ return "ec-3";
1343
1349
  } else if (PCM_AUDIO_CODECS.includes(codec)) {
1344
1350
  return codec;
1345
1351
  }
@@ -1371,6 +1377,10 @@ var Mediabunny = (() => {
1371
1377
  return "vorbis";
1372
1378
  } else if (codec === "flac") {
1373
1379
  return "flac";
1380
+ } else if (codec === "ac3") {
1381
+ return "ac-3";
1382
+ } else if (codec === "eac3") {
1383
+ return "ec-3";
1374
1384
  } else if (codec && PCM_AUDIO_CODECS.includes(codec)) {
1375
1385
  return codec;
1376
1386
  }
@@ -1503,6 +1513,10 @@ var Mediabunny = (() => {
1503
1513
  return "vorbis";
1504
1514
  } else if (codecString === "flac") {
1505
1515
  return "flac";
1516
+ } else if (codecString === "ac-3" || codecString === "ac3") {
1517
+ return "ac3";
1518
+ } else if (codecString === "ec-3" || codecString === "eac3") {
1519
+ return "eac3";
1506
1520
  } else if (codecString === "ulaw") {
1507
1521
  return "ulaw";
1508
1522
  } else if (codecString === "alaw") {
@@ -1573,7 +1587,7 @@ var Mediabunny = (() => {
1573
1587
  }
1574
1588
  if (!VALID_VIDEO_CODEC_STRING_PREFIXES.some((prefix) => metadata.decoderConfig.codec.startsWith(prefix))) {
1575
1589
  throw new TypeError(
1576
- "Video chunk metadata decoder configuration codec string must be a valid video codec string as specified in the WebCodecs Codec Registry."
1590
+ "Video chunk metadata decoder configuration codec string must be a valid video codec string as specified in the Mediabunny Codec Registry."
1577
1591
  );
1578
1592
  }
1579
1593
  if (!Number.isInteger(metadata.decoderConfig.codedWidth) || metadata.decoderConfig.codedWidth <= 0) {
@@ -1654,7 +1668,18 @@ var Mediabunny = (() => {
1654
1668
  }
1655
1669
  }
1656
1670
  };
1657
- var VALID_AUDIO_CODEC_STRING_PREFIXES = ["mp4a", "mp3", "opus", "vorbis", "flac", "ulaw", "alaw", "pcm"];
1671
+ var VALID_AUDIO_CODEC_STRING_PREFIXES = [
1672
+ "mp4a",
1673
+ "mp3",
1674
+ "opus",
1675
+ "vorbis",
1676
+ "flac",
1677
+ "ulaw",
1678
+ "alaw",
1679
+ "pcm",
1680
+ "ac-3",
1681
+ "ec-3"
1682
+ ];
1658
1683
  var validateAudioChunkMetadata = (metadata) => {
1659
1684
  if (!metadata) {
1660
1685
  throw new TypeError("Audio chunk metadata must be provided.");
@@ -1673,7 +1698,7 @@ var Mediabunny = (() => {
1673
1698
  }
1674
1699
  if (!VALID_AUDIO_CODEC_STRING_PREFIXES.some((prefix) => metadata.decoderConfig.codec.startsWith(prefix))) {
1675
1700
  throw new TypeError(
1676
- "Audio chunk metadata decoder configuration codec string must be a valid audio codec string as specified in the WebCodecs Codec Registry."
1701
+ "Audio chunk metadata decoder configuration codec string must be a valid audio codec string as specified in the Mediabunny Codec Registry."
1677
1702
  );
1678
1703
  }
1679
1704
  if (!Number.isInteger(metadata.decoderConfig.sampleRate) || metadata.decoderConfig.sampleRate <= 0) {
@@ -1734,6 +1759,14 @@ var Mediabunny = (() => {
1734
1759
  "Audio chunk metadata decoder configuration for FLAC must include a description, which is expected to adhere to the format described in https://www.w3.org/TR/webcodecs-flac-codec-registration/."
1735
1760
  );
1736
1761
  }
1762
+ } else if (metadata.decoderConfig.codec.startsWith("ac-3") || metadata.decoderConfig.codec.startsWith("ac3")) {
1763
+ if (metadata.decoderConfig.codec !== "ac-3") {
1764
+ throw new TypeError('Audio chunk metadata decoder configuration codec string for AC-3 must be "ac-3".');
1765
+ }
1766
+ } else if (metadata.decoderConfig.codec.startsWith("ec-3") || metadata.decoderConfig.codec.startsWith("eac3")) {
1767
+ if (metadata.decoderConfig.codec !== "ec-3") {
1768
+ throw new TypeError('Audio chunk metadata decoder configuration codec string for EC-3 must be "ec-3".');
1769
+ }
1737
1770
  } else if (metadata.decoderConfig.codec.startsWith("pcm") || metadata.decoderConfig.codec.startsWith("ulaw") || metadata.decoderConfig.codec.startsWith("alaw")) {
1738
1771
  if (!PCM_AUDIO_CODECS.includes(metadata.decoderConfig.codec)) {
1739
1772
  throw new TypeError(
@@ -3973,6 +4006,287 @@ var Mediabunny = (() => {
3973
4006
  }
3974
4007
  return commentHeader;
3975
4008
  };
4009
+ var AC3_SAMPLE_RATES = [48e3, 44100, 32e3];
4010
+ var AC3_ACMOD_CHANNEL_COUNTS = [2, 1, 2, 3, 3, 4, 4, 5];
4011
+ var parseAc3SyncFrame = (data) => {
4012
+ if (data.length < 7) {
4013
+ return null;
4014
+ }
4015
+ if (data[0] !== 11 || data[1] !== 119) {
4016
+ return null;
4017
+ }
4018
+ const bitstream = new Bitstream(data);
4019
+ bitstream.skipBits(16);
4020
+ bitstream.skipBits(16);
4021
+ const fscod = bitstream.readBits(2);
4022
+ if (fscod === 3) {
4023
+ return null;
4024
+ }
4025
+ const frmsizecod = bitstream.readBits(6);
4026
+ const bsid = bitstream.readBits(5);
4027
+ if (bsid > 8) {
4028
+ return null;
4029
+ }
4030
+ const bsmod = bitstream.readBits(3);
4031
+ const acmod = bitstream.readBits(3);
4032
+ if ((acmod & 1) !== 0 && acmod !== 1) {
4033
+ bitstream.skipBits(2);
4034
+ }
4035
+ if ((acmod & 4) !== 0) {
4036
+ bitstream.skipBits(2);
4037
+ }
4038
+ if (acmod === 2) {
4039
+ bitstream.skipBits(2);
4040
+ }
4041
+ const lfeon = bitstream.readBits(1);
4042
+ const bitRateCode = Math.floor(frmsizecod / 2);
4043
+ return { fscod, bsid, bsmod, acmod, lfeon, bitRateCode };
4044
+ };
4045
+ var AC3_FRAME_SIZES = [
4046
+ // frmsizecod, [48kHz, 44.1kHz, 32kHz] in bytes
4047
+ 64 * 2,
4048
+ 69 * 2,
4049
+ 96 * 2,
4050
+ 64 * 2,
4051
+ 70 * 2,
4052
+ 96 * 2,
4053
+ 80 * 2,
4054
+ 87 * 2,
4055
+ 120 * 2,
4056
+ 80 * 2,
4057
+ 88 * 2,
4058
+ 120 * 2,
4059
+ 96 * 2,
4060
+ 104 * 2,
4061
+ 144 * 2,
4062
+ 96 * 2,
4063
+ 105 * 2,
4064
+ 144 * 2,
4065
+ 112 * 2,
4066
+ 121 * 2,
4067
+ 168 * 2,
4068
+ 112 * 2,
4069
+ 122 * 2,
4070
+ 168 * 2,
4071
+ 128 * 2,
4072
+ 139 * 2,
4073
+ 192 * 2,
4074
+ 128 * 2,
4075
+ 140 * 2,
4076
+ 192 * 2,
4077
+ 160 * 2,
4078
+ 174 * 2,
4079
+ 240 * 2,
4080
+ 160 * 2,
4081
+ 175 * 2,
4082
+ 240 * 2,
4083
+ 192 * 2,
4084
+ 208 * 2,
4085
+ 288 * 2,
4086
+ 192 * 2,
4087
+ 209 * 2,
4088
+ 288 * 2,
4089
+ 224 * 2,
4090
+ 243 * 2,
4091
+ 336 * 2,
4092
+ 224 * 2,
4093
+ 244 * 2,
4094
+ 336 * 2,
4095
+ 256 * 2,
4096
+ 278 * 2,
4097
+ 384 * 2,
4098
+ 256 * 2,
4099
+ 279 * 2,
4100
+ 384 * 2,
4101
+ 320 * 2,
4102
+ 348 * 2,
4103
+ 480 * 2,
4104
+ 320 * 2,
4105
+ 349 * 2,
4106
+ 480 * 2,
4107
+ 384 * 2,
4108
+ 417 * 2,
4109
+ 576 * 2,
4110
+ 384 * 2,
4111
+ 418 * 2,
4112
+ 576 * 2,
4113
+ 448 * 2,
4114
+ 487 * 2,
4115
+ 672 * 2,
4116
+ 448 * 2,
4117
+ 488 * 2,
4118
+ 672 * 2,
4119
+ 512 * 2,
4120
+ 557 * 2,
4121
+ 768 * 2,
4122
+ 512 * 2,
4123
+ 558 * 2,
4124
+ 768 * 2,
4125
+ 640 * 2,
4126
+ 696 * 2,
4127
+ 960 * 2,
4128
+ 640 * 2,
4129
+ 697 * 2,
4130
+ 960 * 2,
4131
+ 768 * 2,
4132
+ 835 * 2,
4133
+ 1152 * 2,
4134
+ 768 * 2,
4135
+ 836 * 2,
4136
+ 1152 * 2,
4137
+ 896 * 2,
4138
+ 975 * 2,
4139
+ 1344 * 2,
4140
+ 896 * 2,
4141
+ 976 * 2,
4142
+ 1344 * 2,
4143
+ 1024 * 2,
4144
+ 1114 * 2,
4145
+ 1536 * 2,
4146
+ 1024 * 2,
4147
+ 1115 * 2,
4148
+ 1536 * 2,
4149
+ 1152 * 2,
4150
+ 1253 * 2,
4151
+ 1728 * 2,
4152
+ 1152 * 2,
4153
+ 1254 * 2,
4154
+ 1728 * 2,
4155
+ 1280 * 2,
4156
+ 1393 * 2,
4157
+ 1920 * 2,
4158
+ 1280 * 2,
4159
+ 1394 * 2,
4160
+ 1920 * 2
4161
+ ];
4162
+ var AC3_SAMPLES_PER_FRAME = 1536;
4163
+ var AC3_REGISTRATION_DESCRIPTOR = new Uint8Array([5, 4, 65, 67, 45, 51]);
4164
+ var EAC3_REGISTRATION_DESCRIPTOR = new Uint8Array([5, 4, 69, 65, 67, 51]);
4165
+ var EAC3_REDUCED_SAMPLE_RATES = [24e3, 22050, 16e3];
4166
+ var EAC3_NUMBLKS_TABLE = [1, 2, 3, 6];
4167
+ var parseEac3SyncFrame = (data) => {
4168
+ if (data.length < 6) {
4169
+ return null;
4170
+ }
4171
+ if (data[0] !== 11 || data[1] !== 119) {
4172
+ return null;
4173
+ }
4174
+ const bitstream = new Bitstream(data);
4175
+ bitstream.skipBits(16);
4176
+ const strmtyp = bitstream.readBits(2);
4177
+ bitstream.skipBits(3);
4178
+ if (strmtyp !== 0 && strmtyp !== 2) {
4179
+ return null;
4180
+ }
4181
+ const frmsiz = bitstream.readBits(11);
4182
+ const fscod = bitstream.readBits(2);
4183
+ let fscod2 = 0;
4184
+ let numblkscod;
4185
+ if (fscod === 3) {
4186
+ fscod2 = bitstream.readBits(2);
4187
+ numblkscod = 3;
4188
+ } else {
4189
+ numblkscod = bitstream.readBits(2);
4190
+ }
4191
+ const acmod = bitstream.readBits(3);
4192
+ const lfeon = bitstream.readBits(1);
4193
+ const bsid = bitstream.readBits(5);
4194
+ if (bsid < 11 || bsid > 16) {
4195
+ return null;
4196
+ }
4197
+ const numblks = EAC3_NUMBLKS_TABLE[numblkscod];
4198
+ let fs;
4199
+ if (fscod < 3) {
4200
+ fs = AC3_SAMPLE_RATES[fscod] / 1e3;
4201
+ } else {
4202
+ fs = EAC3_REDUCED_SAMPLE_RATES[fscod2] / 1e3;
4203
+ }
4204
+ const dataRate = Math.round((frmsiz + 1) * fs / (numblks * 16));
4205
+ const bsmod = 0;
4206
+ const numDepSub = 0;
4207
+ const chanLoc = 0;
4208
+ const substream = {
4209
+ fscod,
4210
+ fscod2,
4211
+ bsid,
4212
+ bsmod,
4213
+ acmod,
4214
+ lfeon,
4215
+ numDepSub,
4216
+ chanLoc
4217
+ };
4218
+ return {
4219
+ dataRate,
4220
+ substreams: [substream]
4221
+ };
4222
+ };
4223
+ var parseEac3Config = (data) => {
4224
+ if (data.length < 2) {
4225
+ return null;
4226
+ }
4227
+ const bitstream = new Bitstream(data);
4228
+ const dataRate = bitstream.readBits(13);
4229
+ const numIndSub = bitstream.readBits(3);
4230
+ const substreams = [];
4231
+ for (let i = 0; i <= numIndSub; i++) {
4232
+ if (Math.ceil(bitstream.pos / 8) + 3 > data.length) {
4233
+ break;
4234
+ }
4235
+ const fscod = bitstream.readBits(2);
4236
+ const bsid = bitstream.readBits(5);
4237
+ bitstream.skipBits(1);
4238
+ bitstream.skipBits(1);
4239
+ const bsmod = bitstream.readBits(3);
4240
+ const acmod = bitstream.readBits(3);
4241
+ const lfeon = bitstream.readBits(1);
4242
+ bitstream.skipBits(3);
4243
+ const numDepSub = bitstream.readBits(4);
4244
+ let chanLoc = 0;
4245
+ if (numDepSub > 0) {
4246
+ chanLoc = bitstream.readBits(9);
4247
+ } else {
4248
+ bitstream.skipBits(1);
4249
+ }
4250
+ substreams.push({
4251
+ fscod,
4252
+ fscod2: null,
4253
+ bsid,
4254
+ bsmod,
4255
+ acmod,
4256
+ lfeon,
4257
+ numDepSub,
4258
+ chanLoc
4259
+ });
4260
+ }
4261
+ if (substreams.length === 0) {
4262
+ return null;
4263
+ }
4264
+ return { dataRate, substreams };
4265
+ };
4266
+ var getEac3SampleRate = (config) => {
4267
+ const sub = config.substreams[0];
4268
+ assert(sub);
4269
+ if (sub.fscod < 3) {
4270
+ return AC3_SAMPLE_RATES[sub.fscod];
4271
+ } else if (sub.fscod2 !== null && sub.fscod2 < 3) {
4272
+ return EAC3_REDUCED_SAMPLE_RATES[sub.fscod2];
4273
+ }
4274
+ return null;
4275
+ };
4276
+ var getEac3ChannelCount = (config) => {
4277
+ const sub = config.substreams[0];
4278
+ assert(sub);
4279
+ let channels = AC3_ACMOD_CHANNEL_COUNTS[sub.acmod] + sub.lfeon;
4280
+ if (sub.numDepSub > 0) {
4281
+ const CHAN_LOC_COUNTS = [2, 2, 1, 1, 2, 2, 2, 1, 1];
4282
+ for (let bit = 0; bit < 9; bit++) {
4283
+ if (sub.chanLoc & 1 << 8 - bit) {
4284
+ channels += CHAN_LOC_COUNTS[bit];
4285
+ }
4286
+ }
4287
+ }
4288
+ return channels;
4289
+ };
3976
4290
 
3977
4291
  // src/demuxer.ts
3978
4292
  var Demuxer = class {
@@ -8087,6 +8401,10 @@ var Mediabunny = (() => {
8087
8401
  track.info.codec = "ulaw";
8088
8402
  } else if (lowercaseBoxName === "alaw") {
8089
8403
  track.info.codec = "alaw";
8404
+ } else if (lowercaseBoxName === "ac-3") {
8405
+ track.info.codec = "ac3";
8406
+ } else if (lowercaseBoxName === "ec-3") {
8407
+ track.info.codec = "eac3";
8090
8408
  } else {
8091
8409
  console.warn(`Unsupported audio codec (sample entry type '${sampleBoxInfo.name}').`);
8092
8410
  }
@@ -8532,6 +8850,47 @@ var Mediabunny = (() => {
8532
8850
  }
8533
8851
  ;
8534
8852
  break;
8853
+ case "dac3":
8854
+ {
8855
+ const track = this.currentTrack;
8856
+ if (!track) {
8857
+ break;
8858
+ }
8859
+ assert(track.info?.type === "audio");
8860
+ const bytes2 = readBytes(slice, 3);
8861
+ const bitstream = new Bitstream(bytes2);
8862
+ const fscod = bitstream.readBits(2);
8863
+ bitstream.skipBits(5 + 3);
8864
+ const acmod = bitstream.readBits(3);
8865
+ const lfeon = bitstream.readBits(1);
8866
+ if (fscod < 3) {
8867
+ track.info.sampleRate = AC3_SAMPLE_RATES[fscod];
8868
+ }
8869
+ track.info.numberOfChannels = AC3_ACMOD_CHANNEL_COUNTS[acmod] + lfeon;
8870
+ }
8871
+ ;
8872
+ break;
8873
+ case "dec3":
8874
+ {
8875
+ const track = this.currentTrack;
8876
+ if (!track) {
8877
+ break;
8878
+ }
8879
+ assert(track.info?.type === "audio");
8880
+ const bytes2 = readBytes(slice, boxInfo.contentSize);
8881
+ const config = parseEac3Config(bytes2);
8882
+ if (!config) {
8883
+ console.warn("Invalid dec3 box contents, ignoring.");
8884
+ break;
8885
+ }
8886
+ const sampleRate = getEac3SampleRate(config);
8887
+ if (sampleRate !== null) {
8888
+ track.info.sampleRate = sampleRate;
8889
+ }
8890
+ track.info.numberOfChannels = getEac3ChannelCount(config);
8891
+ }
8892
+ ;
8893
+ break;
8535
8894
  case "stts":
8536
8895
  {
8537
8896
  const track = this.currentTrack;
@@ -10399,6 +10758,8 @@ var Mediabunny = (() => {
10399
10758
  "opus": "A_OPUS",
10400
10759
  "vorbis": "A_VORBIS",
10401
10760
  "flac": "A_FLAC",
10761
+ "ac3": "A_AC3",
10762
+ "eac3": "A_EAC3",
10402
10763
  "pcm-u8": "A_PCM/INT/LIT",
10403
10764
  "pcm-s16": "A_PCM/INT/LIT",
10404
10765
  "pcm-s16be": "A_PCM/INT/BIG",
@@ -11064,6 +11425,12 @@ var Mediabunny = (() => {
11064
11425
  } else if (codecIdWithoutSuffix === CODEC_STRING_MAP.flac) {
11065
11426
  this.currentTrack.info.codec = "flac";
11066
11427
  this.currentTrack.info.codecDescription = this.currentTrack.codecPrivate;
11428
+ } else if (codecIdWithoutSuffix === CODEC_STRING_MAP.ac3) {
11429
+ this.currentTrack.info.codec = "ac3";
11430
+ this.currentTrack.info.codecDescription = this.currentTrack.codecPrivate;
11431
+ } else if (codecIdWithoutSuffix === CODEC_STRING_MAP.eac3) {
11432
+ this.currentTrack.info.codec = "eac3";
11433
+ this.currentTrack.info.codecDescription = this.currentTrack.codecPrivate;
11067
11434
  } else if (this.currentTrack.codecId === "A_PCM/INT/LIT") {
11068
11435
  if (this.currentTrack.info.bitDepth === 8) {
11069
11436
  this.currentTrack.info.codec = "pcm-u8";
@@ -14910,7 +15277,19 @@ var Mediabunny = (() => {
14910
15277
  const elementaryPid = bitstream.readBits(13);
14911
15278
  bitstream.skipBits(6);
14912
15279
  const esInfoLength = bitstream.readBits(10);
14913
- bitstream.skipBits(8 * esInfoLength);
15280
+ const esInfoEndPos = bitstream.pos + 8 * esInfoLength;
15281
+ let hasAc3Descriptor = false;
15282
+ let hasEac3Descriptor = false;
15283
+ while (bitstream.pos < esInfoEndPos) {
15284
+ const descriptorTag = bitstream.readBits(8);
15285
+ const descriptorLength = bitstream.readBits(8);
15286
+ if (descriptorTag === 106) {
15287
+ hasAc3Descriptor = true;
15288
+ } else if (descriptorTag === 122 || descriptorTag === 204) {
15289
+ hasEac3Descriptor = true;
15290
+ }
15291
+ bitstream.skipBits(8 * descriptorLength);
15292
+ }
14914
15293
  let info = null;
14915
15294
  switch (streamType) {
14916
15295
  case 3 /* MP3_MPEG1 */:
@@ -14950,6 +15329,52 @@ var Mediabunny = (() => {
14950
15329
  }
14951
15330
  ;
14952
15331
  break;
15332
+ case 129 /* AC3_SYSTEM_A */:
15333
+ {
15334
+ info = {
15335
+ type: "audio",
15336
+ codec: "ac3",
15337
+ aacCodecInfo: null,
15338
+ numberOfChannels: -1,
15339
+ sampleRate: -1
15340
+ };
15341
+ }
15342
+ ;
15343
+ break;
15344
+ case 135 /* EAC3_SYSTEM_A */:
15345
+ {
15346
+ info = {
15347
+ type: "audio",
15348
+ codec: "eac3",
15349
+ aacCodecInfo: null,
15350
+ numberOfChannels: -1,
15351
+ sampleRate: -1
15352
+ };
15353
+ }
15354
+ ;
15355
+ break;
15356
+ case 6 /* PRIVATE_DATA */:
15357
+ {
15358
+ if (hasEac3Descriptor) {
15359
+ info = {
15360
+ type: "audio",
15361
+ codec: "eac3",
15362
+ aacCodecInfo: null,
15363
+ numberOfChannels: -1,
15364
+ sampleRate: -1
15365
+ };
15366
+ } else if (hasAc3Descriptor) {
15367
+ info = {
15368
+ type: "audio",
15369
+ codec: "ac3",
15370
+ aacCodecInfo: null,
15371
+ numberOfChannels: -1,
15372
+ sampleRate: -1
15373
+ };
15374
+ }
15375
+ }
15376
+ ;
15377
+ break;
14953
15378
  default: {
14954
15379
  console.warn(`Unsupported stream_type 0x${streamType.toString(16)}; ignoring stream.`);
14955
15380
  }
@@ -15051,6 +15476,37 @@ var Mediabunny = (() => {
15051
15476
  elementaryStream.info.numberOfChannels = result.header.channel === 3 ? 1 : 2;
15052
15477
  elementaryStream.info.sampleRate = result.header.sampleRate;
15053
15478
  elementaryStream.initialized = true;
15479
+ } else if (elementaryStream.info.codec === "ac3") {
15480
+ const frameInfo = parseAc3SyncFrame(pesPacket.data);
15481
+ if (!frameInfo) {
15482
+ throw new Error(
15483
+ "Invalid AC-3 audio stream; could not read sync frame from first packet."
15484
+ );
15485
+ }
15486
+ if (frameInfo.fscod === 3) {
15487
+ throw new Error(
15488
+ "Invalid AC-3 audio stream; reserved sample rate code found in first packet."
15489
+ );
15490
+ }
15491
+ elementaryStream.info.numberOfChannels = AC3_ACMOD_CHANNEL_COUNTS[frameInfo.acmod] + frameInfo.lfeon;
15492
+ elementaryStream.info.sampleRate = AC3_SAMPLE_RATES[frameInfo.fscod];
15493
+ elementaryStream.initialized = true;
15494
+ } else if (elementaryStream.info.codec === "eac3") {
15495
+ const frameInfo = parseEac3SyncFrame(pesPacket.data);
15496
+ if (!frameInfo) {
15497
+ throw new Error(
15498
+ "Invalid E-AC-3 audio stream; could not read sync frame from first packet."
15499
+ );
15500
+ }
15501
+ const sampleRate = getEac3SampleRate(frameInfo);
15502
+ if (sampleRate === null) {
15503
+ throw new Error(
15504
+ "Invalid E-AC-3 audio stream; reserved sample rate code found in first packet."
15505
+ );
15506
+ }
15507
+ elementaryStream.info.numberOfChannels = getEac3ChannelCount(frameInfo);
15508
+ elementaryStream.info.sampleRate = sampleRate;
15509
+ elementaryStream.initialized = true;
15054
15510
  } else {
15055
15511
  throw new Error("Unhandled.");
15056
15512
  }
@@ -15955,6 +16411,66 @@ var Mediabunny = (() => {
15955
16411
  } else {
15956
16412
  context.seekTo(possibleHeaderStartPos + 1);
15957
16413
  }
16414
+ } else if (codec === "ac3") {
16415
+ if (byte !== 11) {
16416
+ continue;
16417
+ }
16418
+ context.skip(-1);
16419
+ const possibleSyncPos = context.currentPos;
16420
+ let remaining2 = context.ensureBuffered(5);
16421
+ if (remaining2 instanceof Promise) remaining2 = await remaining2;
16422
+ if (remaining2 < 5) {
16423
+ return;
16424
+ }
16425
+ const headerBytes = context.readBytes(5);
16426
+ if (headerBytes[0] !== 11 || headerBytes[1] !== 119) {
16427
+ context.seekTo(possibleSyncPos + 1);
16428
+ continue;
16429
+ }
16430
+ const fscod = headerBytes[4] >> 6;
16431
+ const frmsizecod = headerBytes[4] & 63;
16432
+ if (fscod === 3 || frmsizecod > 37) {
16433
+ context.seekTo(possibleSyncPos + 1);
16434
+ continue;
16435
+ }
16436
+ const frameSize = AC3_FRAME_SIZES[3 * frmsizecod + fscod];
16437
+ assert(frameSize !== void 0);
16438
+ context.seekTo(possibleSyncPos);
16439
+ remaining2 = context.ensureBuffered(frameSize);
16440
+ if (remaining2 instanceof Promise) remaining2 = await remaining2;
16441
+ const duration = Math.round(
16442
+ AC3_SAMPLES_PER_FRAME * TIMESCALE / elementaryStream.info.sampleRate
16443
+ );
16444
+ return context.supplyPacket(remaining2, duration);
16445
+ } else if (codec === "eac3") {
16446
+ if (byte !== 11) {
16447
+ continue;
16448
+ }
16449
+ context.skip(-1);
16450
+ const possibleSyncPos = context.currentPos;
16451
+ let remaining2 = context.ensureBuffered(5);
16452
+ if (remaining2 instanceof Promise) remaining2 = await remaining2;
16453
+ if (remaining2 < 5) {
16454
+ return;
16455
+ }
16456
+ const headerBytes = context.readBytes(5);
16457
+ if (headerBytes[0] !== 11 || headerBytes[1] !== 119) {
16458
+ context.seekTo(possibleSyncPos + 1);
16459
+ continue;
16460
+ }
16461
+ const frmsiz = (headerBytes[2] & 7) << 8 | headerBytes[3];
16462
+ const frameSize = (frmsiz + 1) * 2;
16463
+ const fscod = headerBytes[4] >> 6;
16464
+ const numblkscod = fscod === 3 ? 3 : headerBytes[4] >> 4 & 3;
16465
+ const numblks = EAC3_NUMBLKS_TABLE[numblkscod];
16466
+ context.seekTo(possibleSyncPos);
16467
+ remaining2 = context.ensureBuffered(frameSize);
16468
+ if (remaining2 instanceof Promise) remaining2 = await remaining2;
16469
+ const samplesPerFrame = numblks * 256;
16470
+ const duration = Math.round(
16471
+ samplesPerFrame * TIMESCALE / elementaryStream.info.sampleRate
16472
+ );
16473
+ return context.supplyPacket(remaining2, duration);
15958
16474
  } else {
15959
16475
  throw new Error("Unhandled.");
15960
16476
  }
@@ -20150,6 +20666,63 @@ var Mediabunny = (() => {
20150
20666
  u8(8 * sampleSize)
20151
20667
  ]);
20152
20668
  };
20669
+ var dac3 = (trackData) => {
20670
+ const frameInfo = parseAc3SyncFrame(trackData.info.firstPacket.data);
20671
+ if (!frameInfo) {
20672
+ throw new Error(
20673
+ "Couldn't extract AC-3 frame info from the audio packet. Ensure the packets contain valid AC-3 sync frames (as specified in ETSI TS 102 366)."
20674
+ );
20675
+ }
20676
+ const bytes2 = new Uint8Array(3);
20677
+ const bitstream = new Bitstream(bytes2);
20678
+ bitstream.writeBits(2, frameInfo.fscod);
20679
+ bitstream.writeBits(5, frameInfo.bsid);
20680
+ bitstream.writeBits(3, frameInfo.bsmod);
20681
+ bitstream.writeBits(3, frameInfo.acmod);
20682
+ bitstream.writeBits(1, frameInfo.lfeon);
20683
+ bitstream.writeBits(5, frameInfo.bitRateCode);
20684
+ bitstream.writeBits(5, 0);
20685
+ return box("dac3", [...bytes2]);
20686
+ };
20687
+ var dec3 = (trackData) => {
20688
+ const frameInfo = parseEac3SyncFrame(trackData.info.firstPacket.data);
20689
+ if (!frameInfo) {
20690
+ throw new Error(
20691
+ "Couldn't extract E-AC-3 frame info from the audio packet. Ensure the packets contain valid E-AC-3 sync frames (as specified in ETSI TS 102 366)."
20692
+ );
20693
+ }
20694
+ let totalBits = 16;
20695
+ for (const sub of frameInfo.substreams) {
20696
+ totalBits += 23;
20697
+ if (sub.numDepSub > 0) {
20698
+ totalBits += 9;
20699
+ } else {
20700
+ totalBits += 1;
20701
+ }
20702
+ }
20703
+ const size = Math.ceil(totalBits / 8);
20704
+ const bytes2 = new Uint8Array(size);
20705
+ const bitstream = new Bitstream(bytes2);
20706
+ bitstream.writeBits(13, frameInfo.dataRate);
20707
+ bitstream.writeBits(3, frameInfo.substreams.length - 1);
20708
+ for (const sub of frameInfo.substreams) {
20709
+ bitstream.writeBits(2, sub.fscod);
20710
+ bitstream.writeBits(5, sub.bsid);
20711
+ bitstream.writeBits(1, 0);
20712
+ bitstream.writeBits(1, 0);
20713
+ bitstream.writeBits(3, sub.bsmod);
20714
+ bitstream.writeBits(3, sub.acmod);
20715
+ bitstream.writeBits(1, sub.lfeon);
20716
+ bitstream.writeBits(3, 0);
20717
+ bitstream.writeBits(4, sub.numDepSub);
20718
+ if (sub.numDepSub > 0) {
20719
+ bitstream.writeBits(9, sub.chanLoc);
20720
+ } else {
20721
+ bitstream.writeBits(1, 0);
20722
+ }
20723
+ }
20724
+ return box("dec3", [...bytes2]);
20725
+ };
20153
20726
  var subtitleSampleDescription = (compressionType, trackData) => box(compressionType, [
20154
20727
  Array(6).fill(0),
20155
20728
  // Reserved
@@ -20818,6 +21391,10 @@ var Mediabunny = (() => {
20818
21391
  return "raw ";
20819
21392
  case "pcm-s8":
20820
21393
  return "sowt";
21394
+ case "ac3":
21395
+ return "ac-3";
21396
+ case "eac3":
21397
+ return "ec-3";
20821
21398
  }
20822
21399
  if (isQuickTime) {
20823
21400
  switch (codec) {
@@ -20879,6 +21456,10 @@ var Mediabunny = (() => {
20879
21456
  return esds;
20880
21457
  case "flac":
20881
21458
  return dfLa;
21459
+ case "ac3":
21460
+ return dac3;
21461
+ case "eac3":
21462
+ return dec3;
20882
21463
  }
20883
21464
  if (isQuickTime) {
20884
21465
  switch (codec) {
@@ -21576,9 +22157,10 @@ var Mediabunny = (() => {
21576
22157
  sampleRate: meta.decoderConfig.sampleRate,
21577
22158
  decoderConfig,
21578
22159
  requiresPcmTransformation: !this.isFragmented && PCM_AUDIO_CODECS.includes(track.source._codec),
21579
- requiresAdtsStripping
22160
+ requiresAdtsStripping,
22161
+ firstPacket: packet
21580
22162
  },
21581
- timescale: meta.decoderConfig.sampleRate,
22163
+ timescale: decoderConfig.sampleRate,
21582
22164
  samples: [],
21583
22165
  sampleQueue: [],
21584
22166
  timestampProcessingQueue: [],
@@ -23806,10 +24388,40 @@ ${cue.notes ?? ""}`;
23806
24388
  validateAudioChunkMetadata(meta);
23807
24389
  assert(meta?.decoderConfig);
23808
24390
  const codec = track.source._codec;
23809
- assert(codec === "aac" || codec === "mp3");
23810
- const streamType = codec === "aac" ? 15 /* AAC */ : 3 /* MP3_MPEG1 */;
24391
+ assert(codec === "aac" || codec === "mp3" || codec === "ac3" || codec === "eac3");
24392
+ let streamType;
24393
+ let streamId;
24394
+ switch (codec) {
24395
+ case "aac":
24396
+ {
24397
+ streamType = 15 /* AAC */;
24398
+ streamId = AUDIO_STREAM_ID_BASE + this.audioTrackIndex++;
24399
+ }
24400
+ ;
24401
+ break;
24402
+ case "mp3":
24403
+ {
24404
+ streamType = 3 /* MP3_MPEG1 */;
24405
+ streamId = AUDIO_STREAM_ID_BASE + this.audioTrackIndex++;
24406
+ }
24407
+ ;
24408
+ break;
24409
+ case "ac3":
24410
+ {
24411
+ streamType = 129 /* AC3_SYSTEM_A */;
24412
+ streamId = 189;
24413
+ }
24414
+ ;
24415
+ break;
24416
+ case "eac3":
24417
+ {
24418
+ streamType = 135 /* EAC3_SYSTEM_A */;
24419
+ streamId = 189;
24420
+ }
24421
+ ;
24422
+ break;
24423
+ }
23811
24424
  const pid = FIRST_TRACK_PID + this.trackDatas.length;
23812
- const streamId = AUDIO_STREAM_ID_BASE + this.audioTrackIndex++;
23813
24425
  const newTrackData = {
23814
24426
  track,
23815
24427
  pid,
@@ -23958,7 +24570,7 @@ ${cue.notes ?? ""}`;
23958
24570
  }
23959
24571
  prepareAudioPacket(trackData, packet, meta) {
23960
24572
  const codec = trackData.track.source._codec;
23961
- if (codec === "mp3") {
24573
+ if (codec === "mp3" || codec === "ac3" || codec === "eac3") {
23962
24574
  return packet.data;
23963
24575
  }
23964
24576
  if (trackData.inputIsAdts === null) {
@@ -24186,7 +24798,16 @@ ${cue.notes ?? ""}`;
24186
24798
  view2.setUint32(12, computeMpegTsCrc32(PAT_SECTION.subarray(0, 12)), false);
24187
24799
  }
24188
24800
  var buildPmt = (trackDatas) => {
24189
- const sectionLength = 9 + trackDatas.length * 5 + 4;
24801
+ let totalEsBytes = 0;
24802
+ for (const trackData of trackDatas) {
24803
+ totalEsBytes += 5;
24804
+ if (trackData.streamType === 129 /* AC3_SYSTEM_A */) {
24805
+ totalEsBytes += AC3_REGISTRATION_DESCRIPTOR.length;
24806
+ } else if (trackData.streamType === 135 /* EAC3_SYSTEM_A */) {
24807
+ totalEsBytes += EAC3_REGISTRATION_DESCRIPTOR.length;
24808
+ }
24809
+ }
24810
+ const sectionLength = 9 + totalEsBytes + 4;
24190
24811
  const section = new Uint8Array(3 + sectionLength - 4);
24191
24812
  const view2 = toDataView(section);
24192
24813
  section[0] = 2;
@@ -24202,8 +24823,20 @@ ${cue.notes ?? ""}`;
24202
24823
  section[offset++] = trackData.streamType;
24203
24824
  view2.setUint16(offset, 57344 | trackData.pid & 8191, false);
24204
24825
  offset += 2;
24205
- view2.setUint16(offset, 61440, false);
24206
- offset += 2;
24826
+ if (trackData.streamType === 129 /* AC3_SYSTEM_A */) {
24827
+ view2.setUint16(offset, 61440 | AC3_REGISTRATION_DESCRIPTOR.length, false);
24828
+ offset += 2;
24829
+ section.set(AC3_REGISTRATION_DESCRIPTOR, offset);
24830
+ offset += AC3_REGISTRATION_DESCRIPTOR.length;
24831
+ } else if (trackData.streamType === 135 /* EAC3_SYSTEM_A */) {
24832
+ view2.setUint16(offset, 61440 | EAC3_REGISTRATION_DESCRIPTOR.length, false);
24833
+ offset += 2;
24834
+ section.set(EAC3_REGISTRATION_DESCRIPTOR, offset);
24835
+ offset += EAC3_REGISTRATION_DESCRIPTOR.length;
24836
+ } else {
24837
+ view2.setUint16(offset, 61440, false);
24838
+ offset += 2;
24839
+ }
24207
24840
  }
24208
24841
  const crc = computeMpegTsCrc32(section);
24209
24842
  const result = new Uint8Array(section.length + 4);
@@ -24581,6 +25214,9 @@ ${cue.notes ?? ""}`;
24581
25214
  get supportsVideoRotationMetadata() {
24582
25215
  return true;
24583
25216
  }
25217
+ get supportsTimestampedMediaData() {
25218
+ return true;
25219
+ }
24584
25220
  /** @internal */
24585
25221
  _createMuxer(output) {
24586
25222
  return new IsobmffMuxer2(output, this);
@@ -24605,7 +25241,7 @@ ${cue.notes ?? ""}`;
24605
25241
  return [
24606
25242
  ...VIDEO_CODECS,
24607
25243
  ...NON_PCM_AUDIO_CODECS,
24608
- // These are supported via ISO/IEC 23003-5
25244
+ // These are supported via ISO/IEC 23003-5:
24609
25245
  "pcm-s16",
24610
25246
  "pcm-s16be",
24611
25247
  "pcm-s24",
@@ -24714,6 +25350,9 @@ ${cue.notes ?? ""}`;
24714
25350
  get supportsVideoRotationMetadata() {
24715
25351
  return false;
24716
25352
  }
25353
+ get supportsTimestampedMediaData() {
25354
+ return true;
25355
+ }
24717
25356
  };
24718
25357
  var WebMOutputFormat = class extends MkvOutputFormat2 {
24719
25358
  /** Creates a new {@link WebMOutputFormat} configured with the specified `options`. */
@@ -24788,6 +25427,9 @@ ${cue.notes ?? ""}`;
24788
25427
  get supportsVideoRotationMetadata() {
24789
25428
  return false;
24790
25429
  }
25430
+ get supportsTimestampedMediaData() {
25431
+ return false;
25432
+ }
24791
25433
  };
24792
25434
  var WavOutputFormat = class extends OutputFormat {
24793
25435
  /** Creates a new {@link WavOutputFormat} configured with the specified `options`. */
@@ -24839,6 +25481,9 @@ ${cue.notes ?? ""}`;
24839
25481
  get supportsVideoRotationMetadata() {
24840
25482
  return false;
24841
25483
  }
25484
+ get supportsTimestampedMediaData() {
25485
+ return false;
25486
+ }
24842
25487
  };
24843
25488
  var OggOutputFormat = class extends OutputFormat {
24844
25489
  /** Creates a new {@link OggOutputFormat} configured with the specified `options`. */
@@ -24886,6 +25531,9 @@ ${cue.notes ?? ""}`;
24886
25531
  get supportsVideoRotationMetadata() {
24887
25532
  return false;
24888
25533
  }
25534
+ get supportsTimestampedMediaData() {
25535
+ return false;
25536
+ }
24889
25537
  };
24890
25538
  var AdtsOutputFormat = class extends OutputFormat {
24891
25539
  /** Creates a new {@link AdtsOutputFormat} configured with the specified `options`. */
@@ -24927,6 +25575,9 @@ ${cue.notes ?? ""}`;
24927
25575
  get supportsVideoRotationMetadata() {
24928
25576
  return false;
24929
25577
  }
25578
+ get supportsTimestampedMediaData() {
25579
+ return false;
25580
+ }
24930
25581
  };
24931
25582
  var FlacOutputFormat = class extends OutputFormat {
24932
25583
  /** Creates a new {@link FlacOutputFormat} configured with the specified `options`. */
@@ -24965,6 +25616,9 @@ ${cue.notes ?? ""}`;
24965
25616
  get supportsVideoRotationMetadata() {
24966
25617
  return false;
24967
25618
  }
25619
+ get supportsTimestampedMediaData() {
25620
+ return false;
25621
+ }
24968
25622
  };
24969
25623
  var MpegTsOutputFormat = class extends OutputFormat {
24970
25624
  /** Creates a new {@link MpegTsOutputFormat} configured with the specified `options`. */
@@ -25006,12 +25660,15 @@ ${cue.notes ?? ""}`;
25006
25660
  getSupportedCodecs() {
25007
25661
  return [
25008
25662
  ...VIDEO_CODECS.filter((codec) => ["avc", "hevc"].includes(codec)),
25009
- ...AUDIO_CODECS.filter((codec) => ["aac", "mp3"].includes(codec))
25663
+ ...AUDIO_CODECS.filter((codec) => ["aac", "mp3", "ac3", "eac3"].includes(codec))
25010
25664
  ];
25011
25665
  }
25012
25666
  get supportsVideoRotationMetadata() {
25013
25667
  return false;
25014
25668
  }
25669
+ get supportsTimestampedMediaData() {
25670
+ return true;
25671
+ }
25015
25672
  };
25016
25673
 
25017
25674
  // src/encode.ts
@@ -25188,8 +25845,12 @@ ${cue.notes ?? ""}`;
25188
25845
  // 64kbps base for Opus
25189
25846
  mp3: 16e4,
25190
25847
  // 160kbps base for MP3
25191
- vorbis: 64e3
25848
+ vorbis: 64e3,
25192
25849
  // 64kbps base for Vorbis
25850
+ ac3: 384e3,
25851
+ // 384kbps base for AC-3
25852
+ eac3: 192e3
25853
+ // 192kbps base for E-AC-3
25193
25854
  };
25194
25855
  const baseBitrate = baseRates[codec];
25195
25856
  if (!baseBitrate) {
@@ -27561,11 +28222,11 @@ ${cue.notes ?? ""}`;
27561
28222
  if (options.trim !== void 0 && (!options.trim || typeof options.trim !== "object")) {
27562
28223
  throw new TypeError("options.trim, when provided, must be an object.");
27563
28224
  }
27564
- if (options.trim?.start !== void 0 && (!Number.isFinite(options.trim.start) || options.trim.start < 0)) {
27565
- throw new TypeError("options.trim.start, when provided, must be a non-negative number.");
28225
+ if (options.trim?.start !== void 0 && !Number.isFinite(options.trim.start)) {
28226
+ throw new TypeError("options.trim.start, when provided, must be a finite number.");
27566
28227
  }
27567
- if (options.trim?.end !== void 0 && (!Number.isFinite(options.trim.end) || options.trim.end < 0)) {
27568
- throw new TypeError("options.trim.end, when provided, must be a non-negative number.");
28228
+ if (options.trim?.end !== void 0 && !Number.isFinite(options.trim.end)) {
28229
+ throw new TypeError("options.trim.end, when provided, must be a finite number.");
27569
28230
  }
27570
28231
  if (options.trim?.start !== void 0 && options.trim.end !== void 0 && options.trim.start >= options.trim.end) {
27571
28232
  throw new TypeError("options.trim.start must be less than options.trim.end.");
@@ -27600,7 +28261,7 @@ ${cue.notes ?? ""}`;
27600
28261
  // those out by default.
27601
28262
  0
27602
28263
  );
27603
- this._endTimestamp = this._options.trim?.end ?? Infinity;
28264
+ this._endTimestamp = Math.max(this._options.trim?.end ?? Infinity, this._startTimestamp);
27604
28265
  const inputTracks = await this.input.getTracks();
27605
28266
  const outputTrackCounts = this.output.format.getSupportedTrackCounts();
27606
28267
  let nVideo = 1;
@@ -28126,7 +28787,7 @@ The @mediabunny/mp3-encoder extension package provides support for encoding MP3.
28126
28787
  const firstTimestamp = await track.getFirstTimestamp();
28127
28788
  let numberOfChannels = trackOptions.numberOfChannels ?? originalNumberOfChannels;
28128
28789
  let sampleRate = trackOptions.sampleRate ?? originalSampleRate;
28129
- let needsResample = numberOfChannels !== originalNumberOfChannels || sampleRate !== originalSampleRate || firstTimestamp < this._startTimestamp;
28790
+ let needsResample = numberOfChannels !== originalNumberOfChannels || sampleRate !== originalSampleRate || firstTimestamp < this._startTimestamp || firstTimestamp > this._startTimestamp && !this.output.format.supportsTimestampedMediaData;
28130
28791
  let audioCodecs = this.output.format.getSupportedAudioCodecs();
28131
28792
  if (!trackOptions.forceTranscode && !trackOptions.bitrate && !needsResample && audioCodecs.includes(sourceCodec) && (!trackOptions.codec || trackOptions.codec === sourceCodec) && !trackOptions.process) {
28132
28793
  const source = new EncodedAudioPacketSource(sourceCodec);