@poe-platform/safe-bash 0.1.839 → 0.1.841

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 (68) hide show
  1. package/dist/audio-ast/binary.d.ts +19 -0
  2. package/dist/audio-ast/index.d.ts +1 -0
  3. package/dist/audio-ast/index.js +92 -91
  4. package/dist/audio-ast/mpeg.d.ts +23 -0
  5. package/dist/mp4-ast/containers/adapters.d.ts +1 -0
  6. package/dist/mp4-ast/types.d.ts +8 -2
  7. package/dist/pdf-ast/cos/security.d.ts +10 -0
  8. package/dist/pdf-ast/edit/retained-attachment-edits.d.ts +4 -0
  9. package/dist/pdf-ast/edit/retained-graph.d.ts +1 -1
  10. package/dist/pdf-ast/image.js +1 -1
  11. package/dist/pdf-ast/index.d.ts +2 -1
  12. package/dist/pdf-ast/index.js +7 -1
  13. package/dist/pdf-ast/vendor/pdfjs-fonts.d.mts +8 -0
  14. package/dist/pdf-ast/vendor/pdfjs-fonts.mjs +28 -0
  15. package/dist/safe-bash/audio-ast.browser.js +2 -1
  16. package/dist/safe-bash/audio-ast.js +1 -1
  17. package/dist/safe-bash/command-chunks/{chunk-SG2KOOD4.js → chunk-3SAYZFMD.js} +2 -2
  18. package/dist/safe-bash/command-chunks/{chunk-T6OXG7QQ.js → chunk-AAOPVEPF.js} +66 -1
  19. package/dist/safe-bash/command-chunks/{chunk-FH5VMAPS.js → chunk-BZW25LNV.js} +420 -131
  20. package/dist/safe-bash/command-chunks/{chunk-DQVOBGI2.js → chunk-CIV3GER2.js} +6770 -6523
  21. package/dist/safe-bash/command-chunks/{chunk-46GA576V.js → chunk-CPKVUB7S.js} +2 -2
  22. package/dist/safe-bash/command-chunks/{chunk-MBXNG6C3.js → chunk-DLLN3C3Q.js} +1 -1
  23. package/dist/safe-bash/command-chunks/{chunk-ZSQCROFE.js → chunk-DM5T5D2K.js} +5 -1
  24. package/dist/safe-bash/command-chunks/{chunk-3EAZRKI4.js → chunk-G7HQYFIU.js} +10 -1
  25. package/dist/safe-bash/command-chunks/{chunk-GYKQ3IOV.js → chunk-LMYQMJYY.js} +94 -18
  26. package/dist/safe-bash/command-chunks/{chunk-DX7KU6YU.js → chunk-N52AHO6S.js} +1 -1
  27. package/dist/safe-bash/command-chunks/{chunk-4BSD2RGK.js → chunk-QPKL5GWH.js} +102 -42
  28. package/dist/safe-bash/command-chunks/{chunk-Z2T7E4ID.js → chunk-R7QLP5RH.js} +1212 -1119
  29. package/dist/safe-bash/command-chunks/{chunk-77ROD2TR.js → chunk-X3WNWRVT.js} +11 -5
  30. package/dist/safe-bash/command-chunks/{chunk-RSFKQE2U.js → chunk-YAXP4EHP.js} +19 -10
  31. package/dist/safe-bash/command-chunks/{chunk-TCXM7BSZ.js → chunk-YFMNXPLP.js} +4 -4
  32. package/dist/safe-bash-command-exiftool/index.js +25 -1
  33. package/dist/safe-bash-command-ffmpeg/index.js +191 -49
  34. package/dist/safe-bash-command-ffprobe/index.js +2 -2
  35. package/dist/safe-bash-command-ffprobe/media.js +2 -2
  36. package/dist/safe-bash-command-imagemagick/index.js +498 -101
  37. package/dist/safe-bash-command-mdq/index.js +2 -0
  38. package/dist/safe-bash-command-pandoc/citeproc-filters.js +7 -7
  39. package/dist/safe-bash-command-pandoc/command.js +8 -8
  40. package/dist/safe-bash-command-pandoc/index.js +52 -52
  41. package/dist/safe-bash-command-qpdf/index.js +1037 -654
  42. package/dist/safe-bash-command-qpdf/page-range.d.ts +2 -0
  43. package/dist/safe-bash-command-soffice/index.js +28 -8
  44. package/dist/safe-bash-command-sqlite3/btree.d.ts +2 -1
  45. package/dist/safe-bash-command-sqlite3/engine.d.ts +15 -1
  46. package/dist/safe-bash-command-sqlite3/index.js +294 -68
  47. package/dist/safe-bash-command-tar/create.js +2 -2
  48. package/dist/safe-bash-command-tar/extract.js +2 -2
  49. package/dist/safe-bash-command-tar/format.js +1 -1
  50. package/dist/safe-bash-command-tar/index.js +4 -4
  51. package/dist/safe-bash-command-tar/modes.js +4 -4
  52. package/dist/safe-bash-command-unzip/index.js +1 -1
  53. package/dist/safe-bash-command-unzip/unzip.js +1 -1
  54. package/dist/safe-bash-markdown-engine/commonmark-blocks.d.ts +17 -1
  55. package/dist/safe-bash-markdown-engine/commonmark-blocks.js +3 -3
  56. package/dist/safe-bash-markdown-engine/commonmark-inlines.d.ts +1 -1
  57. package/dist/safe-bash-markdown-engine/commonmark-inlines.js +3 -3
  58. package/dist/safe-bash-markdown-engine/commonmark-syntax.d.ts +5 -0
  59. package/dist/safe-bash-markdown-engine/commonmark-syntax.js +5 -1
  60. package/dist/safe-bash-markdown-engine/gfm-syntax.js +2 -2
  61. package/dist/safe-bash-markdown-engine/index.js +4 -4
  62. package/dist/safe-bash-zip-engine/index.js +1 -1
  63. package/dist/safe-bash-zip-engine/zip/repair.js +1 -1
  64. package/dist/safe-bash-zip-engine/zip/sfx.js +1 -1
  65. package/dist/safe-bash-zip-engine/zip-format.d.ts +2 -0
  66. package/dist/safe-bash-zip-engine/zip-format.js +1 -1
  67. package/package.json +2 -2
  68. package/third-party/pdf-ast/THIRD_PARTY_NOTICES.md +2 -0
@@ -381276,7 +381276,7 @@ function buildProbeStream(track, desc, stats, idx, containerFormat) {
381276
381276
  duration_ts: track.duration,
381277
381277
  duration: durationSec.toFixed(6),
381278
381278
  bit_rate: bitRate,
381279
- nb_frames: String(nbFrames),
381279
+ nb_frames: containerFormat === "wav" ? void 0 : String(nbFrames),
381280
381280
  disposition: {
381281
381281
  default: track.enabled ? 1 : 0,
381282
381282
  dub: 0,
@@ -381979,7 +381979,7 @@ function parseMp4(bytes, options = {}) {
381979
381979
  else if (step.kind === "sync-has") answer = syncSamples.has(step.sample);
381980
381980
  else {
381981
381981
  const { offset, ...sample } = step.sample;
381982
- samples.push({ ...sample, data: bytes.subarray(offset, offset + sample.size) });
381982
+ samples.push({ ...sample, offset, data: bytes.subarray(offset, offset + sample.size) });
381983
381983
  }
381984
381984
  }
381985
381985
  if (moofBoxes.length > 0) {
@@ -382019,7 +382019,7 @@ function parseMp4(bytes, options = {}) {
382019
382019
  if (step.kind === "read") answer2 = bytes.subarray(step.offset, step.offset + step.length);
382020
382020
  else if (step.kind === "sample") {
382021
382021
  const { offset, ...sample } = step.sample;
382022
- samples.push({ ...sample, data: bytes.subarray(offset, offset + sample.size) });
382022
+ samples.push({ ...sample, offset, data: bytes.subarray(offset, offset + sample.size) });
382023
382023
  }
382024
382024
  }
382025
382025
  }
@@ -383203,8 +383203,8 @@ function buildProbeResultFromDoc(doc, byteLength, filename = "input.mp4", option
383203
383203
  duration: s.duration,
383204
383204
  duration_time: durTime,
383205
383205
  size: String(s.size),
383206
- pos: String(bytePos),
383207
- flags: s.isKeyframe ? "K_" : "__"
383206
+ pos: String(s.offset ?? (doc.containerFormat === "mp4" || doc.containerFormat === "mov" ? -1 : bytePos)),
383207
+ flags: s.isKeyframe ? "K__" : "___"
383208
383208
  });
383209
383209
  }
383210
383210
  if (options.showFrames) {
@@ -383218,13 +383218,12 @@ function buildProbeResultFromDoc(doc, byteLength, filename = "input.mp4", option
383218
383218
  pkt_dts_time: dtsTime,
383219
383219
  best_effort_timestamp: s.pts,
383220
383220
  best_effort_timestamp_time: ptsTime,
383221
- pkt_duration: s.duration,
383222
- pkt_duration_time: durTime,
383221
+ ...doc.containerFormat === "gif" ? { duration: s.duration, duration_time: durTime } : { pkt_duration: s.duration, pkt_duration_time: durTime },
383223
383222
  pkt_size: String(s.size),
383224
383223
  width: w,
383225
383224
  height: h,
383226
383225
  pix_fmt: track.type === "video" ? desc?.pixFmt ?? "yuv420p" : void 0,
383227
- pict_type: track.type === "video" ? s.isKeyframe ? "I" : "P" : void 0,
383226
+ pict_type: void 0,
383228
383227
  sample_fmt: sampleFormat,
383229
383228
  nb_samples: track.type === "audio" ? s.duration : void 0,
383230
383229
  channels: track.type === "audio" ? desc?.channels ?? 2 : void 0
@@ -384267,6 +384266,132 @@ function serializeDashDocument(doc, options = {}) {
384267
384266
  return { manifest, resources };
384268
384267
  }
384269
384268
 
384269
+ // packages/mp4-ast/src/containers/mp3-frames.ts
384270
+ import { mpegFrame } from "../../audio-ast/index.js";
384271
+ function* scanMp3Frames() {
384272
+ const frames = [];
384273
+ let offset = 0, first = true, skipSamples = 0, discardPadding = 0;
384274
+ while (true) {
384275
+ const bytes = yield { offset, length: 4 };
384276
+ if (!bytes.length) break;
384277
+ if (bytes.length < 4) throw new Error("Truncated MPEG frame");
384278
+ const marker = String.fromCharCode(...bytes.subarray(0, 3));
384279
+ if (marker === "ID3") {
384280
+ const tag = yield { offset: offset + 4, length: 6 };
384281
+ if (tag.length !== 6 || tag.subarray(2).some((b) => b > 127)) throw new Error("Invalid ID3 header");
384282
+ const size = tag[2] * 2097152 + tag[3] * 16384 + tag[4] * 128 + tag[5];
384283
+ offset += 10 + size + (bytes[3] === 4 && tag[1] & 16 ? 10 : 0);
384284
+ continue;
384285
+ }
384286
+ if (marker === "TAG") {
384287
+ const tag = yield { offset: offset + 4, length: 124 };
384288
+ if (tag.length !== 124) throw new Error("Truncated ID3v1 tag");
384289
+ offset += 128;
384290
+ continue;
384291
+ }
384292
+ const header = new DataView(bytes.buffer, bytes.byteOffset, 4).getUint32(0);
384293
+ const frame = mpegFrame(header, offset, Infinity);
384294
+ const payload = yield { offset: offset + 4, length: frame.frameSize - 4 };
384295
+ if (payload.length !== frame.frameSize - 4) throw new Error("Truncated MPEG frame");
384296
+ const side = frame.version === 1 ? frame.channels === 1 ? 17 : 32 : frame.channels === 1 ? 9 : 17;
384297
+ const xing = side + (header & 65536 ? 0 : 2);
384298
+ const text = (pos) => String.fromCharCode(...payload.subarray(pos, pos + 4));
384299
+ const metadata = first && (["Xing", "Info"].includes(text(xing)) || text(32) === "VBRI");
384300
+ if (metadata && ["Xing", "Info"].includes(text(xing)) && xing + 8 <= payload.length) {
384301
+ const flags = new DataView(payload.buffer, payload.byteOffset, payload.length).getUint32(xing + 4);
384302
+ const encoder = xing + 8 + (flags & 1 ? 4 : 0) + (flags & 2 ? 4 : 0) + (flags & 4 ? 100 : 0) + (flags & 8 ? 4 : 0);
384303
+ if (encoder + 24 <= payload.length && ["LAME", "Lavc", "Lavf"].includes(text(encoder))) {
384304
+ const delay = payload[encoder + 21] * 16 + (payload[encoder + 22] >>> 4);
384305
+ const padding = (payload[encoder + 22] & 15) * 256 + payload[encoder + 23];
384306
+ skipSamples = delay + 529;
384307
+ discardPadding = Math.max(0, padding - 529);
384308
+ }
384309
+ }
384310
+ first = false;
384311
+ if (!metadata) frames.push({ offset, size: frame.frameSize, sampleRate: frame.rate, channels: frame.channels, samples: frame.count, skipSamples: 0, discardPadding: 0 });
384312
+ offset += frame.frameSize;
384313
+ }
384314
+ if (!frames.length) throw new Error("MP3 contains no MPEG frames");
384315
+ for (const frame of frames) {
384316
+ frame.skipSamples = Math.min(skipSamples, frame.samples);
384317
+ skipSamples -= frame.skipSamples;
384318
+ }
384319
+ for (let i = frames.length - 1; i >= 0 && discardPadding; i--) {
384320
+ const frame = frames[i];
384321
+ frame.discardPadding = Math.min(discardPadding, frame.samples - frame.skipSamples);
384322
+ discardPadding -= frame.discardPadding;
384323
+ }
384324
+ return frames;
384325
+ }
384326
+ function readMp3Frames(bytes) {
384327
+ const scan = scanMp3Frames();
384328
+ let step = scan.next();
384329
+ while (!step.done) {
384330
+ const { offset, length } = step.value;
384331
+ step = scan.next(bytes.subarray(offset, offset + length));
384332
+ }
384333
+ return step.value;
384334
+ }
384335
+ async function readMp3SourceFrames(source, signal) {
384336
+ signal?.throwIfAborted();
384337
+ if (!Number.isSafeInteger(source.size) || source.size < 0) throw new RangeError("Invalid MP3 source size");
384338
+ const scan = scanMp3Frames();
384339
+ let step = scan.next();
384340
+ while (!step.done) {
384341
+ const { offset, length } = step.value;
384342
+ const bytes = new Uint8Array(Math.max(0, Math.min(length, source.size - offset)));
384343
+ let filled = 0;
384344
+ while (filled < bytes.length) {
384345
+ signal?.throwIfAborted();
384346
+ const chunk = await source.read(offset + filled, bytes.length - filled);
384347
+ signal?.throwIfAborted();
384348
+ if (!chunk.length || chunk.length > bytes.length - filled) throw new Error("Invalid MP3 source read");
384349
+ bytes.set(chunk, filled);
384350
+ filled += chunk.length;
384351
+ }
384352
+ step = scan.next(bytes);
384353
+ }
384354
+ signal?.throwIfAborted();
384355
+ return step.value;
384356
+ }
384357
+ async function readMp3StreamFrames(source, signal) {
384358
+ signal?.throwIfAborted();
384359
+ const scan = scanMp3Frames();
384360
+ let step = scan.next(), bytes = new Uint8Array(step.done ? 0 : step.value.length);
384361
+ let size = 0, filled = 0;
384362
+ let failure;
384363
+ for await (const chunk of source) {
384364
+ signal?.throwIfAborted();
384365
+ const start = size;
384366
+ size += chunk.byteLength;
384367
+ if (!Number.isSafeInteger(size)) throw new RangeError("Invalid MP3 source size");
384368
+ if (failure) continue;
384369
+ try {
384370
+ while (!step.done && step.value.offset < size) {
384371
+ signal?.throwIfAborted();
384372
+ const request = step.value;
384373
+ const from = Math.max(start, request.offset + filled), end = Math.min(size, request.offset + request.length);
384374
+ if (end > from) {
384375
+ bytes.set(chunk.subarray(from - start, end - start), filled);
384376
+ filled += end - from;
384377
+ }
384378
+ if (filled < request.length) break;
384379
+ step = scan.next(bytes);
384380
+ bytes = new Uint8Array(step.done ? 0 : step.value.length);
384381
+ filled = 0;
384382
+ }
384383
+ } catch (error) {
384384
+ signal?.throwIfAborted();
384385
+ failure = { error };
384386
+ }
384387
+ }
384388
+ signal?.throwIfAborted();
384389
+ if (failure) throw failure.error;
384390
+ if (!step.done) step = scan.next(bytes.subarray(0, filled));
384391
+ if (!step.done) throw new Error("Truncated MP3 source");
384392
+ return { frames: step.value, size };
384393
+ }
384394
+
384270
384395
  // packages/mp4-ast/src/aac.ts
384271
384396
  function decodeAacTrack(doc, track) {
384272
384397
  const description = track.codecDescriptions[0];
@@ -384514,6 +384639,101 @@ function encodeFlacPackets(doc) {
384514
384639
  return frames;
384515
384640
  }
384516
384641
 
384642
+ // packages/mp4-ast/src/containers/flac-probe.ts
384643
+ function checksum(value, byte, width, polynomial) {
384644
+ value ^= byte << width - 8;
384645
+ for (let bit = 0; bit < 8; bit++) value = value << 1 ^ (value & 1 << width - 1 ? polynomial : 0);
384646
+ return value & (1 << width) - 1;
384647
+ }
384648
+ function frameHeader(bytes, start) {
384649
+ if (bytes[start] !== 255 || (bytes[start + 1] & 254) !== 248 || bytes[start + 3] & 1) return;
384650
+ const block = bytes[start + 2] >>> 4, rate = bytes[start + 2] & 15;
384651
+ if (!block || rate === 15 || bytes[start + 3] >>> 4 > 10) return;
384652
+ let pos = start + 4, number = bytes[pos++];
384653
+ if (number >= 128) {
384654
+ let tails = 0, mask = 128;
384655
+ while (number & mask) {
384656
+ tails++;
384657
+ mask >>>= 1;
384658
+ }
384659
+ if (tails < 2 || tails > 7) return;
384660
+ number &= mask - 1;
384661
+ for (let i = 1; i < tails; i++) {
384662
+ const byte = bytes[pos++];
384663
+ if ((byte & 192) !== 128) return;
384664
+ number = number * 64 + (byte & 63);
384665
+ }
384666
+ }
384667
+ let duration = block === 1 ? 192 : block < 6 ? 576 * 2 ** (block - 2) : 256 * 2 ** (block - 8);
384668
+ if (block === 6) duration = bytes[pos++] + 1;
384669
+ if (block === 7) {
384670
+ duration = bytes[pos] * 256 + bytes[pos + 1] + 1;
384671
+ pos += 2;
384672
+ }
384673
+ pos += rate === 12 ? 1 : rate >= 13 ? 2 : 0;
384674
+ if (pos >= bytes.length) return;
384675
+ let crc2 = 0;
384676
+ for (let i = start; i <= pos; i++) crc2 = checksum(crc2, bytes[i], 8, 7);
384677
+ if (crc2) return;
384678
+ return { duration, number, variable: !!(bytes[start + 1] & 1) };
384679
+ }
384680
+ var FlacFrameScanner = class {
384681
+ header = new Uint8Array(42);
384682
+ packets = [];
384683
+ size = 0;
384684
+ pending = new Uint8Array();
384685
+ offset = 0;
384686
+ metadataEnd = 4;
384687
+ audio = false;
384688
+ lastMetadata = false;
384689
+ crc = 0;
384690
+ frame;
384691
+ fixedBlockSize = 0;
384692
+ push(chunk, final = false) {
384693
+ if (this.size < 42) this.header.set(chunk.subarray(0, 42 - this.size), this.size);
384694
+ this.size += chunk.length;
384695
+ let bytes = chunk;
384696
+ if (this.pending.length) {
384697
+ bytes = new Uint8Array(this.pending.length + chunk.length);
384698
+ bytes.set(this.pending);
384699
+ bytes.set(chunk, this.pending.length);
384700
+ }
384701
+ let pos = 0;
384702
+ const end = final ? bytes.length : Math.max(0, bytes.length - 16);
384703
+ for (; pos < end; pos++, this.offset++) {
384704
+ if (!this.audio) {
384705
+ if (this.offset < this.metadataEnd) continue;
384706
+ if (!this.lastMetadata) {
384707
+ if (pos + 4 > bytes.length) break;
384708
+ this.lastMetadata = !!(bytes[pos] & 128);
384709
+ this.metadataEnd = this.offset + 4 + bytes[pos + 1] * 65536 + bytes[pos + 2] * 256 + bytes[pos + 3];
384710
+ continue;
384711
+ }
384712
+ this.audio = true;
384713
+ }
384714
+ if (!this.frame || this.crc === 0) {
384715
+ const header = frameHeader(bytes, pos);
384716
+ if (header) {
384717
+ if (this.frame) this.packets.push({ ...this.frame, size: this.offset - this.frame.pos });
384718
+ this.fixedBlockSize ||= header.duration;
384719
+ this.frame = {
384720
+ pts: header.variable ? header.number : header.number * this.fixedBlockSize,
384721
+ duration: header.duration,
384722
+ pos: this.offset
384723
+ };
384724
+ this.crc = 0;
384725
+ }
384726
+ }
384727
+ if (this.frame) this.crc = checksum(this.crc, bytes[pos], 16, 32773);
384728
+ }
384729
+ this.pending = bytes.slice(pos);
384730
+ if (final && this.frame && this.crc === 0) {
384731
+ this.packets.push({ ...this.frame, size: this.offset - this.frame.pos });
384732
+ this.frame = void 0;
384733
+ }
384734
+ }
384735
+ };
384736
+
384517
384737
  // packages/mp4-ast/src/containers/ogg.ts
384518
384738
  function page(packet, sequence, flags, granule) {
384519
384739
  const segments = Math.floor(packet.length / 255) + 1;
@@ -384634,7 +384854,7 @@ async function readOggFlacHeader(source, options = {}) {
384634
384854
  const start = offset, header = await read(27);
384635
384855
  if (header[0] !== 79 || header[1] !== 103 || header[2] !== 103 || header[3] !== 83) throw new Error("Invalid Ogg page");
384636
384856
  const lacing = await read(header[26]);
384637
- let checksum = oggCrc(lacing, oggCrc(header), 27);
384857
+ let checksum2 = oggCrc(lacing, oggCrc(header), 27);
384638
384858
  const continuation = Boolean(header[5] & 1) !== packetSize > 0;
384639
384859
  let remaining = 0, chunk = new Uint8Array(), used = 0;
384640
384860
  for (const length of lacing) remaining += length;
@@ -384643,7 +384863,7 @@ async function readOggFlacHeader(source, options = {}) {
384643
384863
  if (used === chunk.length) {
384644
384864
  chunk = await read(Math.min(16384, remaining));
384645
384865
  used = 0;
384646
- checksum = oggCrc(chunk, checksum, offset - start - chunk.length);
384866
+ checksum2 = oggCrc(chunk, checksum2, offset - start - chunk.length);
384647
384867
  remaining -= chunk.length;
384648
384868
  }
384649
384869
  const take = Math.min(pending, chunk.length - used);
@@ -384661,7 +384881,7 @@ async function readOggFlacHeader(source, options = {}) {
384661
384881
  packetSize = 0;
384662
384882
  }
384663
384883
  }
384664
- if (checksum !== new DataView(header.buffer).getUint32(22, true)) throw new Error("Ogg CRC mismatch");
384884
+ if (checksum2 !== new DataView(header.buffer).getUint32(22, true)) throw new Error("Ogg CRC mismatch");
384665
384885
  if (continuation) throw new Error("Invalid Ogg packet continuation");
384666
384886
  if (firstSize >= 0 && !mapped) return void 0;
384667
384887
  }
@@ -386509,7 +386729,10 @@ function aacAst() {
386509
386729
  function isWavSignature(bytes) {
386510
386730
  return bytes.byteLength >= 12 && decodeFourCC(bytes, 0) === "RIFF" && decodeFourCC(bytes, 8) === "WAVE";
386511
386731
  }
386512
- var wavPacketFrames = 1024;
386732
+ function wavPacketFrames(sampleRate, block) {
386733
+ const samples = Math.max(1, Math.min(Math.floor(sampleRate / 10), Math.floor(2147483647 / block)));
386734
+ return 2 ** Math.floor(Math.log2(samples));
386735
+ }
386513
386736
  function parseWav(bytes, options = {}) {
386514
386737
  const header = readWavHeader(bytes);
386515
386738
  const { formatTag, channels, sampleRate, bitsPerSample } = header;
@@ -386540,7 +386763,7 @@ function parseWav(bytes, options = {}) {
386540
386763
  decodedAudio = { sampleRate, channels, channelData };
386541
386764
  }
386542
386765
  const samples = [];
386543
- const chunkFrames = wavPacketFrames;
386766
+ const chunkFrames = wavPacketFrames(header.sampleRate, bytesPerFrame);
386544
386767
  for (let offsetSample = 0; offsetSample < totalPcmSamples; offsetSample += chunkFrames) {
386545
386768
  const count = Math.min(chunkFrames, totalPcmSamples - offsetSample);
386546
386769
  const byteStart = offsetSample * bytesPerFrame;
@@ -386643,7 +386866,6 @@ function wavMetadata(header, filename = "input.wav") {
386643
386866
  const bytesPerFrame = Math.max(1, header.channels * (header.bitsPerSample >>> 3));
386644
386867
  return { ...result, streams: [{
386645
386868
  ...result.streams[0],
386646
- nb_frames: String(Math.ceil(samples / wavPacketFrames)),
386647
386869
  bit_rate: doc.durationSeconds > 0 ? String(Math.round(samples * bytesPerFrame * 8 / doc.durationSeconds)) : "0"
386648
386870
  }] };
386649
386871
  }
@@ -386651,10 +386873,11 @@ function wavRecords(header, options) {
386651
386873
  const metadata = wavMetadata(header, options.filename), stream = metadata.streams[0];
386652
386874
  const bytesPerFrame = Math.max(1, header.channels * (header.bitsPerSample >>> 3));
386653
386875
  const samples = Math.floor(header.dataSize / bytesPerFrame), rate = Math.max(1, header.sampleRate);
386876
+ const chunkFrames = wavPacketFrames(header.sampleRate, bytesPerFrame);
386654
386877
  function* spans() {
386655
- for (let pts = 0; pts < samples; pts += wavPacketFrames) {
386878
+ for (let pts = 0; pts < samples; pts += chunkFrames) {
386656
386879
  options.signal?.throwIfAborted();
386657
- const count = Math.min(wavPacketFrames, samples - pts);
386880
+ const count = Math.min(chunkFrames, samples - pts);
386658
386881
  yield { pts, count, size: String(count * bytesPerFrame), time: (pts / rate).toFixed(6), duration: (count / rate).toFixed(6) };
386659
386882
  }
386660
386883
  options.signal?.throwIfAborted();
@@ -386673,7 +386896,7 @@ function wavRecords(header, options) {
386673
386896
  duration_time: s.duration,
386674
386897
  size: s.size,
386675
386898
  pos: String(s.pts * bytesPerFrame),
386676
- flags: "K_"
386899
+ flags: "K__"
386677
386900
  };
386678
386901
  } } : void 0,
386679
386902
  frames: options.showFrames ? { *[Symbol.iterator]() {
@@ -386753,20 +386976,21 @@ function isMp3Signature(bytes) {
386753
386976
  if (bytes[0] === 73 && bytes[1] === 68 && bytes[2] === 51) return true;
386754
386977
  return bytes[0] === 255 && (bytes[1] & 224) === 224 && (bytes[1] & 6) !== 0;
386755
386978
  }
386756
- function mp3Document(byteLength, samples) {
386757
- const sampleRate = 44100, channels = 2, count = Math.max(1, Math.floor(byteLength / 417));
386979
+ function mp3Document(byteLength, frames, samples) {
386980
+ const { sampleRate, channels } = frames[0];
386981
+ const duration = frames.reduce((sum, frame) => sum + frame.samples * 14112e3 / frame.sampleRate, 0);
386758
386982
  return {
386759
386983
  containerFormat: "mp3",
386760
- timescale: sampleRate,
386761
- duration: count * 1152,
386762
- durationSeconds: count * 1152 / sampleRate,
386984
+ timescale: 14112e3,
386985
+ duration,
386986
+ durationSeconds: duration / 14112e3,
386763
386987
  tracks: [
386764
386988
  {
386765
386989
  id: 1,
386766
386990
  type: "audio",
386767
386991
  handlerType: "soun",
386768
- timescale: sampleRate,
386769
- duration: count * 1152,
386992
+ timescale: 14112e3,
386993
+ duration,
386770
386994
  language: "und",
386771
386995
  enabled: true,
386772
386996
  codecDescriptions: [
@@ -386785,24 +387009,27 @@ function mp3Document(byteLength, samples) {
386785
387009
  byteLength
386786
387010
  };
386787
387011
  }
386788
- function mp3Records(size, options) {
387012
+ function mp3Records(size, frames, options) {
386789
387013
  options.signal?.throwIfAborted();
386790
- if (!Number.isSafeInteger(size) || size < 0) throw new RangeError("Invalid MP3 source size");
386791
- const count = Math.max(1, Math.floor(size / 417)), doc = mp3Document(size, []);
387014
+ const doc = mp3Document(size, frames, []);
386792
387015
  const metadata = buildProbeResultFromDoc(doc, size, options.filename ?? "input.mp3", {
386793
387016
  formatName: "mp3",
386794
387017
  formatLongName: "MP2/3 (MPEG audio layer 2/3)"
386795
387018
  });
386796
387019
  const stream = {
386797
387020
  ...metadata.streams[0],
386798
- nb_frames: String(count),
386799
- bit_rate: String(Math.round(Math.min(size, count * 417) * 8 / doc.durationSeconds))
387021
+ nb_frames: void 0,
387022
+ nb_read_packets: String(frames.length),
387023
+ nb_read_frames: String(frames.filter((f) => f.samples > f.skipSamples + f.discardPadding).length),
387024
+ bit_rate: String(Math.round(frames.reduce((sum, f) => sum + f.size, 0) * 8 / doc.durationSeconds))
386800
387025
  };
386801
387026
  function* spans() {
386802
- for (let index = 0; index < count; index++) {
387027
+ let pts = 0;
387028
+ for (const frame of frames) {
386803
387029
  options.signal?.throwIfAborted();
386804
- const pts = index * 1152;
386805
- yield { pts, time: (pts / 44100).toFixed(6), size: String(Math.min(417, size - index * 417)), pos: String(index * 417) };
387030
+ const duration = frame.samples * 14112e3 / frame.sampleRate;
387031
+ yield { ...frame, pts, duration, time: (pts / 14112e3).toFixed(6), durationTime: (duration / 14112e3).toFixed(6) };
387032
+ pts += duration;
386806
387033
  }
386807
387034
  options.signal?.throwIfAborted();
386808
387035
  }
@@ -386817,52 +387044,48 @@ function mp3Records(size, options) {
386817
387044
  pts_time: s.time,
386818
387045
  dts: s.pts,
386819
387046
  dts_time: s.time,
386820
- duration: 1152,
386821
- duration_time: (1152 / 44100).toFixed(6),
386822
- size: s.size,
386823
- pos: s.pos,
386824
- flags: "K_"
387047
+ duration: s.duration,
387048
+ duration_time: s.durationTime,
387049
+ size: String(s.size),
387050
+ pos: String(s.offset),
387051
+ flags: "K__"
386825
387052
  };
386826
387053
  } } : void 0,
386827
387054
  frames: options.showFrames ? { *[Symbol.iterator]() {
386828
- for (const s of spans()) yield {
386829
- media_type: "audio",
386830
- stream_index: 0,
386831
- key_frame: 1,
386832
- pts: s.pts,
386833
- pts_time: s.time,
386834
- pkt_dts: s.pts,
386835
- pkt_dts_time: s.time,
386836
- best_effort_timestamp: s.pts,
386837
- best_effort_timestamp_time: s.time,
386838
- pkt_duration: 1152,
386839
- pkt_duration_time: (1152 / 44100).toFixed(6),
386840
- pkt_size: s.size,
386841
- width: void 0,
386842
- height: void 0,
386843
- pix_fmt: void 0,
386844
- pict_type: void 0,
386845
- sample_fmt: stream.sample_fmt,
386846
- nb_samples: 1152,
386847
- channels: 2
386848
- };
387055
+ for (const s of spans()) {
387056
+ const samples = s.samples - s.skipSamples - s.discardPadding;
387057
+ if (!samples) continue;
387058
+ const pts = s.pts + s.skipSamples * 14112e3 / s.sampleRate, time = (pts / 14112e3).toFixed(6);
387059
+ const duration = samples * 14112e3 / s.sampleRate;
387060
+ yield {
387061
+ media_type: "audio",
387062
+ stream_index: 0,
387063
+ key_frame: 1,
387064
+ pts,
387065
+ pts_time: time,
387066
+ pkt_dts: pts,
387067
+ pkt_dts_time: time,
387068
+ best_effort_timestamp: pts,
387069
+ best_effort_timestamp_time: time,
387070
+ duration,
387071
+ duration_time: (duration / 14112e3).toFixed(6),
387072
+ pkt_size: String(s.size),
387073
+ sample_fmt: stream.sample_fmt,
387074
+ nb_samples: samples,
387075
+ channels: s.channels
387076
+ };
387077
+ }
386849
387078
  } } : void 0
386850
387079
  };
386851
387080
  }
386852
387081
  function mp3Ast() {
386853
387082
  return {
386854
387083
  async probeMetadata(source, options = {}) {
386855
- return mp3Records(source.size, options);
387084
+ return mp3Records(source.size, await readMp3SourceFrames(source, options.signal), options);
386856
387085
  },
386857
387086
  async probeMetadataStream(source, options = {}) {
386858
- options.signal?.throwIfAborted();
386859
- let size = 0;
386860
- for await (const chunk of source) {
386861
- options.signal?.throwIfAborted();
386862
- size += chunk.byteLength;
386863
- if (!Number.isSafeInteger(size)) throw new RangeError("Invalid MP3 source size");
386864
- }
386865
- return mp3Records(size, options);
387087
+ const { frames, size } = await readMp3StreamFrames(source, options.signal);
387088
+ return mp3Records(size, frames, options);
386866
387089
  },
386867
387090
  id: "mp3",
386868
387091
  formatName: "mp3",
@@ -386879,23 +387102,24 @@ function mp3Ast() {
386879
387102
  return false;
386880
387103
  },
386881
387104
  parse(bytes) {
386882
- const numFrames = Math.max(1, Math.floor(bytes.byteLength / 417));
386883
- const samples = [];
386884
- for (let i = 0; i < numFrames; i++) {
386885
- const start = Math.min(bytes.byteLength, i * 417);
386886
- const end = Math.min(bytes.byteLength, start + 417);
386887
- samples.push({
386888
- data: bytes.subarray(start, end),
386889
- dts: i * 1152,
386890
- pts: i * 1152,
387105
+ const frames = readMp3Frames(bytes);
387106
+ let pts = 0;
387107
+ const samples = frames.map((frame) => {
387108
+ const duration = frame.samples * 14112e3 / frame.sampleRate;
387109
+ const sample = {
387110
+ data: bytes.subarray(frame.offset, frame.offset + frame.size),
387111
+ dts: pts,
387112
+ pts,
386891
387113
  cts: 0,
386892
- duration: 1152,
386893
- size: end - start,
387114
+ duration,
387115
+ size: frame.size,
386894
387116
  isKeyframe: true,
386895
387117
  sampleDescriptionIndex: 1
386896
- });
386897
- }
386898
- return mp3Document(bytes.byteLength, samples);
387118
+ };
387119
+ pts += duration;
387120
+ return sample;
387121
+ });
387122
+ return mp3Document(bytes.byteLength, frames, samples);
386899
387123
  },
386900
387124
  serialize(doc) {
386901
387125
  const numFrames = Math.max(1, Math.ceil((doc.durationSeconds || 1) * 44100 / 1152));
@@ -386906,13 +387130,13 @@ function mp3Ast() {
386906
387130
  frame[3] = 0;
386907
387131
  return concatBytes(Array.from({ length: numFrames }, () => frame));
386908
387132
  },
386909
- probe(bytes, options) {
386910
- const doc = this.parse(bytes, options);
386911
- return buildProbeResultFromDoc(doc, bytes.byteLength, options?.filename ?? "input.mp3", {
386912
- ...options,
386913
- formatName: "mp3",
386914
- formatLongName: "MP2/3 (MPEG audio layer 2/3)"
386915
- });
387133
+ probe(bytes, options = {}) {
387134
+ const result = mp3Records(bytes.length, readMp3Frames(bytes), options);
387135
+ return {
387136
+ ...result,
387137
+ packets: result.packets ? Array.from(result.packets) : void 0,
387138
+ frames: result.frames ? Array.from(result.frames) : void 0
387139
+ };
386916
387140
  },
386917
387141
  concat(docs, options) {
386918
387142
  return concatMp4(docs, options);
@@ -386977,42 +387201,61 @@ function flacDocument(bytes, byteLength, data = new Uint8Array()) {
386977
387201
  byteLength
386978
387202
  };
386979
387203
  }
387204
+ function flacProbe(scanner, options = {}) {
387205
+ const doc = flacDocument(scanner.header.subarray(0, Math.min(42, scanner.size)), scanner.size);
387206
+ const samples = scanner.packets.map((packet) => ({
387207
+ ...packet,
387208
+ dts: packet.pts,
387209
+ cts: 0,
387210
+ data: new Uint8Array(),
387211
+ isKeyframe: true,
387212
+ sampleDescriptionIndex: 1
387213
+ }));
387214
+ const result = buildProbeResultFromDoc(
387215
+ { ...doc, tracks: [{ ...doc.tracks[0], samples }] },
387216
+ scanner.size,
387217
+ options.filename ?? "input.flac",
387218
+ { ...options, formatName: "flac", formatLongName: "raw FLAC" }
387219
+ );
387220
+ return {
387221
+ ...result,
387222
+ streams: result.streams.map((stream) => ({
387223
+ ...stream,
387224
+ nb_frames: void 0,
387225
+ nb_read_packets: String(samples.length),
387226
+ nb_read_frames: String(samples.length)
387227
+ })),
387228
+ packets: result.packets?.map((packet, index) => ({ ...packet, pos: String(scanner.packets[index].pos) }))
387229
+ };
387230
+ }
386980
387231
  function flacAst() {
386981
387232
  return {
386982
387233
  async probeMetadata(source, options = {}) {
386983
387234
  options.signal?.throwIfAborted();
386984
387235
  if (!Number.isSafeInteger(source.size) || source.size < 0) throw new RangeError("Invalid FLAC source size");
386985
- const header = new Uint8Array(Math.min(42, source.size));
386986
- for (let offset = 0; offset < header.length; ) {
386987
- const chunk = await source.read(offset, header.length - offset);
387236
+ const scanner = new FlacFrameScanner();
387237
+ while (scanner.size < source.size) {
387238
+ const length = Math.min(16384, source.size - scanner.size);
387239
+ const chunk = await source.read(scanner.size, length);
386988
387240
  options.signal?.throwIfAborted();
386989
387241
  if (!chunk.length) throw new Error("Unexpected end of FLAC source");
386990
- if (chunk.length > header.length - offset) throw new Error("FLAC source returned more bytes than requested");
386991
- header.set(chunk, offset);
386992
- offset += chunk.length;
387242
+ if (chunk.length > length) throw new Error("FLAC source returned more bytes than requested");
387243
+ scanner.push(chunk);
386993
387244
  }
386994
- return buildProbeResultFromDoc(flacDocument(header, source.size), source.size, options.filename ?? "input.flac", {
386995
- ...options,
386996
- formatName: "flac",
386997
- formatLongName: "raw FLAC"
386998
- });
387245
+ scanner.push(new Uint8Array(), true);
387246
+ return flacProbe(scanner, options);
386999
387247
  },
387000
387248
  async probeMetadataStream(source, options = {}) {
387001
387249
  options.signal?.throwIfAborted();
387002
- const header = new Uint8Array(42);
387003
- let size = 0;
387250
+ const scanner = new FlacFrameScanner();
387004
387251
  for await (const chunk of source) {
387005
387252
  options.signal?.throwIfAborted();
387006
- if (size < header.length) header.set(chunk.subarray(0, header.length - size), size);
387007
- size += chunk.length;
387008
- if (!Number.isSafeInteger(size)) throw new RangeError("Invalid FLAC source size");
387253
+ scanner.push(chunk);
387254
+ if (!Number.isSafeInteger(scanner.size)) throw new RangeError("Invalid FLAC source size");
387009
387255
  }
387010
387256
  options.signal?.throwIfAborted();
387011
- return buildProbeResultFromDoc(flacDocument(header.subarray(0, Math.min(size, header.length)), size), size, options.filename ?? "input.flac", {
387012
- ...options,
387013
- formatName: "flac",
387014
- formatLongName: "raw FLAC"
387015
- });
387257
+ scanner.push(new Uint8Array(), true);
387258
+ return flacProbe(scanner, options);
387016
387259
  },
387017
387260
  id: "flac",
387018
387261
  formatName: "flac",
@@ -387037,12 +387280,9 @@ function flacAst() {
387037
387280
  return concatBytes(encodeFlacPackets(doc));
387038
387281
  },
387039
387282
  probe(bytes, options) {
387040
- const doc = this.parse(bytes, options);
387041
- return buildProbeResultFromDoc(doc, bytes.byteLength, options?.filename ?? "input.flac", {
387042
- ...options,
387043
- formatName: "flac",
387044
- formatLongName: "raw FLAC"
387045
- });
387283
+ const scanner = new FlacFrameScanner();
387284
+ scanner.push(bytes, true);
387285
+ return flacProbe(scanner, options);
387046
387286
  },
387047
387287
  concat(docs, options) {
387048
387288
  return concatMp4(docs, options);
@@ -387269,7 +387509,7 @@ function gifAst() {
387269
387509
  enabled: true,
387270
387510
  width,
387271
387511
  height,
387272
- codecDescriptions: [{ formatFourCC: "gif ", codecName: "gif", width, height, pixFmt: "rgb8" }],
387512
+ codecDescriptions: [{ formatFourCC: "gif ", codecName: "gif", width, height, pixFmt: "bgra" }],
387273
387513
  samples,
387274
387514
  decodedVideoFrames: frames
387275
387515
  }],
@@ -387299,11 +387539,28 @@ function gifAst() {
387299
387539
  },
387300
387540
  probe(bytes, options) {
387301
387541
  const doc = this.parse(bytes, options);
387302
- return buildProbeResultFromDoc(doc, bytes.byteLength, options?.filename ?? "input.gif", {
387542
+ const result = buildProbeResultFromDoc(doc, bytes.byteLength, options?.filename ?? "input.gif", {
387303
387543
  ...options,
387304
387544
  formatName: "gif",
387305
387545
  formatLongName: "CompuServe Graphics Interchange Format (GIF)"
387306
387546
  });
387547
+ const track = doc.tracks[0];
387548
+ const stream = result.streams[0];
387549
+ if (track.samples.length > 1) {
387550
+ const averageDelay = Math.floor(track.duration / track.samples.length);
387551
+ const averageDivisor = gcd(track.timescale, averageDelay);
387552
+ let interval = 0;
387553
+ for (let index = 1; index < track.samples.length; index++) {
387554
+ interval = gcd(interval, track.samples[index].dts - track.samples[index - 1].dts);
387555
+ }
387556
+ const nominalDivisor = gcd(track.timescale, interval);
387557
+ return { ...result, streams: [{
387558
+ ...stream,
387559
+ avg_frame_rate: `${track.timescale / averageDivisor}/${averageDelay / averageDivisor}`,
387560
+ r_frame_rate: `${track.timescale / nominalDivisor}/${interval / nominalDivisor}`
387561
+ }] };
387562
+ }
387563
+ return result;
387307
387564
  },
387308
387565
  concat(docs, options) {
387309
387566
  return concatMp4(docs, options);
@@ -388114,9 +388371,9 @@ async function* scanMp4CodecDescriptions(source, range, options = {}) {
388114
388371
  async function* scanMp4Packets(source, options = {}) {
388115
388372
  for await (const record of scanProbeRecords(source, options, "packets")) {
388116
388373
  if (!("sample" in record)) continue;
388117
- const { sample, track, bytePos } = record;
388374
+ const { sample, track } = record;
388118
388375
  const scale = Math.max(1, track.timescale);
388119
- yield { codec_type: track.type, stream_index: track.index, pts: sample.pts, pts_time: (sample.pts / scale).toFixed(6), dts: sample.dts, dts_time: (sample.dts / scale).toFixed(6), duration: sample.duration, duration_time: (sample.duration / scale).toFixed(6), size: String(sample.size), pos: String(bytePos), flags: sample.isKeyframe ? "K_" : "__" };
388376
+ yield { codec_type: track.type, stream_index: track.index, pts: sample.pts, pts_time: (sample.pts / scale).toFixed(6), dts: sample.dts, dts_time: (sample.dts / scale).toFixed(6), duration: sample.duration, duration_time: (sample.duration / scale).toFixed(6), size: String(sample.size), pos: String(sample.offset), flags: sample.isKeyframe ? "K__" : "___" };
388120
388377
  }
388121
388378
  }
388122
388379
  async function* scanMp4Frames(source, options = {}) {
@@ -388140,7 +388397,7 @@ async function* scanMp4Frames(source, options = {}) {
388140
388397
  width: track.width,
388141
388398
  height: track.height,
388142
388399
  pix_fmt: track.type === "video" ? track.codec?.pixFmt ?? "yuv420p" : void 0,
388143
- pict_type: track.type === "video" ? sample.isKeyframe ? "I" : "P" : void 0,
388400
+ pict_type: void 0,
388144
388401
  sample_fmt: probeSampleFormat(track.type, track.codec?.codecName ?? (track.type === "video" ? "h264" : "aac")),
388145
388402
  nb_samples: track.type === "audio" ? sample.duration : void 0,
388146
388403
  channels: track.type === "audio" ? track.codec?.channels ?? 2 : void 0
@@ -388266,11 +388523,16 @@ async function* scanProbeRecords(source, options, mode) {
388266
388523
  }
388267
388524
  }
388268
388525
  let duration = 0, mediaEnd = 0, allPacked = true, count = 0, firstPts = 0;
388526
+ let highestPts = -Infinity, reorderSpan = 0;
388269
388527
  for await (const sample of samples()) {
388270
388528
  if (!count) firstPts = sample.pts;
388271
388529
  count++;
388272
388530
  duration += sample.duration;
388273
388531
  mediaEnd = Math.max(mediaEnd, sample.pts + sample.duration);
388532
+ if (mode === "frames" && type === "video") {
388533
+ highestPts = Math.max(highestPts, sample.pts);
388534
+ reorderSpan = Math.max(reorderSpan, highestPts - sample.pts);
388535
+ }
388274
388536
  if (type === "subtitle" && allPacked) {
388275
388537
  if (sample.size < 2) allPacked = false;
388276
388538
  else allPacked = new BinaryReader(await readMp4SampleRange(source, sample.offset, 2, work)).readU16BE() === sample.size - 2;
@@ -388283,18 +388545,20 @@ async function* scanProbeRecords(source, options, mode) {
388283
388545
  const version = header2.readU8();
388284
388546
  header2.skip(3);
388285
388547
  const count2 = header2.readU32BE(), width2 = version === 1 ? 20 : 12;
388286
- let total = 0, entries = 0, delay = 0, foundMedia = false;
388548
+ let total = 0, entries = 0, delay = 0, mediaStart = 0, foundMedia = false;
388287
388549
  for (let i = 0; i < count2 && 8 + i * width2 < elst.payloadSize; i++) {
388288
388550
  const row = new BinaryReader(yield { kind: "read", table: elst, offset: elst.payloadOffset + 8 + i * width2, length: Math.min(width2, elst.payloadSize - 8 - i * width2) });
388289
388551
  let segment = version === 1 ? row.readU64BE() : row.readU32BE();
388290
388552
  const mediaTime = version === 1 ? row.readI64BE() : row.readI32BE();
388291
388553
  if (fragmented && segment === 0 && mediaTime >= 0) segment = Math.round(Math.max(0, mediaEnd - mediaTime) * movieTimescale / timescale);
388292
- if (mediaTime >= 0) foundMedia = true;
388293
- else if (!foundMedia) delay += segment;
388554
+ if (mediaTime >= 0 && !foundMedia) {
388555
+ mediaStart = mediaTime;
388556
+ foundMedia = true;
388557
+ } else if (!foundMedia) delay += segment;
388294
388558
  total += segment;
388295
388559
  entries++;
388296
388560
  }
388297
- return entries ? { duration: Math.round(total * timescale / movieTimescale), start: Math.round(delay * timescale / movieTimescale) } : void 0;
388561
+ return entries ? { duration: Math.round(total * timescale / movieTimescale), start: Math.round(delay * timescale / movieTimescale), mediaStart } : void 0;
388298
388562
  }
388299
388563
  const edits = consumeMp4SampleSteps(source, editDuration(), sampleOptions), result = await edits.next();
388300
388564
  if (!result.done) throw new Error("Unexpected MP4 edit sample");
@@ -388307,7 +388571,8 @@ async function* scanProbeRecords(source, options, mode) {
388307
388571
  formatStart = Math.min(formatStart, start);
388308
388572
  formatEnd = Math.max(formatEnd, start + probeDuration / Math.max(1, timescale));
388309
388573
  if (mode === "summary") continue;
388310
- let bytePos = 0, cursor = 0, previousPts = -Infinity;
388574
+ const timestampOffset = result.value ? result.value.start - result.value.mediaStart : 0;
388575
+ let cursor = 0, previousPts = -Infinity;
388311
388576
  const stats = { totalBytes: 0, count: 0, ticks: 0, firstPts: startPts, hasReorderedSamples: false };
388312
388577
  const packet = (sample) => {
388313
388578
  if (mode === "streams") {
@@ -388317,11 +388582,34 @@ async function* scanProbeRecords(source, options, mode) {
388317
388582
  stats.hasReorderedSamples ||= sample.pts < previousPts;
388318
388583
  previousPts = sample.pts;
388319
388584
  }
388320
- const record = { sample, track, bytePos };
388321
- bytePos += sample.size;
388322
- return record;
388585
+ return { sample, track };
388323
388586
  };
388324
- for await (const sample of samples()) {
388587
+ async function* frameSamples() {
388588
+ const pending = [];
388589
+ let highest = -Infinity;
388590
+ try {
388591
+ for await (const sample of samples()) {
388592
+ highest = Math.max(highest, sample.pts);
388593
+ const index2 = pending.findIndex((row) => row.pts <= sample.pts);
388594
+ pending.splice(index2 < 0 ? pending.length : index2, 0, sample);
388595
+ budget.allocateMemory(128);
388596
+ while (pending.length && pending[pending.length - 1].pts <= highest - reorderSpan) {
388597
+ const next = pending.pop();
388598
+ budget.releaseMemory(128);
388599
+ yield next;
388600
+ }
388601
+ }
388602
+ while (pending.length) {
388603
+ const next = pending.pop();
388604
+ budget.releaseMemory(128);
388605
+ yield next;
388606
+ }
388607
+ } finally {
388608
+ budget.releaseMemory(pending.length * 128);
388609
+ }
388610
+ }
388611
+ for await (const rawSample of reorderSpan > 0 ? frameSamples() : samples()) {
388612
+ const sample = { ...rawSample, pts: rawSample.pts + timestampOffset, dts: rawSample.dts + timestampOffset };
388325
388613
  if (type !== "subtitle" || !count || allPacked) {
388326
388614
  const row2 = packet(sample);
388327
388615
  if (mode !== "streams") yield row2;
@@ -388329,12 +388617,12 @@ async function* scanProbeRecords(source, options, mode) {
388329
388617
  }
388330
388618
  const start2 = Math.max(cursor, Math.round(sample.pts));
388331
388619
  if (start2 > cursor) {
388332
- const row2 = packet({ pts: cursor, dts: cursor, duration: start2 - cursor, size: 2, isKeyframe: true });
388620
+ const row2 = packet({ offset: -1, pts: cursor, dts: cursor, duration: start2 - cursor, size: 2, isKeyframe: true });
388333
388621
  if (mode !== "streams") yield row2;
388334
388622
  cursor = start2;
388335
388623
  }
388336
388624
  const duration2 = Math.max(1, Math.round(sample.duration));
388337
- const row = packet({ pts: cursor, dts: cursor, duration: duration2, size: sample.size + 2, isKeyframe: true });
388625
+ const row = packet({ offset: sample.offset, pts: cursor, dts: cursor, duration: duration2, size: sample.size + 2, isKeyframe: true });
388338
388626
  if (mode !== "streams") yield row;
388339
388627
  cursor += duration2;
388340
388628
  }
@@ -388387,6 +388675,7 @@ export {
388387
388675
  createSyntheticMp4,
388388
388676
  parseStreamingManifest,
388389
388677
  serializeDashDocument,
388678
+ wavPacketFrames,
388390
388679
  probeOggStreamMetadata,
388391
388680
  probeOggFlacSource,
388392
388681
  parseSubtitleDocument,