video-fps-probe 0.2.0 → 0.3.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 (52) hide show
  1. package/CHANGELOG.md +51 -0
  2. package/README.md +26 -14
  3. package/dist/api/errors.js +1 -1
  4. package/dist/api/guards.d.ts +2 -0
  5. package/dist/api/guards.js +2 -1
  6. package/dist/check/index.js +12 -2
  7. package/dist/client/compare.js +2 -2
  8. package/dist/client/create.d.ts +3 -0
  9. package/dist/client/create.js +8 -0
  10. package/dist/client/fallback.js +2 -2
  11. package/dist/client/index.d.ts +1 -1
  12. package/dist/client/index.js +1 -1
  13. package/dist/client/inline.js +1 -1
  14. package/dist/client/lazy.js +1 -1
  15. package/dist/client/probe-client.js +4 -0
  16. package/dist/client/probe.js +23 -22
  17. package/dist/client/route.js +20 -0
  18. package/dist/client/split.js +9 -0
  19. package/dist/client/stub.js +2 -2
  20. package/dist/client/types.d.ts +1 -0
  21. package/dist/core/analyze.js +4 -78
  22. package/dist/core/dispatch.js +76 -0
  23. package/dist/core/isobmff/boxes.js +4 -7
  24. package/dist/core/isobmff/index.js +8 -5
  25. package/dist/core/isobmff/model.js +1 -1
  26. package/dist/core/isobmff/moov.js +12 -7
  27. package/dist/core/isobmff/track.js +4 -2
  28. package/dist/core/matroska/ebml.js +1 -1
  29. package/dist/core/reader.d.ts +0 -12
  30. package/dist/core/reader.js +10 -27
  31. package/dist/engines/common.js +6 -0
  32. package/dist/engines/mediabunny.js +17 -4
  33. package/dist/engines/mp4box.js +2 -1
  34. package/dist/plugins/own.js +5 -2
  35. package/dist/presets/index.d.ts +1 -0
  36. package/dist/presets/sources.json +8 -0
  37. package/dist/probe.js +2 -1
  38. package/dist/react/store.js +1 -1
  39. package/dist/standalone/own-isobmff.worker.js +1 -0
  40. package/dist/standalone/own-matroska.worker.js +1 -0
  41. package/dist/standalone/own.worker.js +1 -1
  42. package/dist/worker/own-isobmff.worker.js +4 -0
  43. package/dist/worker/own-matroska.worker.js +4 -0
  44. package/dist/worker/runtime.d.ts +2 -3
  45. package/dist/worker/runtime.js +2 -97
  46. package/dist/worker/serve.d.ts +3 -0
  47. package/dist/worker/serve.js +97 -0
  48. package/dist/worker/single.js +13 -0
  49. package/package.json +8 -2
  50. package/dist/client/inline.d.ts +0 -19
  51. package/dist/client/pool.d.ts +0 -29
  52. package/dist/client/probe.d.ts +0 -29
@@ -5,9 +5,6 @@ export class IsoBmffError extends Error {
5
5
  this.name = 'IsoBmffError';
6
6
  }
7
7
  }
8
- function printable(type) {
9
- return type.replace(/[^\x20-\x7e]/g, '?');
10
- }
11
8
  export const MAX_BOX_HEADER = 32;
12
9
  export function readBoxHeader(dv, p, parentEnd, base = 0) {
13
10
  const avail = Math.min(dv.byteLength, parentEnd);
@@ -22,7 +19,7 @@ export function readBoxHeader(dv, p, parentEnd, base = 0) {
22
19
  return null;
23
20
  const big = dv.getBigUint64(p + 8);
24
21
  if (big > BigInt(Number.MAX_SAFE_INTEGER))
25
- throw new IsoBmffError(`corrupt file: box '${printable(type)}' at ${base + p} has a size above 2^53-1`);
22
+ throw new IsoBmffError(`corrupt file: box '${type}' at ${base + p} has a size above 2^53-1`);
26
23
  size = Number(big);
27
24
  headerSize = 16;
28
25
  }
@@ -32,7 +29,7 @@ export function readBoxHeader(dv, p, parentEnd, base = 0) {
32
29
  if (type === 'uuid')
33
30
  headerSize += 16;
34
31
  if (size < headerSize)
35
- throw new IsoBmffError(`corrupt file: box '${printable(type)}' at ${base + p} is smaller than its header`);
32
+ throw new IsoBmffError(`corrupt file: box '${type}' at ${base + p} is smaller than its header`);
36
33
  const end = p + size;
37
34
  return { type, start: p, size, headerSize, end: Math.min(end, parentEnd), truncated: end > parentEnd };
38
35
  }
@@ -56,13 +53,13 @@ export function* childBoxes(dv, start, end, warnings) {
56
53
  export function boxU64(dv, p, box, at) {
57
54
  const v = dv.getBigUint64(p);
58
55
  if (v > BigInt(Number.MAX_SAFE_INTEGER))
59
- throw new IsoBmffError(`unsupported: box '${printable(box)}' at ${at} holds a value above 2^53-1`);
56
+ throw new IsoBmffError(`unsupported: box '${box}' at ${at} holds a value above 2^53-1`);
60
57
  return Number(v);
61
58
  }
62
59
  export function boxI64(dv, p, box, at) {
63
60
  const v = dv.getBigInt64(p);
64
61
  if (v > BigInt(Number.MAX_SAFE_INTEGER) || v < -BigInt(Number.MAX_SAFE_INTEGER)) {
65
- throw new IsoBmffError(`unsupported: box '${printable(box)}' at ${at} holds a value beyond 2^53-1`);
62
+ throw new IsoBmffError(`unsupported: box '${box}' at ${at} holds a value beyond 2^53-1`);
66
63
  }
67
64
  return Number(v);
68
65
  }
@@ -16,7 +16,7 @@ const MAX_TOP_LEVEL_BOXES = 4_000_000;
16
16
  const SMALL_MDAT = 64 * 1024;
17
17
  const HEADER_PEEK = 16;
18
18
  function isAbort(e, reader) {
19
- return reader.signal?.aborted === true || (typeof e === 'object' && e !== null && e.name === 'AbortError');
19
+ return reader.signal?.aborted === true || e?.name === 'AbortError';
20
20
  }
21
21
  function containerOf(movie) {
22
22
  return movie.brand === 'qt ' || (!movie.hasFtyp && movie.topLevel.length > 0) ? 'mov' : 'mp4';
@@ -66,12 +66,15 @@ async function walk(reader, opts, movie) {
66
66
  break;
67
67
  const h = { ...rel, start: pos, end: Math.min(pos + rel.size, size) };
68
68
  const boxEnd = pos + rel.size;
69
+ const trailer = rel.truncated && sawMoov && h.type !== 'mdat' && h.type !== 'moof';
69
70
  if (rel.truncated) {
70
71
  movie.truncated = true;
71
- movie.warnings.push(`'${h.type}' at ${pos} is truncated`);
72
+ movie.warnings.push(trailer ? `ignored trailing data at ${pos}: not a box` : `'${h.type}' at ${pos} is truncated`);
72
73
  }
73
74
  const top = { type: h.type, start: pos, end: h.end, sidx: null };
74
75
  movie.topLevel.push(top);
76
+ if (trailer)
77
+ break;
75
78
  if (h.type === 'ftyp') {
76
79
  const fv = await reader.view(pos, Math.min(h.size, 1024));
77
80
  const p = h.headerSize;
@@ -231,7 +234,7 @@ function buildVideoTrack(tr, movie, opts, ctx) {
231
234
  w.push('avg_frame_rate of ffprobe is not reproduced: its header values are incomplete or overrun a box');
232
235
  const r = ctx.ffprobeFails || broken ? null : ffprobeStage1Rate(tr, movie, totals.moovSamples, opts.maxExpandedSamples, w);
233
236
  t.rFpsFfprobe = r ? toFfprobeString(r) : null;
234
- const edits = editInfo(tr, movie.timescale);
237
+ const edits = editInfo(tr, movie.timescale, totals);
235
238
  if (!broken) {
236
239
  const timing = trackTiming(tr, movie, totals, edits);
237
240
  t.durationSec = timing.durationTs / ts;
@@ -335,7 +338,7 @@ function formatDuration(movie, videoTracks) {
335
338
  continue;
336
339
  }
337
340
  const totals = sampleTotals(tr);
338
- const timing = trackTiming(tr, movie, totals, editInfo(tr, movie.timescale));
341
+ const timing = trackTiming(tr, movie, totals, editInfo(tr, movie.timescale, totals));
339
342
  const d = rescaleRound(timing.durationTs, 1e6, tr.timescale);
340
343
  if (timing.startPts !== null) {
341
344
  const s = rescaleRound(timing.startPts, 1e6, tr.timescale);
@@ -383,7 +386,7 @@ export async function analyzeIsoBmffDetailed(reader, opts) {
383
386
  if (isAbort(e, reader))
384
387
  throw e;
385
388
  const message = e instanceof Error ? e.message : String(e);
386
- const analysis = emptyAnalysis(containerOf(movie), e instanceof IsoBmffError ? message : `corrupt file: ${message}`);
389
+ const analysis = emptyAnalysis(containerOf(movie), e instanceof IsoBmffError || message.startsWith(`file read failed`) ? message : `corrupt file: ${message}`);
387
390
  analysis.brand = movie.brand;
388
391
  analysis.warnings = movie.warnings;
389
392
  return { analysis, movie };
@@ -1,3 +1,4 @@
1
+ export const TO_MEDIA_END = Number.MAX_SAFE_INTEGER;
1
2
  export const IDENTITY_MATRIX = [65536, 0, 0, 0, 65536, 0, 0, 0, 1 << 30];
2
3
  export function newMovie(fileSize) {
3
4
  return {
@@ -13,7 +14,6 @@ export function newMovie(fileSize) {
13
14
  chapterTrackIds: new Set(),
14
15
  hasMvex: false,
15
16
  trex: new Map(),
16
- mehdDuration: null,
17
17
  moofCount: 0,
18
18
  topLevel: [],
19
19
  truncated: false,
@@ -1,6 +1,6 @@
1
1
  import { fourcc } from "../reader.js";
2
2
  import { boundEntries, boxI64, boxU64, childBoxes, IsoBmffError, readBoxHeader } from "./boxes.js";
3
- import { newTrack } from "./model.js";
3
+ import { newTrack, TO_MEDIA_END } from "./model.js";
4
4
  export const MAX_STTS_DELTA = 4294487295;
5
5
  const UINT32_ALL_ONES = 0xffffffff;
6
6
  function children(dv, h, ctx, skip = 0) {
@@ -105,7 +105,7 @@ export function parseCtts(dv, h, tr) {
105
105
  tr.cttsOffsets = Int32Array.from(offsets);
106
106
  tr.dtsShift = shift;
107
107
  }
108
- function parseElst(dv, h, tr, ctx) {
108
+ function parseElst(dv, h, tr, ctx, movie) {
109
109
  const p = payload(h);
110
110
  if (p + 8 > h.end)
111
111
  return;
@@ -125,8 +125,15 @@ function parseElst(dv, h, tr, ctx) {
125
125
  const at = ctx.base + h.start;
126
126
  for (let i = 0; i < n; i++) {
127
127
  const o = p + 8 + i * size;
128
- if (v === 1)
129
- tr.edits.push({ duration: boxU64(dv, o, 'elst', at), mediaTime: boxI64(dv, o + 8, 'elst', at), rate: dv.getInt32(o + 16) / 65536 });
128
+ if (v === 1) {
129
+ const mediaTime = boxI64(dv, o + 8, 'elst', at);
130
+ const unknown = dv.getBigInt64(o) === -1n;
131
+ if (unknown) {
132
+ tr.warnings.push(`unknown elst duration: ${mediaTime === -1 ? 'the empty edit is ignored' : 'the edit lasts to the end'}`);
133
+ movie.ffprobeReject ??= { moof: -1, reason: 'rejects this file: an elst duration of -1' };
134
+ }
135
+ tr.edits.push({ duration: !unknown ? boxU64(dv, o, 'elst', at) : mediaTime === -1 ? 0 : TO_MEDIA_END, mediaTime, rate: dv.getInt32(o + 16) / 65536 });
136
+ }
130
137
  else
131
138
  tr.edits.push({ duration: dv.getUint32(o), mediaTime: dv.getInt32(o + 4), rate: dv.getInt32(o + 8) / 65536 });
132
139
  }
@@ -287,7 +294,7 @@ function parseTrak(dv, h, movie, ctx) {
287
294
  else if (c.type === 'edts') {
288
295
  for (const e of children(dv, c, ctx))
289
296
  if (e.type === 'elst')
290
- parseElst(dv, e, tr, ctx);
297
+ parseElst(dv, e, tr, ctx, movie);
291
298
  }
292
299
  else if (c.type === 'mdia') {
293
300
  parseMdia(dv, c, tr, ctx);
@@ -330,8 +337,6 @@ export function parseMoov(dv, h, movie, strict, base = 0) {
330
337
  const q = payload(m);
331
338
  if (m.type === 'trex' && q + 24 <= m.end)
332
339
  movie.trex.set(dv.getUint32(q + 4), { duration: dv.getUint32(q + 12), size: dv.getUint32(q + 16) });
333
- else if (m.type === 'mehd' && q + 8 <= m.end)
334
- movie.mehdDuration = dv.getUint8(q) === 1 && q + 12 <= m.end ? boxU64(dv, q + 4, 'mehd', base + m.start) : dv.getUint32(q + 4);
335
340
  }
336
341
  break;
337
342
  case 'cmov':
@@ -1,4 +1,5 @@
1
1
  import { INT_MAX, reduceRational, toFfprobeString } from "../rational.js";
2
+ import { TO_MEDIA_END } from "./model.js";
2
3
  export function rescaleRound(a, b, c) {
3
4
  if (!(c > 0))
4
5
  return 0;
@@ -62,13 +63,14 @@ export function missingMandatoryAtoms(tr) {
62
63
  const samples = tr.sampleCount ?? 0;
63
64
  return (chunks > 0 && (!stts || declared(tr.stsc) === 0 || (tr.sampleSize === 0 && samples === 0))) || (samples > 0 && chunks === 0);
64
65
  }
65
- export function editInfo(tr, movieTimescale) {
66
+ export function editInfo(tr, movieTimescale, totals) {
66
67
  let emptyBefore = 0;
67
68
  let editSum = 0;
68
69
  let mediaEdits = 0;
69
70
  let firstMedia = null;
71
+ const mediaEnd = (tr.cttsOffsets?.[0] ?? 0) + totals.moovDuration;
70
72
  for (const e of tr.edits) {
71
- const d = rescaleRound(e.duration, tr.timescale, movieTimescale);
73
+ const d = e.duration === TO_MEDIA_END ? Math.max(0, mediaEnd - e.mediaTime) : rescaleRound(e.duration, tr.timescale, movieTimescale);
72
74
  editSum += d;
73
75
  if (e.mediaTime === -1) {
74
76
  if (!firstMedia)
@@ -146,7 +146,7 @@ export function readString(b, p, n) {
146
146
  let e = p;
147
147
  while (e < p + n && b[e] !== 0)
148
148
  e++;
149
- return utf8.decode(b.subarray(p, e));
149
+ return utf8.decode(b.subarray(p, e)).replace(/[^\x20-\x7e\xa0-\uffff]/g, '?');
150
150
  }
151
151
  export function* children(b, start, end) {
152
152
  let p = start;
@@ -10,17 +10,9 @@ export interface BlobReaderOptions {
10
10
  maxWindows?: number;
11
11
  signal?: AbortSignal | null;
12
12
  }
13
- export interface ReaderStats {
14
- reads: number;
15
- bytesFetched: number;
16
- bytesTransferred: number;
17
- }
18
13
  export declare const DEFAULT_HEAD_WINDOW: number;
19
14
  export declare const DEFAULT_MAX_WINDOWS = 4;
20
15
  export declare const MAX_SAFE_OFFSET: number;
21
- export declare class EndOfFileError extends Error {
22
- constructor(message: string);
23
- }
24
16
  export declare function toSafeNumber(value: bigint, what?: string): number;
25
17
  export declare class BlobReader {
26
18
  #private;
@@ -31,16 +23,12 @@ export declare class BlobReader {
31
23
  constructor(source: BlobLike, options?: BlobReaderOptions);
32
24
  get reads(): number;
33
25
  get bytesFetched(): number;
34
- get bytesTransferred(): number;
35
- stats(): ReaderStats;
36
26
  checkAbort(): void;
37
27
  read(offset: number, length: number): Promise<Uint8Array>;
38
28
  readMany(ranges: ReadonlyArray<readonly [offset: number, length: number]>, concurrency?: number): Promise<Uint8Array[]>;
39
29
  peek(offset: number, length: number): DataView | null;
40
30
  view(offset: number, length: number, readAhead?: number): Promise<DataView>;
41
- viewExact(offset: number, length: number, readAhead?: number): Promise<DataView>;
42
31
  bytes(offset: number, length: number, readAhead?: number): Promise<Uint8Array>;
43
- clearCache(): void;
44
32
  }
45
33
  export declare function u8(dv: DataView, p: number): number;
46
34
  export declare function u16(dv: DataView, p: number): number;
@@ -2,12 +2,6 @@ import { throwIfAborted } from "./abort.js";
2
2
  export const DEFAULT_HEAD_WINDOW = 64 * 1024;
3
3
  export const DEFAULT_MAX_WINDOWS = 4;
4
4
  export const MAX_SAFE_OFFSET = Number.MAX_SAFE_INTEGER;
5
- export class EndOfFileError extends Error {
6
- constructor(message) {
7
- super(message);
8
- this.name = 'EndOfFileError';
9
- }
10
- }
11
5
  function assertSafeCount(value, what) {
12
6
  if (!Number.isSafeInteger(value) || value < 0)
13
7
  throw new RangeError(`${what} must be a non-negative safe integer, got ${value}`);
@@ -27,7 +21,6 @@ export class BlobReader {
27
21
  #covered = [];
28
22
  #reads = 0;
29
23
  #unique = 0;
30
- #transferred = 0;
31
24
  constructor(source, options = {}) {
32
25
  assertSafeCount(source.size, 'blob size');
33
26
  this.#source = source;
@@ -43,12 +36,6 @@ export class BlobReader {
43
36
  get bytesFetched() {
44
37
  return this.#unique;
45
38
  }
46
- get bytesTransferred() {
47
- return this.#transferred;
48
- }
49
- stats() {
50
- return { reads: this.#reads, bytesFetched: this.#unique, bytesTransferred: this.#transferred };
51
- }
52
39
  checkAbort() {
53
40
  throwIfAborted(this.signal);
54
41
  }
@@ -61,12 +48,18 @@ export class BlobReader {
61
48
  if (end === offset)
62
49
  return new Uint8Array(0);
63
50
  this.checkAbort();
64
- const ab = await this.#source.slice(offset, end).arrayBuffer();
51
+ let ab;
52
+ try {
53
+ ab = await this.#source.slice(offset, end).arrayBuffer();
54
+ }
55
+ catch (e) {
56
+ this.checkAbort();
57
+ throw e?.name === 'AbortError' ? e : Error(`file read failed: ${e}`);
58
+ }
65
59
  this.checkAbort();
66
60
  this.#reads++;
67
- this.#transferred += ab.byteLength;
68
61
  if (ab.byteLength !== end - offset) {
69
- throw new EndOfFileError(`short read at ${offset}: expected ${end - offset} bytes, got ${ab.byteLength}`);
62
+ throw Error(`file read failed: short read at ${offset}: expected ${end - offset} bytes, got ${ab.byteLength}`);
70
63
  }
71
64
  this.#cover(offset, end);
72
65
  return new Uint8Array(ab);
@@ -132,20 +125,10 @@ export class BlobReader {
132
125
  this.#windows.length = this.maxWindows;
133
126
  return new DataView(buf.buffer, buf.byteOffset, end - offset);
134
127
  }
135
- async viewExact(offset, length, readAhead = this.headWindow) {
136
- const dv = await this.view(offset, length, readAhead);
137
- if (dv.byteLength < length) {
138
- throw new EndOfFileError(`unexpected end of file: wanted ${length} bytes at ${offset}, file size ${this.size}`);
139
- }
140
- return dv;
141
- }
142
128
  async bytes(offset, length, readAhead = this.headWindow) {
143
129
  const dv = await this.view(offset, length, readAhead);
144
130
  return new Uint8Array(dv.buffer, dv.byteOffset, dv.byteLength);
145
131
  }
146
- clearCache() {
147
- this.#windows = [];
148
- }
149
132
  #cover(start, end) {
150
133
  const list = this.#covered;
151
134
  let lo = 0;
@@ -213,5 +196,5 @@ export function ascii(dv, p, length) {
213
196
  return s;
214
197
  }
215
198
  export function fourcc(dv, p) {
216
- return ascii(dv, p, 4);
199
+ return ascii(dv, p, 4).replace(/[^ -~]/g, '?');
217
200
  }
@@ -53,6 +53,12 @@ export function isAbort(e, signal) {
53
53
  export function newResult(name, size, engine) {
54
54
  return { name, size, ...emptyAnalysis('unknown'), io: { reads: 0, bytesRead: 0, ms: 0 }, engine };
55
55
  }
56
+ const printable = (warnings) => warnings.map((w) => w.replace(/[^\x20-\x7e\xa0-\uffff]/g, '?'));
57
+ export function printableWarnings(result) {
58
+ result.warnings = printable(result.warnings);
59
+ for (const t of result.videoTracks)
60
+ t.warnings = printable(t.warnings);
61
+ }
56
62
  export function ffprobeRotation(matrix) {
57
63
  const a = matrix[0] / 65536;
58
64
  const b = matrix[1] / 65536;
@@ -3,7 +3,7 @@ import { throwIfAborted } from "../core/abort.js";
3
3
  import { resolveOptions } from "../core/options.js";
4
4
  import { emptyTrack } from "../core/result.js";
5
5
  import { analyzeTimeline } from "../core/stats.js";
6
- import { applyStats, approxRational, codecNameFromFourcc, errorMessage, isAbort, newResult } from "./common.js";
6
+ import { applyStats, approxRational, codecNameFromFourcc, errorMessage, isAbort, newResult, printableWarnings } from "./common.js";
7
7
  import { CountingBlob, elapsed, now } from "./counting.js";
8
8
  export const MEDIABUNNY_VERSION = '1.62.1';
9
9
  const CODEC_NAMES = {
@@ -145,7 +145,18 @@ async function probe(counted, result, opts, t0) {
145
145
  ];
146
146
  const source = new CustomSource({
147
147
  getSize: () => counted.size,
148
- read: async (start, end) => new Uint8Array(await counted.slice(start, end).arrayBuffer()),
148
+ read: async (start, end) => {
149
+ let ab;
150
+ try {
151
+ ab = await counted.slice(start, end).arrayBuffer();
152
+ }
153
+ catch (e) {
154
+ throw isAbort(e, signal) ? e : Error(`file read failed: ${e}`);
155
+ }
156
+ if (ab.byteLength !== end - start)
157
+ throw Error(`file read failed: short read at ${start}: expected ${end - start} bytes, got ${ab.byteLength}`);
158
+ return new Uint8Array(ab);
159
+ },
149
160
  prefetchProfile: 'fileSystem',
150
161
  handleUnhandledError: (e) => {
151
162
  unhandled.push(errorMessage(e));
@@ -160,7 +171,8 @@ async function probe(counted, result, opts, t0) {
160
171
  catch (e) {
161
172
  if (isAbort(e, signal))
162
173
  throw e;
163
- result.error = `not a recognised container: ${errorMessage(e)}`;
174
+ const message = errorMessage(e);
175
+ result.error = message.startsWith('file read failed') ? message : `not a recognised container: ${message}`;
164
176
  return;
165
177
  }
166
178
  result.container = containerOf(format);
@@ -176,7 +188,7 @@ async function probe(counted, result, opts, t0) {
176
188
  works.push(await collectTrack(track, quantized, signal, maxPackets));
177
189
  }
178
190
  catch (e) {
179
- if (isAbort(e, signal))
191
+ if (isAbort(e, signal) || errorMessage(e).startsWith('file read failed'))
180
192
  throw e;
181
193
  result.warnings.push(`track ${track.id}: ${errorMessage(e)}`);
182
194
  }
@@ -235,6 +247,7 @@ export async function analyzeWithMediabunny(blob, name, opts = {}) {
235
247
  }
236
248
  if (result.mediabunny === undefined)
237
249
  result.io = counted.io(t0);
250
+ printableWarnings(result);
238
251
  return result;
239
252
  }
240
253
  export const containers = 'any';
@@ -5,7 +5,7 @@ import { BlobReader, fourcc, u32, u64 } from "../core/reader.js";
5
5
  import { emptyTrack } from "../core/result.js";
6
6
  import { sniff } from "../core/sniff.js";
7
7
  import { analyzeTimeline } from "../core/stats.js";
8
- import { applyStats, codecNameFromFourcc, errorMessage, ffprobeRotation, isAbort, newResult } from "./common.js";
8
+ import { applyStats, codecNameFromFourcc, errorMessage, ffprobeRotation, isAbort, newResult, printableWarnings } from "./common.js";
9
9
  import { CountingBlob, now } from "./counting.js";
10
10
  export const MP4BOX_VERSION = '2.4.1';
11
11
  const MAX_TOP_LEVEL_BOXES = 5_000_000;
@@ -423,6 +423,7 @@ export async function analyzeWithMp4box(blob, name, opts = {}) {
423
423
  result.error = errorMessage(e);
424
424
  }
425
425
  result.io = counted.io(t0);
426
+ printableWarnings(result);
426
427
  return result;
427
428
  }
428
429
  export const containers = ['isobmff'];
@@ -1,6 +1,9 @@
1
1
  export const ownDescriptor = {
2
2
  id: 'own',
3
3
  thread: 'worker',
4
- createWorker: () => new Worker(new URL('../worker/own.worker.js', import.meta.url), { type: 'module' }),
5
- load: async () => (await import("../worker/runtime.js")).ownEngine,
4
+ createWorkers: {
5
+ isobmff: () => new Worker(new URL('../worker/own-isobmff.worker.js', import.meta.url), { type: 'module' }),
6
+ matroska: () => new Worker(new URL('../worker/own-matroska.worker.js', import.meta.url), { type: 'module' }),
7
+ },
8
+ load: () => import("../worker/runtime.js").then((m) => m.ownEngine),
6
9
  };
@@ -2,6 +2,7 @@ import type { CheckRules } from '../check/index.js';
2
2
  export type PresetSourceKind = 'official' | 'gateway';
3
3
  export interface ProviderPreset {
4
4
  readonly name: string;
5
+ /** @deprecated Use video-fps-probe/presets/sources.json; sourceUrl will be removed in the next major. */
5
6
  readonly sourceUrl: string;
6
7
  readonly sourceKind: PresetSourceKind;
7
8
  readonly verifiedAt: string;
@@ -0,0 +1,8 @@
1
+ {
2
+ "klingO1ReferenceVideo": "https://kling.ai/document-api/api/video/o1/video-omni.md",
3
+ "klingMotionControl": "https://kling.ai/document-api/api/video/motion-control.md",
4
+ "runwayAleph2": "https://docs.dev.runwayml.com/assets/inputs",
5
+ "veoExtend": "https://docs.cloud.google.com/gemini-enterprise-agent-platform/models/video/extend-a-veo-video",
6
+ "wan26ReferenceToVideoFal": "https://fal.ai/models/wan/v2.6/reference-to-video/api",
7
+ "seedance2ReferenceVideo": "https://evolink.ai/docs/en/api-manual/video-series/seedance2.0/seedance-2.0-reference-to-video"
8
+ }
package/dist/probe.js CHANGED
@@ -1,6 +1,7 @@
1
1
  import { createProbeCore } from "./client/probe.js";
2
+ import { splitRoute } from "./client/route.js";
2
3
  import { ownDescriptor } from "./plugins/own.js";
3
4
  export function createProbe(options = {}) {
4
5
  const { engines = [], worker, ...rest } = options;
5
- return createProbeCore({ ...rest, engines: [ownDescriptor, ...engines], worker: worker === 'inline' ? 'inline' : undefined });
6
+ return createProbeCore({ ...rest, engines: [ownDescriptor, ...engines], worker: worker === 'inline' ? 'inline' : undefined, split: splitRoute });
6
7
  }
@@ -5,7 +5,7 @@ const IDLE = { status: 'idle', ...CLEAR, cancel: noop, retry: noop };
5
5
  const hosts = new WeakMap();
6
6
  let hostCount = 0;
7
7
  const loadSummary = () => import("../api/summary.js");
8
- const failure = (error, reason) => error instanceof ProbeError ? error : Object.assign(new ProbeError('worker-failed', String(error), { cause: error }), { reason });
8
+ const failure = (error, reason) => error?.name === 'ProbeError' && typeof error.code === 'string' ? error : Object.assign(new ProbeError('worker-failed', String(error), { cause: error }), { reason });
9
9
  const sortKeys = (_key, v) => (v && typeof v === 'object' && !Array.isArray(v) ? Object.fromEntries(Object.entries(v).sort(([a], [b]) => (a < b ? -1 : 1))) : v);
10
10
  export function createVideoFpsStore(probe) {
11
11
  const cache = new WeakMap();
@@ -0,0 +1 @@
1
+ (function(){var e=Object.defineProperty,t=(e,t,n)=>()=>{if(n)throw n[0];try{return e&&(t=e(e=0)),t}catch(e){throw n=[e],e}},n=(t,n)=>{let r={};for(var i in t)e(r,i,{get:t[i],enumerable:!0});return n||e(r,Symbol.toStringTag,{value:`Module`}),r};function r(e,t=null){return{container:e,brand:null,formatDurationSec:null,scan:null,videoTracks:[],audioTrackCount:0,primaryTrackId:null,error:t,warnings:[]}}function i(e){return{trackId:e,fourccOrCodecId:``,codecName:``,width:0,height:0,rotation:0,timescale:0,frames:null,presentedFrames:null,durationSec:null,startSec:null,avgFps:null,avgFpsFfprobe:null,rFpsFfprobe:null,nominalFps:null,dominantFps:null,minFps:null,maxFps:null,isVfr:null,vfrRatio:0,distinctDeltas:0,duplicateTimestamps:0,timestampsQuantized:!1,isStill:!1,rateProfile:null,provenance:{},warnings:[]}}function a(e){return e<0n?-e:e}function o(e,t){for(;t!==0n;){let n=e%t;e=t,t=n}return e}function s(e,t){if(typeof e==`bigint`)return e;if(!Number.isSafeInteger(e))throw RangeError(`${t} must be a safe integer, got ${e}`);return BigInt(e)}function c(e,t,n=p){let r=s(e,`num`),i=s(t,`den`),c=s(n,`max`),l=0n,u=1n,d=1n,f=0n,m=r<0n!=i<0n,h=o(a(r),a(i));for(h!==0n&&(r=a(r)/h,i=a(i)/h),r<=c&&i<=c&&(d=r,f=i,i=0n);i!==0n;){let e=r/i,t=r-i*e,n=e*d+l,a=e*f+u;if(n>c||a>c){if(d!==0n&&(e=(c-l)/d),f!==0n){let t=(c-u)/f;t<e&&(e=t)}i*(2n*e*f+u)>r*f&&(d=e*d+l,f=e*f+u);break}l=d,u=f,d=n,f=a,r=i,i=t}let g=Number(d);return{num:m?-g:g,den:Number(f),exact:i===0n}}function l(e){return e.den===0?0:e.num/e.den}function u(e){return e?`${e.num}/${e.den}`:`0/0`}function d(e,t){return{num:e,den:t,value:l({num:e,den:t})}}function f(e,t,n=p){let r=c(e,t,n);return d(r.num,r.den)}var p,m=t((()=>{p=2147483647}));function h(e,t){let n={...e};if(!t)return n;for(let e of Object.keys(t)){let r=t[e];r!==void 0&&(n[e]=r)}return n}function g(e={}){return{signal:e.signal??null,matroskaMode:e.matroskaMode??`auto`,exactBudgetMs:e.exactBudgetMs??150,readAhead:h(_,e.readAhead),costModel:h(v,e.costModel),maxExpandedSamples:e.maxExpandedSamples??5e6,onProgress:e.onProgress??null}}var _,v,y=t((()=>{_={head:65536,fragment:1048576,matroskaScan:1048576,tail:262144},v={perReadMs:.8,bytesPerMs:5e5,perBlockMs:2e-4}})),b=n({CUSUM_ALARM_PERIODS:()=>2,FREEZE_FACTOR:()=>4,FREEZE_MIN_SEC:()=>we,MAX_ANOMALIES:()=>50,MAX_BUCKETS:()=>120,MAX_SEGMENTS:()=>50,MIN_SEGMENT_FRAMES:()=>5,MIN_SEGMENT_SEC:()=>S,UNEVEN_DOMINANT_SHARE:()=>C,rateProfile:()=>D});function x(e,t,n){e.t0=Math.min(e.t0,t.t0),e.t1=Math.max(e.t1,t.t1),e.frames+=t.frames,n?(e.n+=t.n,e.sum+=t.sum,e.ex+=t.ex):e.ex+=t.t1-t.t0}var S,C,w,T,E,D,ee=t((()=>{Ee(),S=.5,C=.8,w=1+Se,T=e=>String(+e.toPrecision(4)),E=e=>({t0:e,t1:e,n:0,sum:0,frames:0,ex:0,d:0,kind:`steady`}),D=(e,t,n,r)=>{let i=t,a=we*i,o=e=>i*e.n/e.sum,s=e=>e.n>=5&&e.t1-e.t0>=.5*i,c=[],l=e=>{let t=c[c.length-1];s(e)?c.push(e):t?.kind===`short`?x(t,e,!0):c.push({...e,kind:`short`})},u=E(0),d=E(0),f=E(0),p=0,m=0,h=0,g=0,_=0,v=!1,y=()=>{u.t1=p,v?c.push({...u,kind:`hold`}):l(u),u=E(p),v=!1,g=_=0},b=Math.min(120,Math.floor(n/2)),S=r/b,C=new Float64Array(b),D=(e,t)=>{u.n+=e,u.sum+=e*t,u.frames+=e,p+=e*t},ee=(e,t)=>{let n=e;if(t<=0)u.frames+=n,h+=n;else{for(let e=p,r=e+n*t,i=Math.floor(e/S);e<r&&i<b;i++){let n=Math.min(r,(i+1)*S);n>e&&(C[i]+=(n-e)/t),e=Math.max(e,n)}for(;n>0;){let e=u.sum/u.n;if(u.n&&t>=Math.max(a,4*e)){y(),v=!0,D(1,t),n--;continue}if(v&&Math.abs(t-e)>.075*e&&y(),v=!1,!u.n){D(n,t);return}let r=t-e,i=Ce*e,o=2*e,s=Math.abs(r)>i,c=s?1:n;if(s&&(r>0?!g||r-i>o:!_)){let e={...u,t1:p,d:t};r>0?d=e:f=e}if(g=Math.max(0,g+c*(r-i)),_=Math.max(0,_-c*(r+i)),D(c,t),n-=c,g>o||_>o){let e=g>o?d:f,t=u.n-e.n-1;t>0&&Math.abs(Math.log(e.d*e.n/e.sum))<Math.abs(Math.log(e.d*t/(u.sum-e.sum-e.d)))&&(e.t1+=e.d,e.n++,e.sum+=e.d,e.frames++),u.t0=e.t1,u.n-=e.n,u.sum-=e.sum,u.frames-=e.frames,l(e),g=_=0}}}},O=0,k=0;if(e((e,t)=>{e>0&&(m+=e,O&&t!==k&&(ee(O,k),O=0),O+=e,k=t)}),O&&ee(O,k),!(p>0))return null;u.n?y():c[c.length-1].frames+=u.frames;let A=[],te=(e,t,n,r,a=t.t1-t.t0)=>{A.push({kind:e,atSec:t.t0/i,durationSec:a/i,fromFps:n,toFps:r})},j=[],ne=(e,t)=>e?Math.abs(Math.log(o(e)/t)):1/0;c.forEach((e,t)=>{let n=j[j.length-1];if(e.kind===`short`||e.kind===`hold`){let r=o(e),i=c[t+1]?.kind===`steady`?c[t+1]:void 0,l=ne(n,r)<=ne(i,r)?n:i;if(e.kind=s(e)?`variable`:`steady`,e.kind===`steady`&&l){let t=o(l),n=e.sum>=e.n*Math.max(a,4*l.sum/l.n)?`freeze`:r*w<t?`gap`:r>t*w?`burst`:null;n&&te(n,e,t,r),x(l,e,!n);return}}let r=n?o(e)/o(n):0;n?.kind===`steady`&&e.kind===`steady`&&r<w&&r*w>1?x(n,e,!0):j.push(e)});let M=j[j.length-1],N=p+M.sum/M.n;M.frames+=n-m,M.t1=N;for(let e=1;e<j.length;e++){let t=j[e-1],n=j[e],r=o(n)/o(t);(t.kind===`steady`&&n.kind===`steady`||r>=w||r*w<=1)&&te(`rate-change`,n,o(t),o(n),0)}A.sort((e,t)=>e.atSec-t.atSec);let P=j.filter(e=>e.kind===`steady`).map(e=>[o(e),e.t1-e.t0-e.ex,e.n]).sort((e,t)=>e[0]-t[0]),F=0,I=0,L=0,re=0,R=0;for(let[e,t,n]of P){for(L+=t,re+=n;e>=P[R][0]*w;R++)L-=P[R][1],re-=P[R][2];F=Math.max(F,L),I=Math.max(I,re)}let ie=F/N,ae=ie<.8||I<.8*(m-h)||P.length>1&&P[P.length-1][0]>=P[0][0]*w,z=j.slice(0,3).map(e=>`${e.kind===`variable`?`~`:``}${T(o(e))} fps for ${T((e.t1-e.t0)/i)} s`);j.length>3&&z.push(`+${j.length-3} more`);let B=``,oe=(e,t)=>{e&&(B+=`${B?`, `:`; `}${e} ${t}${e>1?`s`:``}`)};for(let e of[`freeze`,`gap`,`burst`])oe(A.filter(t=>t.kind===e).length,e);return oe(h,`duplicate timestamp`),{segments:j.slice(0,50).map(e=>({startSec:e.t0/i,endSec:e.t1/i,frames:e.frames,fps:o(e),kind:e.kind})),moreSegments:Math.max(0,j.length-50),anomalies:A.slice(0,50),moreAnomalies:Math.max(0,A.length-50),buckets:{bucketSec:S/i,fps:Array.from(C,e=>e*i/S)},uneven:ae,dominantShare:ie,summary:`${ae?`Uneven`:B?`Mostly steady`:`Steady`}: ${z.join(`, `)}${B}`}}})),O=n({CUSUM_DRIFT:()=>Ce,FREEZE_FACTOR:()=>4,FREEZE_MIN_SEC:()=>we,MAX_REORDER_DEPTH:()=>16,RATE_CHANGE_RELATIVE:()=>Se,SNAP_RELATIVE_TOLERANCE:()=>be,VFR_RELATIVE_TOLERANCE:()=>xe,analyzeTimeline:()=>N,msGridTicks:()=>A,rateFromTicks:()=>M,rateProfileOf:()=>ce,reorderDepthFromCts:()=>j,snapToStandardRate:()=>k,vfrTolerance:()=>te});function k(e,t=be){if(!(e>0))return null;let n=null,r=1/0;for(let t of Te){let i=Math.abs(e-t.value)/t.value;i<r&&(r=i,n=t)}return r<=t?n:null}function A(e,t){if(!(e>1e3)||t.length===0)return 0;for(let n of t){let t=n*1e3;if(!Number.isSafeInteger(t)||t%e!==0)return 0}return e/1e3}function te(e,t,n){return Math.max(1,Math.round(xe*e),A(t,n))}function j(e,t,n){return!(t>e)||!(n>0)?0:Math.min(16,Math.ceil((t-e)/n))}function ne(e){if(Number.isInteger(e)||!(e>0))return null;let t=1e9/e,n=Math.round(t);return n>0&&Math.abs(t-n)<=1e-6*n?n:null}function M(e,t){let n=ne(e);return n!==null&&t>0&&Number.isSafeInteger(n*t)?f(1e9,n*t,2**53-1):I(e,t,2**53-1)}function N(e){let t=[],n=re(e.timescale,t);return`segments`in e?he(e,n,t):ye(e,n,t)}function P(e){return`counts`in e&&`deltas`in e?{n:Math.min(e.counts.length,e.deltas.length),counts:e.counts,values:e.deltas}:{n:e.length,counts:null,values:e}}function F(e){return e?`counts`in e&&`offsets`in e?{n:Math.min(e.counts.length,e.offsets.length),counts:e.counts,values:e.offsets}:{n:e.length,counts:null,values:e}:null}function I(e,t,n=p){if(!(e>0)||!(t>0))return null;if(Number.isSafeInteger(e)&&Number.isSafeInteger(t))return f(e,t,n);let r=1e6,i=Math.round(e*r),a=Math.round(t*r);return Number.isSafeInteger(i)&&Number.isSafeInteger(a)?f(i,a,n):d(e/t,1)}function L(e,t,n){if(!(t>0)||!(n>0))return null;let r=ne(e);return r!==null&&Number.isSafeInteger(t)&&Number.isSafeInteger(n)?f(BigInt(t)*1000000000n,BigInt(r)*BigInt(n),p):Number.isSafeInteger(e)&&Number.isSafeInteger(t)&&Number.isSafeInteger(n)?f(BigInt(e)*BigInt(t),n,p):I(e*t,n)}function re(e,t){return e>0&&Number.isFinite(e)?e:(t.push(`invalid timescale ${e}, using 1`),1)}function R(e){return e?{ws:e.start,we:e.end>e.start?e.end:1/0}:{ws:-1/0,we:1/0}}function ie(e,t){return{timescale:e,sampleCount:0,durationSum:0,avgFps:null,avgFpsString:`0/0`,presentedAvgFps:null,presentedFrames:null,firstPts:null,lastPts:null,deltaCount:0,excludedTailDeltas:0,reorderDepth:0,duplicateTimestamps:0,discontinuities:0,histogram:[],distinctDeltas:0,minDelta:null,maxDelta:null,medianDelta:null,meanDelta:null,tolerance:null,minFps:null,maxFps:null,isVfr:null,vfrRatio:0,nominalFps:null,dominantFps:null,timestampsQuantized:!1,profile:null,fastPath:!1,warnings:t}}function ae(e,t,n,r,i,a){let o=e.timescale,s=e.isVfr===!1&&n-t<=(e.tolerance??0)&&n<2*t;return n>t*1.075&&!s?e=>e(r,o,i,a):null}function z(e,t){let n=e.medianDelta,r=e.timescale;!n||!t||t<4*n||t<.5*r||e.warnings.push(`last frame held ${(t/r).toFixed(3)} s (${(t/n).toFixed(1)}x the median frame interval): the average is below the frame rate`)}function B(e,t){if(z(e,t),e.presentedFrames===null||e.presentedFrames<=0||e.firstPts===null||e.lastPts===null)return;let n=t>0?t:e.medianDelta??0;e.presentedAvgFps=L(e.timescale,e.presentedFrames,e.lastPts-e.firstPts+n)}function oe(e,t){let n=0;for(let[r,i]of V(e)){if(t<n+r)return i;n+=r}return 0}async function se(){try{let{rateProfile:e}=await Promise.resolve().then(()=>(ee(),b));return e}catch{return null}}async function ce(e){let t=e&&await se();return t?e(t):null}function le(e,t){return e-t>=2?e-t:e}function ue(e,t,n){let r=e.timescale,i=[...t.keys()].sort((e,t)=>e-t),a=i.map(e=>[e,t.get(e)??0]),o=0,s=0;for(let[e,t]of a)o+=t,s+=e*t;if(e.histogram=a,e.distinctDeltas=i.length,o===0)return;let c=0,l=i[0];for(let[e,t]of a)if(c+=t,c*2>=o){l=e;break}let u=i[0],d=0;for(let[e,t]of a)t>d&&(u=e,d=t);let f=A(r,i),p=Math.max(1,Math.round(xe*l),f),m=0;for(let[e,t]of a)Math.abs(e-l)>p&&(m+=t);let h=i[0],g=i[i.length-1],_=o>=2&&m>0;if(e.minDelta=h,e.maxDelta=g,e.medianDelta=l,e.meanDelta=s/o,e.tolerance=p,e.minFps=M(r,g),e.maxFps=M(r,h),e.isVfr=_,e.vfrRatio=m/o,i.length===1){let t=M(r,h);t&&(e.nominalFps={...t,kind:`exact`})}else if(_&&d*2>=o){let t=M(r,u);t&&(e.dominantFps={rate:t,share:d/o})}e.timestampsQuantized=(n||f>0)&&!_&&i.length>1}function de(e){if(e.nominalFps||e.isVfr!==!1||e.distinctDeltas<2||!e.avgFps)return;let t=k(e.meanDelta?e.timescale/e.meanDelta:e.avgFps.value);t&&(e.nominalFps={...t,kind:`snapped`})}function fe(e){let t={n:0,d:0,constantCts:!0,ctsValue:0,ctsMin:1/0,ctsMax:-1/0,firstDelta:0,negativeDurations:!1,discontinuities:0,startDts:0,ctsMismatch:0},n=!1,r=e=>{n?e!==t.ctsValue&&(t.constantCts=!1):(t.ctsValue=e,n=!0),e<t.ctsMin&&(t.ctsMin=e),e>t.ctsMax&&(t.ctsMax=e)},i=0;for(let n=0;n<e.length;n++){let a=e[n];a.baseDts!==void 0&&a.baseDts!==null&&(n===0?t.startDts=a.baseDts:a.baseDts!==i&&t.discontinuities++,i=a.baseDts);let o=P(a.durations),s=0;for(let e=0;e<o.n;e++){let n=o.counts?o.counts[e]:1;if(n<=0)continue;let r=o.values[e];s+=n,t.d+=n*r,i+=n*r,r<0&&(t.negativeDurations=!0),t.firstDelta===0&&r>0&&(t.firstDelta=r)}t.n+=s;let c=F(a.cts),l=0,u=0;if(c){for(let e=0;e<c.n;e++){let t=c.counts?c.counts[e]:1;if(t<=0)continue;u+=t;let n=Math.min(t,s-l);n<=0||(l+=n,r(c.values[e]))}u!==s&&t.ctsMismatch++}l<s&&r(0)}return n||(t.ctsMin=0,t.ctsMax=0),t}function*V(e){for(let t of e){let e=P(t.durations);for(let t=0;t<e.n;t++){let n=e.counts?e.counts[t]:1;n>0&&(yield[n,e.values[t]])}}}function pe(e,t,n,r){if(n===-1/0)return 0;if(n===1/0)return r;let i=t,a=0;for(let[t,r]of V(e)){if(r===0){if(i<n){a+=t;continue}return a}if(i+(t-1)*r<n)a+=t,i+=t*r;else return a+Math.max(0,Math.min(t,Math.ceil((n-i)/r)))}return a}function me(e,t,n){let r=t,i=0;for(let[t,a]of V(e)){if(n<i+t)return r+(n-i)*a;i+=t,r+=t*a}return r}function he(e,t,n){let r=e.segments,i=fe(r);i.ctsMismatch>0&&n.push(`composition offsets do not match the sample count in ${i.ctsMismatch} segment(s)`),i.discontinuities>0&&n.push(`decode timestamp discontinuities: ${i.discontinuities}`),i.negativeDurations&&n.push(`negative sample durations`),Number.isSafeInteger(i.d)||n.push(`duration sum exceeds 2^53-1`);let a=ie(t,n);if(a.sampleCount=i.n,a.durationSum=i.d,a.discontinuities=i.discontinuities,a.avgFps=L(t,i.n,i.d),a.avgFpsString=u(a.avgFps),i.n===0)return a.presentedFrames=0,a;let o=e.reorderDepth??j(i.ctsMin,i.ctsMax,i.firstDelta);a.reorderDepth=o;let s=1+o,{ws:c,we:l}=R(e.editWindow),d=e.tickQuantized??!1;if(!e.forceExpand&&i.constantCts&&i.discontinuities===0&&!i.negativeDurations){a.fastPath=!0;let e=i.startDts+i.ctsValue,t=pe(r,e,c,i.n),n=Math.max(t,pe(r,e,l,i.n));if(a.presentedFrames=n-t,n===t)return a;let o=me(r,e,t),u=me(r,e,n-1);a.firstPts=o,a.lastPts=u;let f=n-t-1,p=le(f,s),m=new Map,h=0,g=1/0,_=0;for(let[e,n]of V(r)){if(h>=t+f)break;let r=Math.max(h,t),i=Math.min(h+e,t+f);if(i>r){if(n===0)a.duplicateTimestamps+=i-r;else{g=Math.min(g,n),_=Math.max(_,n);let i=Math.min(h+e,t+p);i>r&&(m.set(n,(m.get(n)??0)+(i-r)),a.deltaCount+=i-r)}}h+=e}return a.excludedTailDeltas=f-p,ue(a,m,d),de(a),B(a,oe(r,n-1)),a.profile=ae(a,g,_,e=>{let n=0;for(let[i,a]of V(r)){if(n>=t+f)break;let r=Math.max(n,t),o=Math.min(n+i,t+f);o>r&&e(o-r,a),n+=i}},n-t,u-o),a}let f=e.maxExpandedSamples??5e6;if(i.n>f)return n.push(`per-sample analysis skipped: ${i.n} samples exceed the limit of ${f}`),a;let p=new Float64Array(i.n),m=0,h=0;for(let e of r){e.baseDts!==void 0&&e.baseDts!==null&&(h=e.baseDts);let t=m,n=P(e.durations);for(let e=0;e<n.n;e++){let t=n.counts?n.counts[e]:1,r=n.values[e];for(let e=0;e<t;e++)p[m++]=h,h+=r}let r=F(e.cts);if(r){let e=t;for(let t=0;t<r.n&&e<m;t++){let n=r.counts?r.counts[t]:1,i=r.values[t];for(let t=0;t<n&&e<m;t++)p[e++]+=i}}}let g=-1;for(let e=0;e<p.length;e++){let t=p[e];t>=c&&t<l&&(g<0||t>=p[g])&&(g=e)}let _=g>=0?oe(r,g):0;return _e(a,ge(p,c,l),s,d),B(a,_),de(a),a}function ge(e,t,n){let r=e.length;if(t!==-1/0||n!==1/0){r=0;for(let i=0;i<e.length;i++){let a=e[i];a>=t&&a<n&&(e[r++]=a)}}let i=e.subarray(0,r);for(let e=1;e<r;e++)if(i[e]<i[e-1]){i.sort();break}return i}function _e(e,t,n,r){let i=t.length;if(e.presentedFrames=i,i===0)return;e.firstPts=t[0],e.lastPts=t[i-1];let a=i-1,o=le(a,n),s=new Map,c=1/0,l=0;for(let n=1;n<=a;n++){let r=t[n]-t[n-1];r<=0?e.duplicateTimestamps++:(c=Math.min(c,r),l=Math.max(l,r),n<=o&&(s.set(r,(s.get(r)??0)+1),e.deltaCount++))}e.excludedTailDeltas=a-o,ue(e,s,r),e.profile=ae(e,c,l,e=>{for(let n=1;n<=a;n++)e(1,t[n]-t[n-1])},i,t[a]-t[0])}function ve(e){let t=-1/0,n=0;for(let r=0;r<e.length;r++){let i=e[r];i>t?t=i:t-i>n&&(n=t-i)}return n}function ye(e,t,n){let r=e.pts,i=r.length,a=ie(t,n);if(a.sampleCount=i,i===0)return a.presentedFrames=0,a;let o=1/0,s=-1/0;for(let e=0;e<i;e++){let t=r[e];t<o&&(o=t),t>s&&(s=t)}let{ws:c,we:l}=R(e.editWindow),d=ge(Float64Array.from(r),c,l),f=e.reorderDepth;if(f===void 0){let t=0;for(let e=1;e<d.length;e++){let n=d[e]-d[e-1];if(n>0){t=n;break}}f=e.ctsRange?j(e.ctsRange.min,e.ctsRange.max,t):j(0,ve(r),t)}a.reorderDepth=f,_e(a,d,1+f,e.tickQuantized??!1),z(a,e.lastDuration);let p=e.lastDuration??a.medianDelta??0;return a.durationSum=s-o+p,a.avgFps=L(t,i,a.durationSum),a.avgFpsString=u(a.avgFps),a.presentedAvgFps=a.avgFps,de(a),a}var be,xe,Se,Ce,we,Te,Ee=t((()=>{m(),y(),be=.001,xe=.005,Se=.15,Ce=Se/2,we=.5,Te=(()=>{let e=[];for(let t of[24,30,48,60,120,240])e.push(d(t*1e3,1001));for(let t=1;t<=240;t++)e.push(d(t,1));return e})()}));function De(e){if(e?.aborted)throw e.reason??new DOMException(`Aborted`,`AbortError`)}function H(e,t){if(!Number.isSafeInteger(e)||e<0)throw RangeError(`${t} must be a non-negative safe integer, got ${e}`)}var Oe=class{size;headWindow;maxWindows;signal;#e;#t=[];#n=[];#r=0;#i=0;constructor(e,t={}){H(e.size,`blob size`),this.#e=e,this.size=e.size,this.headWindow=t.headWindow??65536,this.maxWindows=Math.max(1,t.maxWindows??4),this.signal=t.signal??null,H(this.headWindow,`headWindow`)}get reads(){return this.#r}get bytesFetched(){return this.#i}checkAbort(){De(this.signal)}async read(e,t){if(H(e,`offset`),H(t,`length`),e>this.size)throw RangeError(`offset ${e} is beyond the end of the file (${this.size})`);let n=Math.min(this.size,e+t);if(n===e)return new Uint8Array;this.checkAbort();let r;try{r=await this.#e.slice(e,n).arrayBuffer()}catch(e){throw this.checkAbort(),e?.name===`AbortError`?e:Error(`file read failed: ${e}`)}if(this.checkAbort(),this.#r++,r.byteLength!==n-e)throw Error(`file read failed: short read at ${e}: expected ${n-e} bytes, got ${r.byteLength}`);return this.#a(e,n),new Uint8Array(r)}async readMany(e,t=4){let n=Array(e.length),r=0,i=async()=>{for(;r<e.length;){let t=r++,[i,a]=e[t],o=this.peek(i,a);n[t]=o?new Uint8Array(o.buffer,o.byteOffset,o.byteLength):await this.read(i,a)}},a=[];for(let n=0;n<Math.max(1,Math.min(t,e.length));n++)a.push(i());return await Promise.all(a),n}peek(e,t){let n=Math.min(this.size,e+t);for(let t=0;t<this.#t.length;t++){let r=this.#t[t];if(e>=r.off&&n<=r.off+r.buf.length)return t>0&&(this.#t.splice(t,1),this.#t.unshift(r)),new DataView(r.buf.buffer,r.buf.byteOffset+(e-r.off),n-e)}return null}async view(e,t,n=this.headWindow){if(H(e,`offset`),H(t,`length`),H(n,`readAhead`),e>this.size)throw RangeError(`offset ${e} is beyond the end of the file (${this.size})`);let r=Math.min(this.size,e+t);if(r===e)return new DataView(new ArrayBuffer(0));let i=this.peek(e,r-e);if(i)return i;let a=Math.min(this.size,Math.max(r,e+n)),o=this.#t.find(t=>e>=t.off&&e<t.off+t.buf.length),s;if(o){let t=o.buf.subarray(e-o.off),n=await this.read(o.off+o.buf.length,a-(o.off+o.buf.length));s=new Uint8Array(t.length+n.length),s.set(t,0),s.set(n,t.length)}else s=await this.read(e,a-e);return this.#t.unshift({off:e,buf:s}),this.#t.length>this.maxWindows&&(this.#t.length=this.maxWindows),new DataView(s.buffer,s.byteOffset,r-e)}async bytes(e,t,n=this.headWindow){let r=await this.view(e,t,n);return new Uint8Array(r.buffer,r.byteOffset,r.byteLength)}#a(e,t){let n=this.#n,r=0,i=n.length;for(;r<i;){let t=r+i>>>1;n[t].end<e?r=t+1:i=t}let a=r,o=e,s=t,c=0;for(;a<n.length&&n[a].start<=t;){let r=n[a],i=Math.min(t,r.end)-Math.max(e,r.start);i>0&&(c+=i),r.start<o&&(o=r.start),r.end>s&&(s=r.end),a++}n.splice(r,a-r,{start:o,end:s}),this.#i+=t-e-c}};function ke(e,t){return e.getUint8(t)*65536+e.getUint16(t+1)}function Ae(e,t,n){let r=``;for(let i=0;i<n;i++)r+=String.fromCharCode(e.getUint8(t+i));return r}function U(e,t){return Ae(e,t,4).replace(/[^ -~]/g,`?`)}var W=class extends Error{constructor(e){super(e),this.name=`IsoBmffError`}};function G(e,t,n,r=0){let i=Math.min(e.byteLength,n);if(t+8>i)return null;let a=e.getUint32(t),o=U(e,t+4),s=8,c=a;if(a===1){if(t+16>i)return null;let n=e.getBigUint64(t+8);if(n>BigInt(2**53-1))throw new W(`corrupt file: box '${o}' at ${r+t} has a size above 2^53-1`);c=Number(n),s=16}else a===0&&(c=n-t);if(o===`uuid`&&(s+=16),c<s)throw new W(`corrupt file: box '${o}' at ${r+t} is smaller than its header`);let l=t+c;return{type:o,start:t,size:c,headerSize:s,end:Math.min(l,n),truncated:l>n}}function*K(e,t,n,r){let i=t;for(;i+8<=n;){let t;try{t=G(e,i,n)}catch(e){r?.push(e.message.replace(/^corrupt file: /,`ignored invalid child: `));return}if(!t)return;yield t,i=t.start+t.size}}function q(e,t,n,r){let i=e.getBigUint64(t);if(i>BigInt(2**53-1))throw new W(`unsupported: box '${n}' at ${r} holds a value above 2^53-1`);return Number(i)}function je(e,t,n,r){let i=e.getBigInt64(t);if(i>BigInt(2**53-1)||i<-BigInt(2**53-1))throw new W(`unsupported: box '${n}' at ${r} holds a value beyond 2^53-1`);return Number(i)}function Me(e,t,n,r,i){let a=Math.max(0,Math.floor(t/n));return e>a?(i.push(`${r} declares ${e} entries but its box holds only ${a}`),a):e}let J=null;function Ne(){if(J)return J;J=new Map;for(let e of`rawvideo:raw yuv22vuyyuvs|v210:v210|mjpeg:jpegmjpaAVDJAVRndmb1|mpeg4:mp4vDIVXXVID3IV2|h263:h263s263H263|dvvideo:dvcpdvc dvppdv5pdv5nAVdvAVd1dvhqdvhpdvh1dvh2dvh3dvh4dvh5dvh6|qtrle:rle |cinepak:cvid|svq1:SVQ1svq1svqi|svq3:SVQ3|vvc:vvc1vvi1|hevc:hev1hvc1dvhe|h264:avc1avc2avc3avc4ai5pai5qai52ai53ai55ai56ai1pai1qai12ai13ai15ai16AVinaivxdva1dvav|evc:evc1|vp8:vp08|vp9:vp09|av1:av01|mpeg1video:m1v m1v1mpegmp1v|mpeg2video:m2v1hdv1hdv2hdv3hdv4hdv5hdv6hdv7hdv8hdv9hdvamx5nmx5pmx4nmx4pmx3nmx3pxd51xd54xd55xd59xd5axd5bxd5cxd5dxd5exd5fxdv1xdv2xdv3xdv4xdv5xdv6xdv7xdv8xdv9xdvaxdvbxdvcxdvdxdvexdvfxdhdxdh2AVmpmp2v|jpeg2000:mjp2|png:png MNG |gif:gif |tiff:tiff|vc1:vc-1|cavs:avs2|avs3:avs3|dirac:drac|dnxhd:AVdnAVdh|prores:apchapcnapcsapcoap4hap4x|prores_raw:aprnaprh|hap:Hap1Hap5HapYHapAHapM|cfhd:CFHD|lcevc:lvc1|apv:apv1`.split(`|`)){let t=e.indexOf(`:`),n=e.slice(0,t);for(let r=t+1;r+4<=e.length;r+=4)J.set(e.slice(r,r+4),n)}return J}let Pe={32:`mpeg4`,33:`h264`,35:`hevc`,51:`vvc`,96:`mpeg2video`,97:`mpeg2video`,98:`mpeg2video`,99:`mpeg2video`,100:`mpeg2video`,101:`mpeg2video`,106:`mpeg1video`,108:`mjpeg`,109:`png`,110:`jpeg2000`,163:`vc1`,164:`dirac`,177:`vp9`};function Fe(e){return Ne().has(e)}function Ie(e,t=null,n=!1){return t!==null&&Pe[t]?Pe[t]:e===`dvh1`&&n?`hevc`:Ne().get(e)??`unknown`}let Le=2**53-1,Re=[65536,0,0,0,65536,0,0,0,1<<30];function ze(e){return{fileSize:e,brand:null,compatibleBrands:[],hasFtyp:!1,hasMvhd:!1,timescale:1,duration:0,matrix:Int32Array.from(Re),tracks:[],chapterTrackIds:new Set,hasMvex:!1,trex:new Map,moofCount:0,topLevel:[],truncated:!1,ffprobeMoofLimit:1/0,ffprobeReject:null,warnings:[]}}function Be(){return{id:0,enabled:!1,handler:``,timescale:0,hasMdhd:!1,mdhdDuration:0,matrix:Int32Array.from(Re),sampleEntry:``,originalFormat:null,stsdCount:0,width:0,height:0,esdsObjectType:null,hasHvcc:!1,sttsCounts:new Uint32Array,sttsDeltas:new Uint32Array,cttsCounts:null,cttsOffsets:null,dtsShift:0,sampleCount:null,sampleSize:0,overruns:[],edits:[],fragments:[],warnings:[],dv:null,stss:null,stsz:null,stz2:null,stsc:null,stco:null,co64:null}}let Ve=`no trex: sample defaults taken from tfhd`;function He(e){let t=0;for(let n=256;n<=2048;n<<=1)e&n&&(t+=4);return t}function Ue(e,t,n,r,i,a,o=i+t-8){if(t+8>n)return null;let s=ke(e,t+1),c=e.getUint32(t+4),l=r.trex.get(c),u=t+8,d=e=>u+e<=n,f=s&131072?i:a;if(s&1){if(!d(8))return null;f=q(e,u,`tfhd`,o),u+=8}s&2&&(u+=4);let p=l?l.duration:null;if(s&8){if(!d(4))return null;p=e.getUint32(u),u+=4}let m=l?l.size:0;if(s&16){if(!d(4))return null;m=e.getUint32(u)}return{flags:s,trackId:c,baseDataOffset:f,defaultDuration:p,defaultSize:m,trexMissing:!l}}function We(e,t,n,r,i,a,o,s){let c=ke(e,t+1),l=e.getUint32(t+4),u=t+8,d=i;c&1&&(d=r.baseDataOffset+e.getInt32(u),u+=4),c&4&&(u+=4);let f=He(c),p;f>0?p=Me(l,n-u,f,`trun`,o):(p=l,p>s&&(o.push(`trun count ${l} limited to ${s}`),p=s));let m=f>0&&p<l,h=!!(c&256);if(!h&&r.defaultDuration===null&&p>0)throw new W(`corrupt file: no sample duration for track ${r.trackId}`);let g=r.defaultDuration??0,_=h?new Uint32Array(p):null,v=c&2048?new Int32Array(p):null,y=!!(c&512),b=h?0:g*p,x=d,S=0,C=0;if(f>0)for(let t=0;t<p;t++){if(h){let n=e.getUint32(u);_[t]=n,b+=n,u+=4}let n=r.defaultSize;y&&(n=e.getUint32(u),u+=4),c&1024&&(u+=4),v&&(v[t]=e.getInt32(u),u+=4),x<a&&S++,C===t&&x+n<=a&&C++,x+=n}if(!y){let e=r.defaultSize,t=Math.max(0,a-d);S=e>0?Math.min(p,Math.ceil(t/e)):Math.min(p,t),C=e>0?Math.min(p,Math.floor(t/e)):S,x=d+e*p}return{fragment:{moofIndex:0,baseDts:null,count:p,durations:_,defaultDuration:g,cts:v,durationSum:b,present:S,complete:C,trexMissing:r.trexMissing,overrun:m},dataEnd:x}}function Ge(e,t,n,r,i,a){let o=n,s=!1,c=e=>{i.ffprobeReject||={moof:r,reason:e}},l=new Map;for(let e of i.tracks)l.has(e.id)||l.set(e.id,e);for(let u of K(e,t.start+t.headerSize,t.end,i.warnings)){if(u.type!==`traf`)continue;let t=null,d,f=null,p=0;for(let m of K(e,u.start+u.headerSize,u.end,i.warnings)){let u=m.start+m.headerSize;if(m.type===`tfhd`){if(t=Ue(e,u,m.end,i,n,o,n+m.start),!t)continue;t.trackId===0?c(`rejects this file: tfhd with track_ID 0`):t.trexMissing||(s=!0),p=t.baseDataOffset,d=l.get(t.trackId),d||i.warnings.push(`fragment for unknown track ${t.trackId}`)}else if(m.type===`tfdt`&&u+8<=m.end)f=e.getUint8(u)===1&&u+12<=m.end?q(e,u+4,`tfdt`,n+m.start):e.getUint32(u+4);else if(m.type===`trun`&&u+8<=m.end){if(s?(!t||t.trexMissing)&&c(`misreads this file: a traf without trex is read as another track`):c(`rejects this file: trun without a tfhd that has a trex`),!t||!d)continue;let n=d,{fragment:l,dataEnd:h}=We(e,u,m.end,t,p,i.fileSize,n.warnings,a);l.moofIndex=r,l.baseDts=f,f=null,p=h,o=h,l.trexMissing&&!n.warnings.includes(Ve)&&n.warnings.push(Ve),n.fragments.push(l)}}}}function Ke(e,t,n){let r=t.start+t.headerSize,i=r<t.end&&e.getUint8(r)===1;if(r+(i?32:24)>t.end)throw new W(`corrupt file: box 'sidx' at ${n} is truncated`);let a=r+12,o=i?q(e,a,`sidx`,n):e.getUint32(a),s=i?q(e,a+8,`sidx`,n):e.getUint32(a+4);a+=i?16:8;let c=e.getUint16(a+2);a+=4;let l=n+(t.end-t.start),u=l+s,d=0,f=!1,p=[];for(let n=0;n<c&&a+12<=t.end;n++,a+=12){let t=e.getUint32(a);t&2147483648&&(f=!0);let n=t&2147483647;p.push([u,n]),u+=n,d+=e.getUint32(a+4)}return{start:n,end:l,referenceId:e.getUint32(r+4),timescale:e.getUint32(r+8),earliestPts:o,firstOffset:s,coverageEnd:u,durationSum:d,subsegments:p,hierarchical:f}}function Y(e,t,n,r=0){return qe(K(e,t.start+t.headerSize+r,t.end,n.warnings),n,t.type)}function*qe(e,t,n){for(let r of e){if(r.truncated){if(t.strict)throw new W(`incomplete file: moov is truncated`);t.warnings.push(`'${r.type}' overruns '${n}'`)}yield r}}function X(e){return e.start+e.headerSize}function Je(e,t){let n=new Int32Array(9);for(let r=0;r<9;r++)n[r]=e.getInt32(t+r*4);return n}function Ye(e){return e>0&&e<=2147483647?e:1}function Z(e){return{start:X(e),end:e.end}}function Xe(e,t,n){let r=X(t);if(r+8>t.end)return;let i=e.getUint32(r+4),a=Me(i,t.end-r-8,8,`stts`,n.warnings);a<i&&n.overruns.push(`stts`);let o=new Uint32Array(a),s=new Uint32Array(a),c=!1;for(let t=0;t<a;t++)o[t]=e.getUint32(r+8+t*8),s[t]=e.getUint32(r+12+t*8),s[t]>4294487295&&(c=!0);c&&Ze(o,s,n.warnings),n.sttsCounts=o,n.sttsDeltas=s}function Ze(e,t,n){let r=0n,i=0n;for(let a=0;a<e.length;a++){let o=BigInt(e[a]),s=t[a];if(s>4294487295){n.push(`stts delta ${s} clipped to 1`);let e=s|0;s=1,i+=BigInt(e<0?e:1)*o}else i+=BigInt(s)*o;if(r+=BigInt(s)*o,r>i){let e=(r-i)/(o>0n?o:1n),t=BigInt(s)>e?e:BigInt(s-1>>>0);r-=t*o,s=Number(BigInt(s)-t&4294967295n)}t[a]=s}}function Qe(e,t,n){let r=X(t);if(r+8>t.end)return;let i=e.getUint32(r+4),a=Me(i,t.end-r-8,8,`ctts`,n.warnings);if(a<i&&n.overruns.push(`ctts`),a===0)return;let o=[],s=[],c=0;for(let t=0;t<a;t++){let n=e.getInt32(r+8+t*8),a=e.getInt32(r+12+t*8);n<=0||(o.push(n),s.push(a),t+2<i&&a<0&&(c=Math.max(c,a===-2147483648?2147483647:-a)))}n.cttsCounts=Uint32Array.from(o),n.cttsOffsets=Int32Array.from(s),n.dtsShift=c}function $e(e,t,n,r,i){let a=X(t);if(a+8>t.end)return;let o=e.getUint8(a),s=o===1?20:12,c=e.getUint32(a+4),l=t.end-a-8,u=c*s===l?c:Math.floor(l/s);if(u!==c&&n.warnings.push(`elst declares ${c} entries but its box holds ${u}`),u===0)return;n.edits.length&&(n.warnings.push(`duplicated elst: the last one is used`),n.edits=[]);let d=r.base+t.start;for(let t=0;t<u;t++){let r=a+8+t*s;if(o===1){let t=je(e,r+8,`elst`,d),a=e.getBigInt64(r)===-1n;a&&(n.warnings.push(`unknown elst duration: ${t===-1?`the empty edit is ignored`:`the edit lasts to the end`}`),i.ffprobeReject??={moof:-1,reason:`rejects this file: an elst duration of -1`}),n.edits.push({duration:a?t===-1?0:Le:q(e,r,`elst`,d),mediaTime:t,rate:e.getInt32(r+16)/65536})}else n.edits.push({duration:e.getUint32(r),mediaTime:e.getInt32(r+4),rate:e.getInt32(r+8)/65536})}}function et(e,t,n){let r=t+4,i=()=>{if(r+2>n)return null;let t=e.getUint8(r++),i=0;for(let t=0;t<4&&r<n;t++){let t=e.getUint8(r++);if(i=i*128+(t&127),!(t&128))break}return[t,i]},a=i();if(a&&a[0]===3){if(r+3>n)return null;let t=e.getUint8(r+2);r+=3,t&128&&(r+=2),t&64&&r<n&&(r+=1+e.getUint8(r)),t&32&&(r+=2),a=i()}return a&&a[0]===4&&r<n?e.getUint8(r):null}function tt(e,t,n,r){let i=X(t);if(i+8>t.end||(n.stsdCount=e.getUint32(i+4),n.stsdCount===0))return;let a;try{a=G(e,i+8,t.end)}catch(e){n.warnings.push(e.message);return}if(a&&(n.sampleEntry=a.type,!(n.handler===`soun`||a.start+86>a.end))){n.width=e.getUint16(a.start+32),n.height=e.getUint16(a.start+34);for(let t of K(e,a.start+86,a.end,r.warnings))if(t.type===`esds`)n.esdsObjectType=et(e,X(t),t.end);else if(t.type===`hvcC`)n.hasHvcc=!0;else if(t.type===`sinf`)for(let i of K(e,X(t),t.end,r.warnings))i.type===`frma`&&X(i)+4<=i.end&&(n.originalFormat=U(e,X(i)))}}function nt(e,t,n,r){n.dv=e;for(let i of Y(e,t,r)){let t=X(i);switch(i.type){case`stsd`:tt(e,i,n,r);break;case`stts`:Xe(e,i,n);break;case`ctts`:Qe(e,i,n);break;case`stsz`:case`stz2`:t+12<=i.end&&(n.sampleCount=e.getUint32(t+8),n.sampleSize=i.type===`stsz`?e.getUint32(t+4):0),i.type===`stsz`?n.stsz=Z(i):n.stz2=Z(i);break;case`stss`:n.stss=Z(i),t+8<=i.end&&e.getUint32(t+4)>Math.floor((i.end-t-8)/4)&&n.overruns.push(`stss`);break;case`stsc`:n.stsc=Z(i);break;case`stco`:n.stco=Z(i);break;case`co64`:n.co64=Z(i)}}}function rt(e,t,n,r){for(let i of Y(e,t,r)){let t=X(i);if(i.type===`mdhd`&&t+24<=i.end){let r=e.getUint8(t)===1;if(r&&t+32>i.end)continue;n.hasMdhd=!0;let a=e.getUint32(t+(r?20:12));if(n.timescale=Ye(a),n.timescale!==a&&n.warnings.push(`invalid mdhd timescale ${a}, using 1`),r){let r=e.getBigUint64(t+24);n.mdhdDuration=r===18446744073709551615n?0:Number(r)}else{let r=e.getUint32(t+16);n.mdhdDuration=r===4294967295?0:r}}else if(i.type===`hdlr`&&t+12<=i.end)n.handler=U(e,t+8);else if(i.type===`minf`)for(let t of Y(e,i,r))t.type===`stbl`&&nt(e,t,n,r)}}function it(e,t,n,r){let i=Be();for(let a of Y(e,t,r)){let t=X(a);if(a.type===`tkhd`&&t+84<=a.end){let n=e.getUint8(t)===1;if(n&&t+96>a.end)continue;i.enabled=(e.getUint8(t+3)&1)==1,i.id=e.getUint32(t+(n?20:12)),i.matrix=Je(e,t+(n?52:40))}else if(a.type===`edts`)for(let t of Y(e,a,r))t.type===`elst`&&$e(e,t,i,r,n);else if(a.type===`mdia`)rt(e,a,i,r);else if(a.type===`tref`){for(let t of Y(e,a,r))if(t.type===`chap`)for(let r=X(t);r+4<=t.end;r+=4)n.chapterTrackIds.add(e.getUint32(r))}}return i}function at(e,t,n,r,i=0){let a={strict:r,warnings:n.warnings,base:i};for(let r of Y(e,t,a)){let t=X(r);switch(r.type){case`mvhd`:{if(t+24>r.end)break;let i=e.getUint8(t)===1;if(i&&t+84>r.end)break;n.hasMvhd=!0,n.timescale=Ye(e.getUint32(t+(i?20:12))),n.duration=i?Number(e.getBigUint64(t+24)):e.getUint32(t+16),t+(i?84:72)<=r.end&&(n.matrix=Je(e,t+(i?48:36)));break}case`trak`:n.tracks.push(it(e,r,n,a));break;case`mvex`:n.hasMvex=!0;for(let t of Y(e,r,a)){let r=X(t);t.type===`trex`&&r+24<=t.end&&n.trex.set(e.getUint32(r+4),{duration:e.getUint32(r+12),size:e.getUint32(r+16)})}break;case`cmov`:throw new W(`unsupported: compressed movie header (cmov)`)}}}let ot=new Set([`moof`,`styp`,`sidx`,`ssix`,`emsg`,`prft`,`free`,`skip`,`uuid`]);function st(){return{windows:[],hints:[],next:0,mfraTried:!1}}function ct(e,t,n){for(let[r,i]of e.windows)if(t>=r&&t+n<=r+i.byteLength)return new DataView(i.buffer,i.byteOffset+t-r,n);return null}async function lt(e,t,n,r){for(;t.next<t.hints.length&&t.hints[t.next]<=n;)t.next++;let i=[];for(let n=t.next;n<t.hints.length&&i.length<8;n++)t.hints[n]<e.size&&i.push([t.hints[n],Math.min(r,e.size-t.hints[n])]);if(t.next+=i.length,!i.length)return;let a=await e.readMany(i,4);t.windows=i.map(([e],t)=>[e,new DataView(a[t].buffer,a[t].byteOffset,a[t].byteLength)]),t.windows.every(([,e])=>ut(e))||(t.hints=[],t.next=0)}function ut(e){return e.byteLength>=8&&e.getUint32(0)>=8&&ot.has(U(e,4))}function dt(e,t,n,r,i=2**53-1){for(let a of K(e,t,n)){let t=a.start+a.headerSize;if(a.type!==`tfra`||t+16>a.end)continue;let n=e.getUint8(t)===1,o=e.getUint32(t+8),s=(n?16:8)+(o>>4&3)+(o>>2&3)+(o&3)+3,c=Math.min(e.getUint32(t+12),Math.floor((a.end-t-16)/s));for(let a=0;a<c;a++){let o=t+16+a*s,c=n?e.getBigUint64(o+8):BigInt(e.getUint32(o+4));c>0n&&c<BigInt(i)&&r.add(Number(c))}}}async function ft(e){try{return await pt(e)}catch(t){if(e.signal?.aborted||t?.name===`AbortError`)throw t;return[]}}async function pt(e){let t=e.size,n=Math.min(t,65536);if(n<16)return[];let r=await e.view(t-n,n,0);if(U(r,n-12)!==`mfro`)return[];let i=r.getUint32(n-4);if(i<24||i>Math.min(t,16777216))return[];let a=i<=n?new DataView(r.buffer,r.byteOffset+n-i,i):await e.view(t-i,i,0),o;try{o=G(a,0,i)}catch{return[]}if(!o||o.type!==`mfra`)return[];let s=new Set;return dt(a,o.headerSize,o.end,s,t),[...s].sort((e,t)=>e-t)}m();function Q(e,t,n){if(!(n>0))return 0;let r=BigInt(Math.abs(e))*BigInt(t),i=BigInt(n),a=Number((r+i/2n)/i);return e<0?-a:a}function mt(e){let t=0,n=0;for(let r=0;r<e.sttsCounts.length;r++)t+=e.sttsCounts[r],n+=e.sttsCounts[r]*e.sttsDeltas[r];let r=0;for(let t of e.fragments)r+=t.count;return{moovSamples:t,moovDuration:n,fragmentSamples:r}}function ht(e,t,n){let r=0n,i=0n;if(n){for(let t=0;t<e.sttsCounts.length;t++)r+=BigInt(e.sttsCounts[t]),i+=BigInt(e.sttsCounts[t])*BigInt(e.sttsDeltas[t]);i<=0n&&(r=0n,i=0n)}for(let n of e.fragments)t(n.moofIndex,n.trexMissing)&&(r+=BigInt(n.count),i+=BigInt(n.durationSum));return[r,i]}function gt(e,t,n){return t<=0n||n<=0n?null:f(BigInt(e)*t,n,p)}function _t(e,t){let n=e.timescale,r=(e,n)=>e<t.ffprobeMoofLimit&&!n,[i,a]=ht(e,()=>!0,!0),[o,s]=ht(e,r,!0),c=e.overruns.includes(`stts`)||e.fragments.some(e=>e.overrun&&r(e.moofIndex,e.trexMissing))?null:gt(n,o,s);return{avg:gt(n,i,a),ffprobe:c?u(c):null}}function vt(e){let t=e.dv,n=e=>t&&e&&e.start+8<=e.end?t.getUint32(e.start+4):0,r=n(e.co64??e.stco),i=e.sttsCounts.length>0||e.overruns.includes(`stts`),a=e.sampleCount??0;return r>0&&(!i||n(e.stsc)===0||e.sampleSize===0&&a===0)||a>0&&r===0}function yt(e,t,n){let r=0,i=0,a=0,o=null,s=(e.cttsOffsets?.[0]??0)+n.moovDuration;for(let n of e.edits){let c=n.duration===Le?Math.max(0,s-n.mediaTime):Q(n.duration,e.timescale,t);i+=c,n.mediaTime===-1?o||(r+=c):(a++,o||={mediaTime:n.mediaTime,duration:c,rate:n.rate})}return{emptyBefore:r,firstMedia:o,editSum:i,mediaEdits:a}}function bt(e,t,n,r){let i=e.mdhdDuration;n.moovDuration>0&&(i=Math.min(i,n.moovDuration));let a=e.edits.length>0&&n.moovSamples>0;a&&(i=Math.min(i,r.editSum));let o=n.moovDuration,s=null,c=St(e,t);for(let t of e.fragments)t.baseDts!==null&&(o=t.baseDts),s===null&&t.count>0&&(s=o-c+(t.cts?t.cts[0]:0)),o+=t.durationSum,o>i&&(i=o);let l=xt(e,t);l!==null&&l>i&&(i=l);let u=null;return u=a?r.emptyBefore:n.moovSamples>0?e.cttsOffsets&&e.cttsOffsets.length?e.cttsOffsets[0]:0:s,{durationTs:i,startPts:u}}function xt(e,t){if(t.ffprobeMoofLimit===1/0)return null;let n=0,r=null;for(let i of t.topLevel){if(i.type===`moof`&&++n>t.ffprobeMoofLimit)break;let a=i.sidx;a&&!a.hierarchical&&a.referenceId===e.id&&a.timescale===e.timescale&&(r=a.earliestPts+a.durationSum)}return r}function St(e,t){let n=0,r=0,i=0;return e.edits.forEach((e,t)=>{t===0&&e.mediaTime===-1?(n=e.duration,i=1):t===i&&e.mediaTime>=0&&(r=e.mediaTime)}),!n&&!r?0:r-Q(n,e.timescale,t.timescale)}function Ct(e,t,n){let r=new Float64Array(e.length+1),i=new Float64Array(e.length),a=0,o=0;for(let s=0;s<e.length&&o<n;s++)e[s]<=0||(r[a]=o,i[a]=t[s],o+=Math.min(e[s],n-o),a++);return r[a]=o,{count:a,starts:r,values:i,total:o}}function wt(e){let t=e.starts,n=0;return r=>{if(r>=t[n]&&r<t[n+1])return n;let i=0,a=e.count-1;for(;i<a;){let e=Math.ceil((i+a)/2);t[e]<=r?i=e:a=e-1}return n=i,i}}function Tt(e,t){let n=e.stss;if(!n||!e.dv)return{all:!0,list:new Float64Array};let r=e.dv,i=n.start+8<=n.end?Math.min(r.getUint32(n.start+4),Math.floor((n.end-n.start-8)/4)):0;if(i===0)return{all:!1,list:Float64Array.of(0)};let a=+(r.getUint32(n.start+8)>0),o=new Float64Array(i),s=0,c=-1;for(let e=0;e<i;e++){let i=r.getUint32(n.start+8+e*4)-a;if(i<=c||i>=t)break;o[s++]=i,c=i}return{all:!1,list:o.subarray(0,s)}}function Et(e,t,n){if(n>=t)return-1;if(e.all)return n;let r=e.list,i=0,a=r.length;for(;i<a;){let e=Math.floor((i+a)/2);r[e]<n?i=e+1:a=e}return i<r.length?r[i]:-1}function Dt(e,t){if(t<0)return-1;if(e.all)return t;let n=e.list,r=0,i=n.length;for(;r<i;){let e=Math.floor((r+i)/2);n[e]<=t?r=e+1:i=e}return r>0?n[r-1]:-1}function Ot(e,t,n){let r=n;r<=0||e.len===0&&(e.first=t,e.last=t,e.len=1,r--,r===0)||((e.len>=2&&e.last!==e.first||r>=2&&t!==e.first)&&(e.bad=!0),e.last=t,e.len+=r)}function kt(e,t,n,r,i){let a=r,o=Math.min(i,t.total-r),s=0;for(;o>0&&!e.bad;){let r=n(a),i=Math.min(t.starts[r+1]-a,o);Ot(e,t.values[r],i),a+=i,o-=i,s++}return s}function At(e,t){return e.bad||e.len===0||!(e.first>0)?null:f(t,e.first,p)}function jt(e,t,n,r,i){let a=Math.min(n,e.sampleCount??0);if(a<=0||e.sttsCounts.length===0||e.overruns.length>0)return null;let o=e.timescale,s=Ct(e.sttsCounts,e.sttsDeltas,a),c=wt(s),l={len:0,first:0,last:0,bad:!1};if(e.edits.length===0)return kt(l,s,c,0,a),At(l,o);if(!e.edits.some(e=>e.mediaTime!==-1))return null;let u=!0;for(let e=1;e<s.count&&u;e++)u=s.values[e]===s.values[0];if(u)return s.values[0]>0?f(o,s.values[0],p):null;let d=Math.min(r,2e6),m=0,h=!1,g=e=>(m+=e,m>d&&(h=!0),h),_=new Float64Array(s.count+1);for(let e=0;e<s.count;e++)_[e+1]=_[e]+(s.starts[e+1]-s.starts[e])*s.values[e];let v=e=>{let t=c(e);return _[t]+(e-s.starts[t])*s.values[t]},y=e=>s.values[c(e)],b=!!e.cttsCounts&&e.cttsCounts.length>0,x=b?Ct(e.cttsCounts,e.cttsOffsets,a):null,S=x?wt(x):null,C=e=>x&&e<x.total?x.values[S(e)]:0,w=Tt(e,a),T=e=>Et(w,a,e),E=e=>Dt(w,e),D=e.dtsShift,ee=(e,t)=>{let n=0,r=t;for(;n<r;){let t=Math.floor((n+r)/2);v(t)>=e?r=t:n=t+1}return n},O=(e,t)=>{let n=D>0?e-D:e,r=-1,i=a;for(v(a-1)-D<n&&(r=a-1);i-r>1;){let e=Math.floor((r+i)/2),t=v(e)-D;t>=n&&(i=e),t<=n&&(r=e)}let o=t?r:E(r);if(o>0){let e=ee(v(o),o);if(e<o){if(t)o=e;else{let t=T(e);t>=0&&t<o&&(o=t)}}}if(b&&o>=0){let e=E(o);for(;e>=0&&!g(1)&&v(e)-D+C(e)>n;)e=E(e-1);o=e}return o},k=0,A=!1;for(let n of e.edits){let r=n.mediaTime;if(!A&&r===-1)continue;if(A=!0,g(64))break;let i=Q(n.duration,e.timescale,t.timescale),o=O(r,!1);if(o<0&&!h&&(o=O(r,!0)),h)break;o<0&&(o=0,k=0),b&&(k=o);let u=-1;if(b){let e=!1;for(let t=T(o);t>=0&&!g(1);t=T(t+1)){let n=t+1<a?y(t):i;if(v(t)+C(t)+n>=i+r){if(e){u=t;break}e=!0}}if(h)break}else{let e=o,t=a;for(;e<t;){let n=Math.floor((e+t)/2);(n+1<a?v(n+1):v(a-1)+i)>=i+r?t=n:e=n+1}e<a&&(u=T(e))}let d=u<0?a-o:u-o+1,f=Math.min(d,a-k);if(f>0&&(g(kt(l,s,c,k,f)),k+=f),l.bad)return null;if(h)break}return h?(i?.push(`r_frame_rate not reproduced: edit list walk limit reached`),null):At(l,o)}function Mt(e,t,n){let r=[],i=[],a=n;for(let n=0;n<e.length&&a>0;n++){let o=Math.min(e[n],a);o<=0||(r.push(o),i.push(t[n]),a-=o)}return{counts:r,values:i}}function Nt(e,t){let n=[];if(t>0){let r=Mt(e.sttsCounts,e.sttsDeltas,t),i=e.cttsCounts&&e.cttsOffsets?Mt(e.cttsCounts,e.cttsOffsets,t):null;n.push({durations:{counts:r.counts,deltas:r.values},cts:i?{counts:i.counts,offsets:i.values}:null})}for(let t of e.fragments){let e=t.complete;n.push({baseDts:t.baseDts,durations:t.durations?t.durations.subarray(0,e):{counts:[e],deltas:[t.defaultDuration]},cts:t.cts?t.cts.subarray(0,e):null})}return n}function Pt(e,t,n){let r=t.firstMedia;if(!r)return e.edits.length&&n.push(`edit list has no media edit`),null;t.mediaEdits>1&&n.push(`edit list has ${t.mediaEdits} media edits, only the first is applied`),r.rate!==1&&n.push(`edit rate ${r.rate} is not applied`);let i=e.fragments.length>0||r.duration<=0?r.mediaTime:r.mediaTime+r.duration;return{start:r.mediaTime,end:i}}function Ft(e,t,n){let r=e.dv,i=e.co64??e.stco,a=e.stsz??e.stz2;if(!r||!i||!a||!e.stsc||i.start+8>i.end||e.stsc.start+8>e.stsc.end||a.start+12>a.end)return null;let o=!!e.co64,s=Math.min(r.getUint32(i.start+4),Math.floor((i.end-i.start-8)/(o?8:4))),c=Math.min(r.getUint32(e.stsc.start+4),Math.floor((e.stsc.end-e.stsc.start-8)/12)),l=e.stsz?r.getUint32(a.start+4):0,u=e.stz2?r.getUint8(a.start+7):32,d=Math.min(r.getUint32(a.start+8),n),f=a.end-a.start-12,p=e=>{if(l)return l;let t=a.start+12;if(u===32)return(e+1)*4<=f?r.getUint32(t+e*4):0;if(u===16)return(e+1)*2<=f?r.getUint16(t+e*2):0;if(u===8)return e<f?r.getUint8(t+e):0;let n=e>>1<f?r.getUint8(t+(e>>1)):0;return e&1?n&15:n>>4},m=0,h=0,g=0,_=0;for(let n=0;n<s&&g<d;n++){for(;_+1<c&&r.getUint32(e.stsc.start+8+(_+1)*12)<=n+1;)_++;let a=c?r.getUint32(e.stsc.start+12+_*12):0,s=o?Number(r.getBigUint64(i.start+8+n*8)):r.getUint32(i.start+8+n*4);for(let e=0;e<a&&g<d;e++,g++){let e=p(g);s<t&&m++,s+e<=t&&h===g&&h++,s+=e}}return{present:m,complete:h}}function It(e,t){let n=[16n,16n,30n],r=new Int32Array(9);for(let i=0;i<3;i++)for(let a=0;a<3;a++){let o=0n;for(let r=0;r<3;r++)o+=BigInt(e[i*3+r])*BigInt(t[r*3+a])>>n[r];r[i*3+a]=Number(BigInt.asIntN(32,o))}if(r[0]===65536&&r[4]===65536&&r[8]===1<<30&&!r[1]&&!r[2]&&!r[3]&&!r[5]&&!r[6]&&!r[7])return 0;let i=r[0]/65536,a=r[1]/65536,o=Math.hypot(i,r[3]/65536),s=Math.hypot(a,r[4]/65536);return o===0||s===0?0:Math.trunc(-(Math.atan2(a/s,i/o)*180/Math.PI))||0}Ee(),m();let Lt=65536;function Rt(e,t){return t.signal?.aborted===!0||e?.name===`AbortError`}function zt(e){return e.brand===`qt `||!e.hasFtyp&&e.topLevel.length>0?`mov`:`mp4`}async function Bt(e,t,n){let r=e.size,i=t.start+t.size>r;if(!i&&t.size>268435456)throw new W(`unsupported: moov larger than 256 MiB`);let a=i?Math.min(r-t.start,16777216):t.size,o=await e.view(t.start,a,0),s=G(o,0,o.byteLength);if(!s)throw new W(`incomplete file: moov is truncated`);at(o,s,n,i,t.start),i&&n.warnings.push(`moov size exceeds the file; parsed what is there`)}async function Vt(e,t,n){let r=e.size,i=0,a=t.readAhead.head,o=!1,s=0,c=!1,l=st(),u=async(t,n,r)=>ct(l,t,n)??e.view(t,n,r);for(;i+8<=r;){if(e.checkAbort(),++s>4e6){n.warnings.push(`too many top-level boxes`);break}let d=c&&!o&&r-i<=16777216?r-i:a,f=await u(i,Math.min(16,r-i),d),p;try{p=G(f,0,r-i,i)}catch(e){if(!o)throw e;n.warnings.push(`ignored trailing data at ${i}: ${e.message}`);break}if(!p)break;let m={...p,start:i,end:Math.min(i+p.size,r)},h=i+p.size,g=p.truncated&&o&&m.type!==`mdat`&&m.type!==`moof`;p.truncated&&(n.truncated=!0,n.warnings.push(g?`ignored trailing data at ${i}: not a box`:`'${m.type}' at ${i} is truncated`));let _={type:m.type,start:i,end:m.end,sidx:null};if(n.topLevel.push(_),g)break;if(m.type===`ftyp`){let t=await e.view(i,Math.min(m.size,1024)),r=m.headerSize;if(r+4<=t.byteLength){n.hasFtyp=!0,n.brand=String.fromCharCode(t.getUint8(r),t.getUint8(r+1),t.getUint8(r+2),t.getUint8(r+3));for(let e=r+8;e+4<=t.byteLength;e+=4)n.compatibleBrands.push(String.fromCharCode(t.getUint8(e),t.getUint8(e+1),t.getUint8(e+2),t.getUint8(e+3)))}}else if(m.type===`moov`)o?n.warnings.push(`ignored a second moov at ${i}`):(await Bt(e,m,n),o=!0);else if(m.type===`moof`){if(!o)throw new W(`corrupt file: movie fragment (moof) before moov`);if(m.size>67108864)throw new W(`corrupt file: moof larger than 64 MiB at ${i}`);let s=Math.min(m.size+16,r-i),c=await u(i,s,0),d=G(c,0,Math.min(m.size,c.byteLength));d&&Ge(c,d,i,n.moofCount,n,t.maxExpandedSamples),n.moofCount++;let f=0;try{let e=G(c,m.size,c.byteLength);e&&e.type===`mdat`&&(f=e.size)}catch{f=0}a=f<=Lt?t.readAhead.fragment:Math.min(65536,Math.max(1024,2*m.size+64)),f>Lt&&(!l.hints.length&&!l.mfraTried&&(r-i)/(m.size+f)>16&&(l.mfraTried=!0,l.hints=await ft(e)),l.next<l.hints.length&&!ct(l,i+m.size+f,16)&&await lt(e,l,i,a)),t.onProgress&&n.moofCount%64==0&&t.onProgress({phase:`fragments`,done:i,total:r})}else if(m.type===`sidx`&&!p.truncated){let e=await u(i,m.size,0),t=G(e,0,e.byteLength);t&&(_.sidx=Ke(e,t,i)),_.sidx&&_.sidx.subsegments.length>1&&!l.hints.length&&(l.hints=_.sidx.subsegments.map(([e])=>e))}else if(m.type===`mfra`)break;c=m.type===`mdat`,i=h}if(!o)throw new W(`incomplete file: no moov`)}async function Ht(e,t){let n=e.size,r=new Set(t.tracks.map(e=>e.id)),i=!1,a=!1,o=!1,s=null,c=0;for(let l of t.topLevel){if(l.type===`moof`)c++;else if(l.type===`moov`)i=!0;else if(l.type===`mdat`&&l.end-l.start>8)a=!0;else if(l.type===`sidx`&&i&&l.sidx&&!l.sidx.hierarchical&&r.has(l.sidx.referenceId)){let t=l.sidx.coverageEnd===n;!t&&n>=4&&(s===null&&(s=(await e.view(n-4,4,0)).getUint32(0)),t=l.sidx.coverageEnd===n-s),t&&l.sidx.firstOffset===0&&(o=!0)}if(i&&a&&(o||l.end===n)){t.ffprobeMoofLimit=c;return}}}function Ut(e,t){return t.chapterTrackIds.has(e.id)?!1:e.handler===`vide`||e.handler!==`soun`&&Fe(e.originalFormat??e.sampleEntry)}function Wt(e,t,n,r){let a=i(r.reportedId),o=a.warnings;r.reportedId!==e.id&&o.push(`duplicate track_ID ${e.id}: reported as ${r.reportedId}`),o.push(...e.warnings);let s=e.handler===`auxv`;s&&o.push(`auxiliary video track (handler 'auxv')`);let c=vt(e);c&&o.push(`missing mandatory sample tables: ffprobe ignores the samples and timing of this track`);let l=e.hasMdhd?e.timescale:t.timescale;e.hasMdhd||(o.push(`no mdhd: using the movie timescale`),e.timescale=l),a.fourccOrCodecId=e.sampleEntry,a.codecName=Ie(e.originalFormat??e.sampleEntry,e.esdsObjectType,e.hasHvcc),e.originalFormat&&o.push(`encrypted: ${e.sampleEntry} of ${e.originalFormat}`),e.stsdCount>1&&o.push(`${e.stsdCount} sample descriptions, first used`),a.width=e.width,a.height=e.height,a.rotation=It(e.matrix,t.matrix),a.timescale=l;let d=mt(e),f=t.truncated,p=0;for(let t of e.fragments)p+=t.present;let m=d.moovSamples+d.fragmentSamples,h=d.moovSamples+p;a.frames=h,a.isStill=h<=1,d.moovSamples>0&&e.fragments.length>0&&o.push(`hybrid fragmented file: moov holds ${d.moovSamples} of ${m} samples`),h<m&&o.push(`truncated: ${m-h} of ${m} samples missing`);let g=_t(e,t);a.avgFps=g.avg,a.avgFpsFfprobe=r.ffprobeFails?null:g.ffprobe,a.avgFpsFfprobe!==null&&a.avgFpsFfprobe!==u(g.avg)&&o.push(`ffprobe reads part of the fragments: avg_frame_rate ${a.avgFpsFfprobe}`),g.ffprobe===null&&!r.ffprobeFails&&m>0&&o.push(`avg_frame_rate of ffprobe is not reproduced: its header values are incomplete or overrun a box`);let _=r.ffprobeFails||c?null:jt(e,t,d.moovSamples,n.maxExpandedSamples,o);a.rFpsFfprobe=_?u(_):null;let v=yt(e,t.timescale,d);if(!c){let n=bt(e,t,d,v);a.durationSec=n.durationTs/l,a.startSec=n.startPts===null?null:n.startPts/l}let y=d.moovSamples;if(e.sampleCount!==null&&e.sampleCount<y&&(o.push(`stts describes ${y} samples but the sample size table holds ${e.sampleCount}`),y=e.sampleCount),c)return a.presentedFrames=0,Gt(a),{result:a,enabled:e.enabled,auxiliary:s};if(f&&y>0){let n=Ft(e,t.fileSize,d.moovSamples);n&&n.complete<y&&(o.push(`truncated: ${n.complete} of ${y} samples complete`),y=n.complete)}let b=Pt(e,v,o);b&&!e.cttsCounts&&!e.fragments.length&&b.start<=0&&(b.end<=b.start||b.end>=d.moovDuration)&&(b=null);let x=N({segments:Nt(e,y),timescale:l,editWindow:b,maxExpandedSamples:n.maxExpandedSamples});return o.push(...x.warnings),a.presentedFrames=x.presentedFrames,a.minFps=x.minFps,a.maxFps=x.maxFps,a.isVfr=x.isVfr,a.vfrRatio=x.vfrRatio,a.distinctDeltas=x.distinctDeltas,a.duplicateTimestamps=x.duplicateTimestamps,a.nominalFps=x.nominalFps,a.dominantFps=x.dominantFps,a.timestampsQuantized=x.timestampsQuantized,x.presentedAvgFps&&(a.avgFps=x.presentedAvgFps),a.duplicateTimestamps>0&&o.push(`${a.duplicateTimestamps} duplicate timestamps`),Gt(a),x.presentedAvgFps&&(a.provenance.avgFps=`exact`),{result:a,enabled:e.enabled,auxiliary:s,profile:x.profile}}function Gt(e){let t=e.provenance;for(let e of[`codec`,`dimensions`,`rotation`,`frames`,`avgFps`])t[e]=`header`;e.durationSec!==null&&(t.durationSec=`header`),e.startSec!==null&&(t.startSec=`header`),e.presentedFrames!==null&&(t.presentedFrames=`exact`),e.isVfr!==null&&(t.minFps=`exact`,t.maxFps=`exact`,t.isVfr=`exact`,t.duplicateTimestamps=`exact`),e.nominalFps&&(t.nominalFps=`exact`),e.dominantFps&&(t.dominantFps=`exact`)}function Kt(e){let t=null,n=e=>(e.result.frames??0)>1?e.auxiliary?.5:e.enabled?2:1:0;for(let r of e)(!t||n(r)>n(t)||n(r)===n(t)&&(r.result.frames??0)>(t.result.frames??0))&&(t=r);return t?t.result.trackId:null}function qt(e,t){let n=2**53-1,r=n,i=n,a=-n,o=-n,s=-n,c=-n;for(let n of e.tracks){if(!n.hasMdhd)continue;let l=t.has(n)||n.handler===`soun`;if(vt(n)){let e=Q(n.mdhdDuration,1e6,9e4);l?s=Math.max(s,e):c=Math.max(c,e);continue}let u=mt(n),d=bt(n,e,u,yt(n,e.timescale,u)),f=Q(d.durationTs,1e6,n.timescale);if(d.startPts!==null){let e=Q(d.startPts,1e6,n.timescale);l?(r=Math.min(r,e),a=Math.max(a,e+f)):(i=Math.min(i,e),o=Math.max(o,e+f))}l?s=Math.max(s,f):c=Math.max(c,f)}return(r===n||r>i&&r-i<1e6)&&(r=i),(a===-n||a<o&&o-a<1e6)&&(a=o),(s===-n||s<c&&c-s<1e6)&&(s=c),r!==n&&a!==-n&&a>=r&&(s=Math.max(s,a-r)),s>0?s/1e6:null}function Jt(e){let t=new Map,n=new Set,r=e.reduce((e,t)=>Math.max(e,t.id),0)+1;for(let i of e)n.has(i.id)?t.set(i,r++):(n.add(i.id),t.set(i,i.id));return t}async function Yt(e,t){let n=ze(e.size),i=t=>{if(Rt(t,e))throw t;let i=t instanceof Error?t.message:String(t),a=r(zt(n),t instanceof W||i.startsWith(`file read failed`)?i:`corrupt file: ${i}`);return a.brand=n.brand,a.warnings=n.warnings,{analysis:a,movie:n}};try{await Vt(e,t,n),await Ht(e,n);let i=r(zt(n));i.brand=n.brand,i.scan=`exact`,i.warnings=n.warnings;let a=n.ffprobeReject,o=a!==null&&a.moof<n.ffprobeMoofLimit;o&&n.warnings.push(`ffprobe 8.1.1 ${a.reason}`);let s=Jt(n.tracks);[...s].some(([e,t])=>e.id!==t)&&n.warnings.push(`duplicate track_ID values`);let c=n.tracks.filter(e=>Ut(e,n)),l=c.map(e=>Wt(e,n,t,{reportedId:s.get(e)??e.id,ffprobeFails:o}));for(let e of l)e.result.rateProfile=await ce(e.profile??null);return i.videoTracks=l.map(e=>e.result),i.audioTrackCount=n.tracks.filter(e=>e.handler===`soun`).length,i.primaryTrackId=Kt(l),i.formatDurationSec=qt(n,new Set(c)),{analysis:i,movie:n}}catch(e){return i(e)}}async function Xt(e,t){return(await Yt(e,t)).analysis}let Zt=new Set([`ftyp`,`moov`,`mdat`,`free`,`skip`,`wide`,`pnot`,`uuid`,`moof`,`styp`,`sidx`]),Qt=[26,69,223,163],$t=[{bytes:[137,80,78,71,13,10,26,10],offset:0,label:`PNG image`},{bytes:[255,216,255],offset:0,label:`JPEG image`},{bytes:[71,73,70,56],offset:0,label:`GIF image`},{bytes:[82,73,70,70],offset:0,label:`RIFF file (AVI/WAV/WebP)`},{bytes:[79,103,103,83],offset:0,label:`Ogg file`},{bytes:[70,76,86,1],offset:0,label:`FLV file`},{bytes:[0,0,1,186],offset:0,label:`MPEG program stream`},{bytes:[37,80,68,70],offset:0,label:`PDF document`},{bytes:[80,75,3,4],offset:0,label:`ZIP archive`},{bytes:[73,68,51],offset:0,label:`MP3 file`}];function en(e,t,n){if(e.length<n+t.length)return!1;for(let r=0;r<t.length;r++)if(e[n+r]!==t[r])return!1;return!0}function tn(e){for(let t=4;t<8;t++){let n=e[t];if(n<32||n>126)return!1}return!0}function nn(e){let t=Math.min(e.length,512);if(t===0)return!1;for(let n=0;n<t;n++){let t=e[n];if(t!==9&&t!==10&&t!==13&&(t<32||t===127))return!1}return!0}function rn(e){for(let t of $t)if(en(e,t.bytes,t.offset))return t.label;return e.length>=188&&e[0]===71&&e[188]===71?`MPEG transport stream`:nn(e)?`text file`:`no known signature`}function an(e){if(e.length===0)return{kind:`unknown`,reason:`empty file`};if(en(e,Qt,0))return{kind:`matroska`,reason:`EBML header 1A45DFA3`};if(e.length>=8&&tn(e)){let t=String.fromCharCode(e[4],e[5],e[6],e[7]);if(Zt.has(t)){let n=e[0]*16777216+e[1]*65536+e[2]*256+e[3];if(n===0)return{kind:`isobmff`,reason:`top-level '${t}' box running to end of file`};if(n>=8)return{kind:`isobmff`,reason:`top-level '${t}' box`};if(n===1){if(e.length<16)return{kind:`unknown`,reason:`'${t}' box with a truncated 64-bit size`};let n=0;for(let t=8;t<16;t++)n=n*256+e[t];if(n>=16)return{kind:`isobmff`,reason:`top-level '${t}' box with 64-bit size`}}return{kind:`unknown`,reason:`'${t}' box with invalid size ${n}`}}}return e.length<8?{kind:`unknown`,reason:`too small (${e.length} bytes)`}:{kind:`unknown`,reason:rn(e)}}async function on(e){let{kind:t}=an(new Uint8Array(await e.slice(0,Math.min(1024,e.size)).arrayBuffer()));return t===`unknown`?null:t}y();function sn(e,t){let{perReadMs:n,bytesPerMs:r}=t.costModel,i=t.readAhead.head;return e<Math.max(i,Math.min(i+n*r,1048576))?e:i}function cn(e){return e?.name===`AbortError`}function ln(e){return e instanceof Error?e.message||e.name:String(e)}function un(e,t){e.container=t.container,e.brand=t.brand,e.formatDurationSec=t.formatDurationSec,e.scan=t.scan,e.videoTracks=t.videoTracks,e.audioTrackCount=t.audioTrackCount,e.primaryTrackId=t.primaryTrackId,e.error=t.error,e.warnings=t.warnings}async function dn(e,t,n,i){let a=performance.now(),o=g(n);De(o.signal);let s={name:t,size:e.size,...r(`unknown`),io:{reads:0,bytesRead:0,ms:0},engine:`own`},c=null,l=0;try{if(c=new Oe(e,{headWindow:o.readAhead.head,signal:o.signal}),c.size===0)s.error=`not a recognised container: empty file`;else{let e=an(await c.bytes(0,Math.min(1024,c.size),sn(c.size,o)));if(e.kind===`unknown`)s.error=`not a recognised container: ${e.reason}`;else{s.container=e.kind===`isobmff`?`mp4`:`matroska`;let t=performance.now(),n=await i(e.kind);l=performance.now()-t,un(s,await n(c,o))}}}catch(e){if(o.signal?.aborted||cn(e))throw e;s.error=ln(e)}return c&&(s.io.reads=c.reads,s.io.bytesRead=c.bytesFetched),s.io.ms=performance.now()-a-l,s}let $=(e,t)=>Object.assign(Error(e),{code:t}),fn=e=>e===`isobmff`||e===`matroska`;function pn(e){let t=self,n=new Map,r=new Map,i=e=>t.postMessage({v:1,...e}),a=t=>{let r=n.get(t);if(!r){let i=Object.hasOwn(e,t)?e[t]:void 0;if(!i)return Promise.reject($(`unknown engine ${t}`,`unknown-engine`));r=(typeof i==`function`?Promise.all([i(),Promise.resolve().then(()=>(Ee(),O))]).then(([e])=>e):Promise.resolve(i)).catch(e=>{throw n.delete(t),e}),n.set(t,r)}return r},o=(e,t,n=!1,r=!1)=>{let a=t?.code,o=a===`unknown-engine`||a===`protocol`;i({type:`error`,id:e,message:ln(t),aborted:n||cn(t),...o?{code:a}:r&&{reason:`load`}})},s=async e=>{let t=new AbortController;r.set(e.id,t);let n=0,s=!0;try{if(!(e.file instanceof Blob))throw $(`malformed analyze request`,`protocol`);let r=await a(e.engine);if(s=!1,r.containers!==`any`){let t=await on(e.file);if(!t||!r.containers.includes(t))return i({type:`skipped`,id:e.id,reason:`unsupported-container`,family:t})}let o=await r.run(e.file,e.name,{...e.options,signal:t.signal,onProgress:t=>{let r=performance.now();r-n<50||(n=r,i({type:`progress`,id:e.id,progress:t}))}});i({type:`result`,id:e.id,result:o})}catch(n){o(e.id,n,t.signal.aborted,s)}finally{r.delete(e.id)}},c=async e=>{try{if(![e.engines,e.containers].every(Array.isArray)||!e.containers.every(fn))throw $(`malformed warm request`,`protocol`);await Promise.all(e.engines.map(async t=>(await a(t)).warm?.(e.containers))),i({type:`warmed`,id:e.id})}catch(t){o(e.id,t,!1,!0)}};t.onmessage=({data:e})=>{if(e?.v!==1)return o(e?.id??0,$(`unsupported protocol version ${e?.v}`,`protocol`));if(e.type===`cancel`)r.get(e.id)?.abort();else if(e.type===`analyze`)s(e);else if(e.type===`warm`)c(e);else{let t=e;o(t.id,$(`unknown request type ${t.type}`,`protocol`))}}}let mn={isobmff:`ISO BMFF`,matroska:`Matroska`},hn=(e,t)=>`the own ${mn[e]} worker does not read ${mn[t]}`;function gn(e,t){return{containers:`any`,run:(n,r,i)=>dn(n,r,i,n=>{if(n!==e)throw Error(hn(e,n));return t})}}pn({own:gn(`isobmff`,Xt)})})();