@poe-platform/safe-bash 0.1.840 → 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.
- package/dist/audio-ast/binary.d.ts +19 -0
- package/dist/audio-ast/index.d.ts +1 -0
- package/dist/audio-ast/index.js +92 -91
- package/dist/audio-ast/mpeg.d.ts +23 -0
- package/dist/mp4-ast/containers/adapters.d.ts +1 -0
- package/dist/mp4-ast/types.d.ts +4 -0
- package/dist/safe-bash/audio-ast.browser.js +2 -1
- package/dist/safe-bash/audio-ast.js +1 -1
- package/dist/safe-bash/command-chunks/{chunk-45ZH6CNF.js → chunk-BZW25LNV.js} +400 -127
- package/dist/safe-bash/command-chunks/{chunk-YVFQ5I36.js → chunk-CIV3GER2.js} +3458 -3384
- package/dist/safe-bash/command-chunks/{chunk-T5WFJ44Z.js → chunk-YAXP4EHP.js} +19 -10
- package/dist/safe-bash-command-ffmpeg/index.js +28 -19
- package/dist/safe-bash-command-ffprobe/index.js +2 -2
- package/dist/safe-bash-command-ffprobe/media.js +2 -2
- package/dist/safe-bash-command-imagemagick/index.js +16 -3
- package/dist/safe-bash-command-pandoc/command.js +6 -6
- package/dist/safe-bash-command-pandoc/index.js +37 -37
- package/package.json +2 -2
|
@@ -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 ? "
|
|
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) {
|
|
@@ -383223,7 +383223,7 @@ function buildProbeResultFromDoc(doc, byteLength, filename = "input.mp4", option
|
|
|
383223
383223
|
width: w,
|
|
383224
383224
|
height: h,
|
|
383225
383225
|
pix_fmt: track.type === "video" ? desc?.pixFmt ?? "yuv420p" : void 0,
|
|
383226
|
-
pict_type:
|
|
383226
|
+
pict_type: void 0,
|
|
383227
383227
|
sample_fmt: sampleFormat,
|
|
383228
383228
|
nb_samples: track.type === "audio" ? s.duration : void 0,
|
|
383229
383229
|
channels: track.type === "audio" ? desc?.channels ?? 2 : void 0
|
|
@@ -384266,6 +384266,132 @@ function serializeDashDocument(doc, options = {}) {
|
|
|
384266
384266
|
return { manifest, resources };
|
|
384267
384267
|
}
|
|
384268
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
|
+
|
|
384269
384395
|
// packages/mp4-ast/src/aac.ts
|
|
384270
384396
|
function decodeAacTrack(doc, track) {
|
|
384271
384397
|
const description = track.codecDescriptions[0];
|
|
@@ -384513,6 +384639,101 @@ function encodeFlacPackets(doc) {
|
|
|
384513
384639
|
return frames;
|
|
384514
384640
|
}
|
|
384515
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
|
+
|
|
384516
384737
|
// packages/mp4-ast/src/containers/ogg.ts
|
|
384517
384738
|
function page(packet, sequence, flags, granule) {
|
|
384518
384739
|
const segments = Math.floor(packet.length / 255) + 1;
|
|
@@ -384633,7 +384854,7 @@ async function readOggFlacHeader(source, options = {}) {
|
|
|
384633
384854
|
const start = offset, header = await read(27);
|
|
384634
384855
|
if (header[0] !== 79 || header[1] !== 103 || header[2] !== 103 || header[3] !== 83) throw new Error("Invalid Ogg page");
|
|
384635
384856
|
const lacing = await read(header[26]);
|
|
384636
|
-
let
|
|
384857
|
+
let checksum2 = oggCrc(lacing, oggCrc(header), 27);
|
|
384637
384858
|
const continuation = Boolean(header[5] & 1) !== packetSize > 0;
|
|
384638
384859
|
let remaining = 0, chunk = new Uint8Array(), used = 0;
|
|
384639
384860
|
for (const length of lacing) remaining += length;
|
|
@@ -384642,7 +384863,7 @@ async function readOggFlacHeader(source, options = {}) {
|
|
|
384642
384863
|
if (used === chunk.length) {
|
|
384643
384864
|
chunk = await read(Math.min(16384, remaining));
|
|
384644
384865
|
used = 0;
|
|
384645
|
-
|
|
384866
|
+
checksum2 = oggCrc(chunk, checksum2, offset - start - chunk.length);
|
|
384646
384867
|
remaining -= chunk.length;
|
|
384647
384868
|
}
|
|
384648
384869
|
const take = Math.min(pending, chunk.length - used);
|
|
@@ -384660,7 +384881,7 @@ async function readOggFlacHeader(source, options = {}) {
|
|
|
384660
384881
|
packetSize = 0;
|
|
384661
384882
|
}
|
|
384662
384883
|
}
|
|
384663
|
-
if (
|
|
384884
|
+
if (checksum2 !== new DataView(header.buffer).getUint32(22, true)) throw new Error("Ogg CRC mismatch");
|
|
384664
384885
|
if (continuation) throw new Error("Invalid Ogg packet continuation");
|
|
384665
384886
|
if (firstSize >= 0 && !mapped) return void 0;
|
|
384666
384887
|
}
|
|
@@ -386508,7 +386729,10 @@ function aacAst() {
|
|
|
386508
386729
|
function isWavSignature(bytes) {
|
|
386509
386730
|
return bytes.byteLength >= 12 && decodeFourCC(bytes, 0) === "RIFF" && decodeFourCC(bytes, 8) === "WAVE";
|
|
386510
386731
|
}
|
|
386511
|
-
|
|
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
|
+
}
|
|
386512
386736
|
function parseWav(bytes, options = {}) {
|
|
386513
386737
|
const header = readWavHeader(bytes);
|
|
386514
386738
|
const { formatTag, channels, sampleRate, bitsPerSample } = header;
|
|
@@ -386539,7 +386763,7 @@ function parseWav(bytes, options = {}) {
|
|
|
386539
386763
|
decodedAudio = { sampleRate, channels, channelData };
|
|
386540
386764
|
}
|
|
386541
386765
|
const samples = [];
|
|
386542
|
-
const chunkFrames = wavPacketFrames;
|
|
386766
|
+
const chunkFrames = wavPacketFrames(header.sampleRate, bytesPerFrame);
|
|
386543
386767
|
for (let offsetSample = 0; offsetSample < totalPcmSamples; offsetSample += chunkFrames) {
|
|
386544
386768
|
const count = Math.min(chunkFrames, totalPcmSamples - offsetSample);
|
|
386545
386769
|
const byteStart = offsetSample * bytesPerFrame;
|
|
@@ -386642,7 +386866,6 @@ function wavMetadata(header, filename = "input.wav") {
|
|
|
386642
386866
|
const bytesPerFrame = Math.max(1, header.channels * (header.bitsPerSample >>> 3));
|
|
386643
386867
|
return { ...result, streams: [{
|
|
386644
386868
|
...result.streams[0],
|
|
386645
|
-
nb_frames: String(Math.ceil(samples / wavPacketFrames)),
|
|
386646
386869
|
bit_rate: doc.durationSeconds > 0 ? String(Math.round(samples * bytesPerFrame * 8 / doc.durationSeconds)) : "0"
|
|
386647
386870
|
}] };
|
|
386648
386871
|
}
|
|
@@ -386650,10 +386873,11 @@ function wavRecords(header, options) {
|
|
|
386650
386873
|
const metadata = wavMetadata(header, options.filename), stream = metadata.streams[0];
|
|
386651
386874
|
const bytesPerFrame = Math.max(1, header.channels * (header.bitsPerSample >>> 3));
|
|
386652
386875
|
const samples = Math.floor(header.dataSize / bytesPerFrame), rate = Math.max(1, header.sampleRate);
|
|
386876
|
+
const chunkFrames = wavPacketFrames(header.sampleRate, bytesPerFrame);
|
|
386653
386877
|
function* spans() {
|
|
386654
|
-
for (let pts = 0; pts < samples; pts +=
|
|
386878
|
+
for (let pts = 0; pts < samples; pts += chunkFrames) {
|
|
386655
386879
|
options.signal?.throwIfAborted();
|
|
386656
|
-
const count = Math.min(
|
|
386880
|
+
const count = Math.min(chunkFrames, samples - pts);
|
|
386657
386881
|
yield { pts, count, size: String(count * bytesPerFrame), time: (pts / rate).toFixed(6), duration: (count / rate).toFixed(6) };
|
|
386658
386882
|
}
|
|
386659
386883
|
options.signal?.throwIfAborted();
|
|
@@ -386672,7 +386896,7 @@ function wavRecords(header, options) {
|
|
|
386672
386896
|
duration_time: s.duration,
|
|
386673
386897
|
size: s.size,
|
|
386674
386898
|
pos: String(s.pts * bytesPerFrame),
|
|
386675
|
-
flags: "
|
|
386899
|
+
flags: "K__"
|
|
386676
386900
|
};
|
|
386677
386901
|
} } : void 0,
|
|
386678
386902
|
frames: options.showFrames ? { *[Symbol.iterator]() {
|
|
@@ -386752,20 +386976,21 @@ function isMp3Signature(bytes) {
|
|
|
386752
386976
|
if (bytes[0] === 73 && bytes[1] === 68 && bytes[2] === 51) return true;
|
|
386753
386977
|
return bytes[0] === 255 && (bytes[1] & 224) === 224 && (bytes[1] & 6) !== 0;
|
|
386754
386978
|
}
|
|
386755
|
-
function mp3Document(byteLength, samples) {
|
|
386756
|
-
const sampleRate
|
|
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);
|
|
386757
386982
|
return {
|
|
386758
386983
|
containerFormat: "mp3",
|
|
386759
|
-
timescale:
|
|
386760
|
-
duration
|
|
386761
|
-
durationSeconds:
|
|
386984
|
+
timescale: 14112e3,
|
|
386985
|
+
duration,
|
|
386986
|
+
durationSeconds: duration / 14112e3,
|
|
386762
386987
|
tracks: [
|
|
386763
386988
|
{
|
|
386764
386989
|
id: 1,
|
|
386765
386990
|
type: "audio",
|
|
386766
386991
|
handlerType: "soun",
|
|
386767
|
-
timescale:
|
|
386768
|
-
duration
|
|
386992
|
+
timescale: 14112e3,
|
|
386993
|
+
duration,
|
|
386769
386994
|
language: "und",
|
|
386770
386995
|
enabled: true,
|
|
386771
386996
|
codecDescriptions: [
|
|
@@ -386784,24 +387009,27 @@ function mp3Document(byteLength, samples) {
|
|
|
386784
387009
|
byteLength
|
|
386785
387010
|
};
|
|
386786
387011
|
}
|
|
386787
|
-
function mp3Records(size, options) {
|
|
387012
|
+
function mp3Records(size, frames, options) {
|
|
386788
387013
|
options.signal?.throwIfAborted();
|
|
386789
|
-
|
|
386790
|
-
const count = Math.max(1, Math.floor(size / 417)), doc = mp3Document(size, []);
|
|
387014
|
+
const doc = mp3Document(size, frames, []);
|
|
386791
387015
|
const metadata = buildProbeResultFromDoc(doc, size, options.filename ?? "input.mp3", {
|
|
386792
387016
|
formatName: "mp3",
|
|
386793
387017
|
formatLongName: "MP2/3 (MPEG audio layer 2/3)"
|
|
386794
387018
|
});
|
|
386795
387019
|
const stream = {
|
|
386796
387020
|
...metadata.streams[0],
|
|
386797
|
-
nb_frames:
|
|
386798
|
-
|
|
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))
|
|
386799
387025
|
};
|
|
386800
387026
|
function* spans() {
|
|
386801
|
-
|
|
387027
|
+
let pts = 0;
|
|
387028
|
+
for (const frame of frames) {
|
|
386802
387029
|
options.signal?.throwIfAborted();
|
|
386803
|
-
const
|
|
386804
|
-
yield { pts, time: (pts /
|
|
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;
|
|
386805
387033
|
}
|
|
386806
387034
|
options.signal?.throwIfAborted();
|
|
386807
387035
|
}
|
|
@@ -386816,52 +387044,48 @@ function mp3Records(size, options) {
|
|
|
386816
387044
|
pts_time: s.time,
|
|
386817
387045
|
dts: s.pts,
|
|
386818
387046
|
dts_time: s.time,
|
|
386819
|
-
duration:
|
|
386820
|
-
duration_time:
|
|
386821
|
-
size: s.size,
|
|
386822
|
-
pos: s.
|
|
386823
|
-
flags: "
|
|
387047
|
+
duration: s.duration,
|
|
387048
|
+
duration_time: s.durationTime,
|
|
387049
|
+
size: String(s.size),
|
|
387050
|
+
pos: String(s.offset),
|
|
387051
|
+
flags: "K__"
|
|
386824
387052
|
};
|
|
386825
387053
|
} } : void 0,
|
|
386826
387054
|
frames: options.showFrames ? { *[Symbol.iterator]() {
|
|
386827
|
-
for (const s of spans())
|
|
386828
|
-
|
|
386829
|
-
|
|
386830
|
-
|
|
386831
|
-
|
|
386832
|
-
|
|
386833
|
-
|
|
386834
|
-
|
|
386835
|
-
|
|
386836
|
-
|
|
386837
|
-
|
|
386838
|
-
|
|
386839
|
-
|
|
386840
|
-
|
|
386841
|
-
|
|
386842
|
-
|
|
386843
|
-
|
|
386844
|
-
|
|
386845
|
-
|
|
386846
|
-
|
|
386847
|
-
|
|
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
|
+
}
|
|
386848
387078
|
} } : void 0
|
|
386849
387079
|
};
|
|
386850
387080
|
}
|
|
386851
387081
|
function mp3Ast() {
|
|
386852
387082
|
return {
|
|
386853
387083
|
async probeMetadata(source, options = {}) {
|
|
386854
|
-
return mp3Records(source.size, options);
|
|
387084
|
+
return mp3Records(source.size, await readMp3SourceFrames(source, options.signal), options);
|
|
386855
387085
|
},
|
|
386856
387086
|
async probeMetadataStream(source, options = {}) {
|
|
386857
|
-
options.signal
|
|
386858
|
-
|
|
386859
|
-
for await (const chunk of source) {
|
|
386860
|
-
options.signal?.throwIfAborted();
|
|
386861
|
-
size += chunk.byteLength;
|
|
386862
|
-
if (!Number.isSafeInteger(size)) throw new RangeError("Invalid MP3 source size");
|
|
386863
|
-
}
|
|
386864
|
-
return mp3Records(size, options);
|
|
387087
|
+
const { frames, size } = await readMp3StreamFrames(source, options.signal);
|
|
387088
|
+
return mp3Records(size, frames, options);
|
|
386865
387089
|
},
|
|
386866
387090
|
id: "mp3",
|
|
386867
387091
|
formatName: "mp3",
|
|
@@ -386878,23 +387102,24 @@ function mp3Ast() {
|
|
|
386878
387102
|
return false;
|
|
386879
387103
|
},
|
|
386880
387104
|
parse(bytes) {
|
|
386881
|
-
const
|
|
386882
|
-
|
|
386883
|
-
|
|
386884
|
-
const
|
|
386885
|
-
const
|
|
386886
|
-
|
|
386887
|
-
|
|
386888
|
-
|
|
386889
|
-
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,
|
|
386890
387113
|
cts: 0,
|
|
386891
|
-
duration
|
|
386892
|
-
size:
|
|
387114
|
+
duration,
|
|
387115
|
+
size: frame.size,
|
|
386893
387116
|
isKeyframe: true,
|
|
386894
387117
|
sampleDescriptionIndex: 1
|
|
386895
|
-
}
|
|
386896
|
-
|
|
386897
|
-
|
|
387118
|
+
};
|
|
387119
|
+
pts += duration;
|
|
387120
|
+
return sample;
|
|
387121
|
+
});
|
|
387122
|
+
return mp3Document(bytes.byteLength, frames, samples);
|
|
386898
387123
|
},
|
|
386899
387124
|
serialize(doc) {
|
|
386900
387125
|
const numFrames = Math.max(1, Math.ceil((doc.durationSeconds || 1) * 44100 / 1152));
|
|
@@ -386905,13 +387130,13 @@ function mp3Ast() {
|
|
|
386905
387130
|
frame[3] = 0;
|
|
386906
387131
|
return concatBytes(Array.from({ length: numFrames }, () => frame));
|
|
386907
387132
|
},
|
|
386908
|
-
probe(bytes, options) {
|
|
386909
|
-
const
|
|
386910
|
-
return
|
|
386911
|
-
...
|
|
386912
|
-
|
|
386913
|
-
|
|
386914
|
-
}
|
|
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
|
+
};
|
|
386915
387140
|
},
|
|
386916
387141
|
concat(docs, options) {
|
|
386917
387142
|
return concatMp4(docs, options);
|
|
@@ -386976,42 +387201,61 @@ function flacDocument(bytes, byteLength, data = new Uint8Array()) {
|
|
|
386976
387201
|
byteLength
|
|
386977
387202
|
};
|
|
386978
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
|
+
}
|
|
386979
387231
|
function flacAst() {
|
|
386980
387232
|
return {
|
|
386981
387233
|
async probeMetadata(source, options = {}) {
|
|
386982
387234
|
options.signal?.throwIfAborted();
|
|
386983
387235
|
if (!Number.isSafeInteger(source.size) || source.size < 0) throw new RangeError("Invalid FLAC source size");
|
|
386984
|
-
const
|
|
386985
|
-
|
|
386986
|
-
const
|
|
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);
|
|
386987
387240
|
options.signal?.throwIfAborted();
|
|
386988
387241
|
if (!chunk.length) throw new Error("Unexpected end of FLAC source");
|
|
386989
|
-
if (chunk.length >
|
|
386990
|
-
|
|
386991
|
-
offset += chunk.length;
|
|
387242
|
+
if (chunk.length > length) throw new Error("FLAC source returned more bytes than requested");
|
|
387243
|
+
scanner.push(chunk);
|
|
386992
387244
|
}
|
|
386993
|
-
|
|
386994
|
-
|
|
386995
|
-
formatName: "flac",
|
|
386996
|
-
formatLongName: "raw FLAC"
|
|
386997
|
-
});
|
|
387245
|
+
scanner.push(new Uint8Array(), true);
|
|
387246
|
+
return flacProbe(scanner, options);
|
|
386998
387247
|
},
|
|
386999
387248
|
async probeMetadataStream(source, options = {}) {
|
|
387000
387249
|
options.signal?.throwIfAborted();
|
|
387001
|
-
const
|
|
387002
|
-
let size = 0;
|
|
387250
|
+
const scanner = new FlacFrameScanner();
|
|
387003
387251
|
for await (const chunk of source) {
|
|
387004
387252
|
options.signal?.throwIfAborted();
|
|
387005
|
-
|
|
387006
|
-
size
|
|
387007
|
-
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");
|
|
387008
387255
|
}
|
|
387009
387256
|
options.signal?.throwIfAborted();
|
|
387010
|
-
|
|
387011
|
-
|
|
387012
|
-
formatName: "flac",
|
|
387013
|
-
formatLongName: "raw FLAC"
|
|
387014
|
-
});
|
|
387257
|
+
scanner.push(new Uint8Array(), true);
|
|
387258
|
+
return flacProbe(scanner, options);
|
|
387015
387259
|
},
|
|
387016
387260
|
id: "flac",
|
|
387017
387261
|
formatName: "flac",
|
|
@@ -387036,12 +387280,9 @@ function flacAst() {
|
|
|
387036
387280
|
return concatBytes(encodeFlacPackets(doc));
|
|
387037
387281
|
},
|
|
387038
387282
|
probe(bytes, options) {
|
|
387039
|
-
const
|
|
387040
|
-
|
|
387041
|
-
|
|
387042
|
-
formatName: "flac",
|
|
387043
|
-
formatLongName: "raw FLAC"
|
|
387044
|
-
});
|
|
387283
|
+
const scanner = new FlacFrameScanner();
|
|
387284
|
+
scanner.push(bytes, true);
|
|
387285
|
+
return flacProbe(scanner, options);
|
|
387045
387286
|
},
|
|
387046
387287
|
concat(docs, options) {
|
|
387047
387288
|
return concatMp4(docs, options);
|
|
@@ -388130,9 +388371,9 @@ async function* scanMp4CodecDescriptions(source, range, options = {}) {
|
|
|
388130
388371
|
async function* scanMp4Packets(source, options = {}) {
|
|
388131
388372
|
for await (const record of scanProbeRecords(source, options, "packets")) {
|
|
388132
388373
|
if (!("sample" in record)) continue;
|
|
388133
|
-
const { sample, track
|
|
388374
|
+
const { sample, track } = record;
|
|
388134
388375
|
const scale = Math.max(1, track.timescale);
|
|
388135
|
-
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(
|
|
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__" : "___" };
|
|
388136
388377
|
}
|
|
388137
388378
|
}
|
|
388138
388379
|
async function* scanMp4Frames(source, options = {}) {
|
|
@@ -388156,7 +388397,7 @@ async function* scanMp4Frames(source, options = {}) {
|
|
|
388156
388397
|
width: track.width,
|
|
388157
388398
|
height: track.height,
|
|
388158
388399
|
pix_fmt: track.type === "video" ? track.codec?.pixFmt ?? "yuv420p" : void 0,
|
|
388159
|
-
pict_type:
|
|
388400
|
+
pict_type: void 0,
|
|
388160
388401
|
sample_fmt: probeSampleFormat(track.type, track.codec?.codecName ?? (track.type === "video" ? "h264" : "aac")),
|
|
388161
388402
|
nb_samples: track.type === "audio" ? sample.duration : void 0,
|
|
388162
388403
|
channels: track.type === "audio" ? track.codec?.channels ?? 2 : void 0
|
|
@@ -388282,11 +388523,16 @@ async function* scanProbeRecords(source, options, mode) {
|
|
|
388282
388523
|
}
|
|
388283
388524
|
}
|
|
388284
388525
|
let duration = 0, mediaEnd = 0, allPacked = true, count = 0, firstPts = 0;
|
|
388526
|
+
let highestPts = -Infinity, reorderSpan = 0;
|
|
388285
388527
|
for await (const sample of samples()) {
|
|
388286
388528
|
if (!count) firstPts = sample.pts;
|
|
388287
388529
|
count++;
|
|
388288
388530
|
duration += sample.duration;
|
|
388289
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
|
+
}
|
|
388290
388536
|
if (type === "subtitle" && allPacked) {
|
|
388291
388537
|
if (sample.size < 2) allPacked = false;
|
|
388292
388538
|
else allPacked = new BinaryReader(await readMp4SampleRange(source, sample.offset, 2, work)).readU16BE() === sample.size - 2;
|
|
@@ -388299,18 +388545,20 @@ async function* scanProbeRecords(source, options, mode) {
|
|
|
388299
388545
|
const version = header2.readU8();
|
|
388300
388546
|
header2.skip(3);
|
|
388301
388547
|
const count2 = header2.readU32BE(), width2 = version === 1 ? 20 : 12;
|
|
388302
|
-
let total = 0, entries = 0, delay = 0, foundMedia = false;
|
|
388548
|
+
let total = 0, entries = 0, delay = 0, mediaStart = 0, foundMedia = false;
|
|
388303
388549
|
for (let i = 0; i < count2 && 8 + i * width2 < elst.payloadSize; i++) {
|
|
388304
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) });
|
|
388305
388551
|
let segment = version === 1 ? row.readU64BE() : row.readU32BE();
|
|
388306
388552
|
const mediaTime = version === 1 ? row.readI64BE() : row.readI32BE();
|
|
388307
388553
|
if (fragmented && segment === 0 && mediaTime >= 0) segment = Math.round(Math.max(0, mediaEnd - mediaTime) * movieTimescale / timescale);
|
|
388308
|
-
if (mediaTime >= 0
|
|
388309
|
-
|
|
388554
|
+
if (mediaTime >= 0 && !foundMedia) {
|
|
388555
|
+
mediaStart = mediaTime;
|
|
388556
|
+
foundMedia = true;
|
|
388557
|
+
} else if (!foundMedia) delay += segment;
|
|
388310
388558
|
total += segment;
|
|
388311
388559
|
entries++;
|
|
388312
388560
|
}
|
|
388313
|
-
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;
|
|
388314
388562
|
}
|
|
388315
388563
|
const edits = consumeMp4SampleSteps(source, editDuration(), sampleOptions), result = await edits.next();
|
|
388316
388564
|
if (!result.done) throw new Error("Unexpected MP4 edit sample");
|
|
@@ -388323,7 +388571,8 @@ async function* scanProbeRecords(source, options, mode) {
|
|
|
388323
388571
|
formatStart = Math.min(formatStart, start);
|
|
388324
388572
|
formatEnd = Math.max(formatEnd, start + probeDuration / Math.max(1, timescale));
|
|
388325
388573
|
if (mode === "summary") continue;
|
|
388326
|
-
|
|
388574
|
+
const timestampOffset = result.value ? result.value.start - result.value.mediaStart : 0;
|
|
388575
|
+
let cursor = 0, previousPts = -Infinity;
|
|
388327
388576
|
const stats = { totalBytes: 0, count: 0, ticks: 0, firstPts: startPts, hasReorderedSamples: false };
|
|
388328
388577
|
const packet = (sample) => {
|
|
388329
388578
|
if (mode === "streams") {
|
|
@@ -388333,11 +388582,34 @@ async function* scanProbeRecords(source, options, mode) {
|
|
|
388333
388582
|
stats.hasReorderedSamples ||= sample.pts < previousPts;
|
|
388334
388583
|
previousPts = sample.pts;
|
|
388335
388584
|
}
|
|
388336
|
-
|
|
388337
|
-
bytePos += sample.size;
|
|
388338
|
-
return record;
|
|
388585
|
+
return { sample, track };
|
|
388339
388586
|
};
|
|
388340
|
-
|
|
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 };
|
|
388341
388613
|
if (type !== "subtitle" || !count || allPacked) {
|
|
388342
388614
|
const row2 = packet(sample);
|
|
388343
388615
|
if (mode !== "streams") yield row2;
|
|
@@ -388345,12 +388617,12 @@ async function* scanProbeRecords(source, options, mode) {
|
|
|
388345
388617
|
}
|
|
388346
388618
|
const start2 = Math.max(cursor, Math.round(sample.pts));
|
|
388347
388619
|
if (start2 > cursor) {
|
|
388348
|
-
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 });
|
|
388349
388621
|
if (mode !== "streams") yield row2;
|
|
388350
388622
|
cursor = start2;
|
|
388351
388623
|
}
|
|
388352
388624
|
const duration2 = Math.max(1, Math.round(sample.duration));
|
|
388353
|
-
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 });
|
|
388354
388626
|
if (mode !== "streams") yield row;
|
|
388355
388627
|
cursor += duration2;
|
|
388356
388628
|
}
|
|
@@ -388403,6 +388675,7 @@ export {
|
|
|
388403
388675
|
createSyntheticMp4,
|
|
388404
388676
|
parseStreamingManifest,
|
|
388405
388677
|
serializeDashDocument,
|
|
388678
|
+
wavPacketFrames,
|
|
388406
388679
|
probeOggStreamMetadata,
|
|
388407
388680
|
probeOggFlacSource,
|
|
388408
388681
|
parseSubtitleDocument,
|