@poe-platform/safe-bash 0.1.830 → 0.1.831

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.
@@ -18,6 +18,7 @@ export interface ParsedH264Sps {
18
18
  readonly sarHeight: number;
19
19
  readonly fps?: number | undefined;
20
20
  readonly maxNumRefFrames: number;
21
+ readonly maxNumReorderFrames?: number | undefined;
21
22
  }
22
23
  export declare function parseH264Sps(nalu: Uint8Array): ParsedH264Sps;
23
24
  export declare function parseAvcC(payload: Uint8Array): Mp4AvcCConfig;
@@ -171,6 +171,7 @@ export interface MediaCodecDescription {
171
171
  readonly codecTagString?: string | undefined;
172
172
  readonly profile?: string | undefined;
173
173
  readonly level?: number | undefined;
174
+ readonly maxNumReorderFrames?: number | undefined;
174
175
  readonly width?: number | undefined;
175
176
  readonly height?: number | undefined;
176
177
  readonly pixFmt?: string | undefined;
@@ -12,7 +12,7 @@ import {
12
12
  probeOggStreamMetadata,
13
13
  scanMp4Frames,
14
14
  scanMp4Packets
15
- } from "./chunk-BXOBM4HJ.js";
15
+ } from "./chunk-R6PMUP4E.js";
16
16
 
17
17
  // packages/safe-bash-command-ffprobe/src/probe-text.ts
18
18
  import { yieldTurn } from "../../safe-bash-contracts/yield.js";
@@ -332075,6 +332075,7 @@ function parseH264Sps(nalu) {
332075
332075
  let sarWidth = 1;
332076
332076
  let sarHeight = 1;
332077
332077
  let fps;
332078
+ let maxNumReorderFrames;
332078
332079
  const vuiPresent = bits.readBit();
332079
332080
  if (vuiPresent && bits.bitsRemaining > 0) {
332080
332081
  const aspectRatioInfoPresent = bits.readBit();
@@ -332108,10 +332109,34 @@ function parseH264Sps(nalu) {
332108
332109
  if (timingInfoPresent && bits.bitsRemaining >= 64) {
332109
332110
  const numUnitsInTick = bits.readBits(32);
332110
332111
  const timeScale = bits.readBits(32);
332112
+ bits.readBit();
332111
332113
  if (numUnitsInTick > 0 && timeScale > 0) {
332112
332114
  fps = timeScale / (2 * numUnitsInTick);
332113
332115
  }
332114
332116
  }
332117
+ let hrdPresent = false;
332118
+ for (let kind = 0; kind < 2; kind++) {
332119
+ if (!bits.readBit()) continue;
332120
+ hrdPresent = true;
332121
+ const cpbCount = bits.readUE() + 1;
332122
+ bits.readBits(8);
332123
+ for (let i = 0; i < cpbCount && bits.bitsRemaining > 0; i++) {
332124
+ bits.readUE();
332125
+ bits.readUE();
332126
+ bits.readBit();
332127
+ }
332128
+ bits.readBits(20);
332129
+ }
332130
+ if (hrdPresent) bits.readBit();
332131
+ bits.readBit();
332132
+ if (bits.readBit()) {
332133
+ bits.readBit();
332134
+ bits.readUE();
332135
+ bits.readUE();
332136
+ bits.readUE();
332137
+ bits.readUE();
332138
+ maxNumReorderFrames = bits.readUE();
332139
+ }
332115
332140
  }
332116
332141
  let profileName = H264_PROFILES[profileIdc] ?? `Profile ${profileIdc}`;
332117
332142
  if (profileIdc === 66 && (constraintFlags & 64) !== 0) {
@@ -332135,7 +332160,8 @@ function parseH264Sps(nalu) {
332135
332160
  sarWidth,
332136
332161
  sarHeight,
332137
332162
  fps,
332138
- maxNumRefFrames
332163
+ maxNumRefFrames,
332164
+ maxNumReorderFrames
332139
332165
  };
332140
332166
  }
332141
332167
  function parseAvcC(payload) {
@@ -332895,6 +332921,7 @@ function applyCodecMetadata(state, child) {
332895
332921
  metadata.level = child.levelIdc;
332896
332922
  if (child.sps) {
332897
332923
  const sps = parseH264Sps(child.sps);
332924
+ metadata.maxNumReorderFrames = sps.maxNumReorderFrames;
332898
332925
  metadata.profile = sps.profileName;
332899
332926
  metadata.width = sps.width || metadata.width;
332900
332927
  metadata.height = sps.height || metadata.height;
@@ -333036,7 +333063,7 @@ function buildProbeStream(track, desc, stats, idx, containerFormat) {
333036
333063
  height: h,
333037
333064
  coded_width: w ? Math.ceil(w / 16) * 16 : void 0,
333038
333065
  coded_height: h ? Math.ceil(h / 16) * 16 : void 0,
333039
- has_b_frames: track.type === "video" ? stats.hasCts ? 1 : 0 : void 0,
333066
+ has_b_frames: track.type === "video" ? desc?.maxNumReorderFrames ?? (stats.hasCts ? 1 : 0) : void 0,
333040
333067
  sample_aspect_ratio: track.type === "video" ? `${desc?.sarWidth ?? 1}:${desc?.sarHeight ?? 1}` : void 0,
333041
333068
  display_aspect_ratio: track.type === "video" && w && h ? `${w / darGcd}:${h / darGcd}` : void 0,
333042
333069
  pix_fmt: track.type === "video" ? desc?.pixFmt ?? "yuv420p" : void 0,
@@ -334937,15 +334964,31 @@ function buildProbeResultFromDoc(doc, byteLength, filename = "input.mp4", option
334937
334964
  const streams = [];
334938
334965
  const packets = [];
334939
334966
  const frames = [];
334967
+ let formatStart = Infinity, formatEnd = -Infinity;
334940
334968
  for (let idx = 0; idx < doc.tracks.length; idx++) {
334941
334969
  const track = doc.tracks[idx];
334942
334970
  const materialized = materializeTrackSamples(track);
334943
334971
  const desc = materialized.codecDescriptions[0];
334944
- const stream = buildProbeStream(track, desc, {
334972
+ let firstPts = materialized.samples[0]?.pts ?? 0;
334973
+ if (track.editList?.length) {
334974
+ let delay = 0;
334975
+ for (const edit of track.editList) {
334976
+ if (edit.mediaTime >= 0) break;
334977
+ delay += edit.segmentDuration;
334978
+ }
334979
+ firstPts = Math.round(delay * track.timescale / Math.max(1, doc.timescale));
334980
+ }
334981
+ const duration2 = Math.max(0, track.duration - (track.editList?.length ? firstPts : 0));
334982
+ if (doc.containerFormat === "mp4" || doc.containerFormat === "mov") {
334983
+ const start = firstPts / Math.max(1, track.timescale);
334984
+ formatStart = Math.min(formatStart, start);
334985
+ formatEnd = Math.max(formatEnd, start + duration2 / Math.max(1, track.timescale));
334986
+ }
334987
+ const stream = buildProbeStream({ ...track, duration: duration2 }, desc, {
334945
334988
  totalBytes: materialized.samples.reduce((total, sample) => total + sample.size, 0),
334946
334989
  count: materialized.samples.length,
334947
334990
  ticks: materialized.samples.reduce((total, sample) => total + sample.duration, 0),
334948
- firstPts: materialized.samples[0]?.pts ?? 0,
334991
+ firstPts,
334949
334992
  hasCts: materialized.samples.some((sample) => sample.cts !== 0)
334950
334993
  }, idx, doc.containerFormat);
334951
334994
  streams.push(stream);
@@ -335008,7 +335051,9 @@ function buildProbeResultFromDoc(doc, byteLength, filename = "input.mp4", option
335008
335051
  const value = doc.metadata[key];
335009
335052
  if (value) formatTags[key] = value;
335010
335053
  }
335011
- const overallBitRate = doc.durationSeconds > 0 ? String(Math.round(byteLength * 8 / doc.durationSeconds)) : "0";
335054
+ const startTime = Number.isFinite(formatStart) ? formatStart : 0;
335055
+ const duration = Number.isFinite(formatEnd) ? Math.max(0, formatEnd - startTime) : doc.durationSeconds;
335056
+ const overallBitRate = duration > 0 ? String(Math.round(byteLength * 8 / duration)) : "0";
335012
335057
  return {
335013
335058
  streams,
335014
335059
  format: {
@@ -335017,8 +335062,8 @@ function buildProbeResultFromDoc(doc, byteLength, filename = "input.mp4", option
335017
335062
  nb_programs: 0,
335018
335063
  format_name: options.formatName ?? "mov,mp4,m4a,3gp,3g2,mj2",
335019
335064
  format_long_name: options.formatLongName ?? "QuickTime / MOV",
335020
- start_time: "0.000000",
335021
- duration: doc.durationSeconds.toFixed(6),
335065
+ start_time: startTime.toFixed(6),
335066
+ duration: duration.toFixed(6),
335022
335067
  size: String(byteLength),
335023
335068
  bit_rate: overallBitRate,
335024
335069
  probe_score: 100,
@@ -339872,7 +339917,7 @@ async function* scanProbeRecords(source, options, mode) {
339872
339917
  movieDuration = version === 1 ? movie.readU64BE() : movie.readU32BE();
339873
339918
  }
339874
339919
  const mvex = await first(moov, "mvex");
339875
- let trackIndex = 0, maxDuration = movieDuration / Math.max(1, movieTimescale);
339920
+ let trackIndex = 0, maxDuration = movieDuration / Math.max(1, movieTimescale), formatStart = Infinity, formatEnd = -Infinity;
339876
339921
  for await (const trak of scanMp4Boxes(source, { ...moov.children, ...work })) {
339877
339922
  if (trak.type !== "trak") continue;
339878
339923
  const index = trackIndex++;
@@ -339965,8 +340010,9 @@ async function* scanProbeRecords(source, options, mode) {
339965
340010
  }
339966
340011
  }
339967
340012
  }
339968
- let duration = 0, mediaEnd = 0, allPacked = true, count = 0;
340013
+ let duration = 0, mediaEnd = 0, allPacked = true, count = 0, firstPts = 0;
339969
340014
  for await (const sample of samples()) {
340015
+ if (!count) firstPts = sample.pts;
339970
340016
  count++;
339971
340017
  duration += sample.duration;
339972
340018
  mediaEnd = Math.max(mediaEnd, sample.pts + sample.duration);
@@ -339982,28 +340028,34 @@ async function* scanProbeRecords(source, options, mode) {
339982
340028
  const version = header2.readU8();
339983
340029
  header2.skip(3);
339984
340030
  const count2 = header2.readU32BE(), width2 = version === 1 ? 20 : 12;
339985
- let total = 0, entries = 0;
340031
+ let total = 0, entries = 0, delay = 0, foundMedia = false;
339986
340032
  for (let i = 0; i < count2 && 8 + i * width2 < elst.payloadSize; i++) {
339987
340033
  const row = new BinaryReader(yield { kind: "read", table: elst, offset: elst.payloadOffset + 8 + i * width2, length: Math.min(width2, elst.payloadSize - 8 - i * width2) });
339988
340034
  let segment = version === 1 ? row.readU64BE() : row.readU32BE();
339989
340035
  const mediaTime = version === 1 ? row.readI64BE() : row.readI32BE();
339990
340036
  if (fragmented && segment === 0 && mediaTime >= 0) segment = Math.round(Math.max(0, mediaEnd - mediaTime) * movieTimescale / timescale);
340037
+ if (mediaTime >= 0) foundMedia = true;
340038
+ else if (!foundMedia) delay += segment;
339991
340039
  total += segment;
339992
340040
  entries++;
339993
340041
  }
339994
- return entries ? Math.round(total * timescale / movieTimescale) : void 0;
340042
+ return entries ? { duration: Math.round(total * timescale / movieTimescale), start: Math.round(delay * timescale / movieTimescale) } : void 0;
339995
340043
  }
339996
340044
  const edits = consumeMp4SampleSteps(source, editDuration(), sampleOptions), result = await edits.next();
339997
340045
  if (!result.done) throw new Error("Unexpected MP4 edit sample");
339998
- const trackDuration = result.value ?? (duration || declaredDuration || Math.round(headerDuration / Math.max(1, movieTimescale) * timescale));
340046
+ const trackDuration = result.value?.duration ?? (duration || declaredDuration || Math.round(headerDuration / Math.max(1, movieTimescale) * timescale));
339999
340047
  maxDuration = Math.max(maxDuration, trackDuration / Math.max(1, timescale));
340000
340048
  budget.checkDuration(maxDuration);
340049
+ const startPts = result.value?.start ?? (type === "subtitle" && count && !allPacked ? 0 : firstPts);
340050
+ const probeDuration = Math.max(0, trackDuration - (result.value?.start ?? 0));
340051
+ const start = startPts / Math.max(1, timescale);
340052
+ formatStart = Math.min(formatStart, start);
340053
+ formatEnd = Math.max(formatEnd, start + probeDuration / Math.max(1, timescale));
340001
340054
  if (mode === "summary") continue;
340002
340055
  let bytePos = 0, cursor = 0;
340003
- const stats = { totalBytes: 0, count: 0, ticks: 0, firstPts: 0, hasCts: false };
340056
+ const stats = { totalBytes: 0, count: 0, ticks: 0, firstPts: startPts, hasCts: false };
340004
340057
  const packet = (sample) => {
340005
340058
  if (mode === "streams") {
340006
- if (!stats.count) stats.firstPts = sample.pts;
340007
340059
  stats.count++;
340008
340060
  stats.totalBytes += sample.size;
340009
340061
  stats.ticks += sample.duration;
@@ -340019,27 +340071,27 @@ async function* scanProbeRecords(source, options, mode) {
340019
340071
  if (mode !== "streams") yield row2;
340020
340072
  continue;
340021
340073
  }
340022
- const start = Math.max(cursor, Math.round(sample.pts));
340023
- if (start > cursor) {
340024
- const row2 = packet({ pts: cursor, dts: cursor, duration: start - cursor, size: 2, isKeyframe: true });
340074
+ const start2 = Math.max(cursor, Math.round(sample.pts));
340075
+ if (start2 > cursor) {
340076
+ const row2 = packet({ pts: cursor, dts: cursor, duration: start2 - cursor, size: 2, isKeyframe: true });
340025
340077
  if (mode !== "streams") yield row2;
340026
- cursor = start;
340078
+ cursor = start2;
340027
340079
  }
340028
340080
  const duration2 = Math.max(1, Math.round(sample.duration));
340029
340081
  const row = packet({ pts: cursor, dts: cursor, duration: duration2, size: sample.size + 2, isKeyframe: true });
340030
340082
  if (mode !== "streams") yield row;
340031
340083
  cursor += duration2;
340032
340084
  }
340033
- if (mode === "streams") yield buildProbeStream({ ...track, duration: trackDuration }, codec, stats, index, "mp4");
340085
+ if (mode === "streams") yield buildProbeStream({ ...track, duration: probeDuration }, codec, stats, index, "mp4");
340034
340086
  }
340035
340087
  budget.checkDuration(maxDuration);
340036
- return { duration: maxDuration, tracks: trackIndex };
340088
+ return { duration: maxDuration, start: trackIndex ? formatStart : 0, presentationDuration: trackIndex ? Math.max(0, formatEnd - formatStart) : maxDuration, tracks: trackIndex };
340037
340089
  }
340038
340090
  async function probeMp4Source(source, options = {}) {
340039
340091
  const work = { ...options, budget: options.budget ?? new MediaBudgetTracker(options.limits) };
340040
340092
  const scan = scanProbeRecords(source, work, "summary"), summary = await scan.next();
340041
340093
  if (!summary.done) throw new Error("Unexpected MP4 summary row");
340042
- const { duration, tracks } = summary.value, metadata = await probeMp4MetadataSource(source, duration, work);
340094
+ const { duration, start, presentationDuration, tracks } = summary.value, metadata = await probeMp4MetadataSource(source, duration, work);
340043
340095
  async function* streams() {
340044
340096
  for await (const row of scanProbeRecords(source, work, "streams")) if (!("sample" in row)) yield row;
340045
340097
  }
@@ -340051,10 +340103,10 @@ async function probeMp4Source(source, options = {}) {
340051
340103
  nb_programs: 0,
340052
340104
  format_name: "mov,mp4,m4a,3gp,3g2,mj2",
340053
340105
  format_long_name: "QuickTime / MOV",
340054
- start_time: "0.000000",
340055
- duration: duration.toFixed(6),
340106
+ start_time: start.toFixed(6),
340107
+ duration: presentationDuration.toFixed(6),
340056
340108
  size: String(source.size),
340057
- bit_rate: duration > 0 ? String(Math.round(source.size * 8 / duration)) : "0",
340109
+ bit_rate: presentationDuration > 0 ? String(Math.round(source.size * 8 / presentationDuration)) : "0",
340058
340110
  probe_score: 100,
340059
340111
  tags: metadata.tags
340060
340112
  },
@@ -20,7 +20,7 @@ import {
20
20
  sliceMp4,
21
21
  srtAst,
22
22
  webvttAst
23
- } from "../safe-bash/command-chunks/chunk-BXOBM4HJ.js";
23
+ } from "../safe-bash/command-chunks/chunk-R6PMUP4E.js";
24
24
  import "../safe-bash/command-chunks/chunk-65DS4IOB.js";
25
25
 
26
26
  // packages/safe-bash-command-ffmpeg/src/index.ts
@@ -1,8 +1,8 @@
1
1
  import {
2
2
  createFfprobeCommand
3
- } from "../safe-bash/command-chunks/chunk-MWPL7AFP.js";
3
+ } from "../safe-bash/command-chunks/chunk-M3QUDUEM.js";
4
4
  import "../safe-bash/command-chunks/chunk-MGBHGZEX.js";
5
- import "../safe-bash/command-chunks/chunk-BXOBM4HJ.js";
5
+ import "../safe-bash/command-chunks/chunk-R6PMUP4E.js";
6
6
  import "../safe-bash/command-chunks/chunk-65DS4IOB.js";
7
7
 
8
8
  // packages/safe-bash-command-ffprobe/src/index.ts
@@ -11,9 +11,9 @@ import {
11
11
  loadManifestResources,
12
12
  resolvePath,
13
13
  rethrowRuntimeError
14
- } from "../safe-bash/command-chunks/chunk-MWPL7AFP.js";
14
+ } from "../safe-bash/command-chunks/chunk-M3QUDUEM.js";
15
15
  import "../safe-bash/command-chunks/chunk-MGBHGZEX.js";
16
- import "../safe-bash/command-chunks/chunk-BXOBM4HJ.js";
16
+ import "../safe-bash/command-chunks/chunk-R6PMUP4E.js";
17
17
  import "../safe-bash/command-chunks/chunk-65DS4IOB.js";
18
18
  export {
19
19
  createFfprobeCommand,
@@ -4321,6 +4321,8 @@ function* magickDrawSteps(img, drawCmd, state) {
4321
4321
  } else if (cmd === "path") {
4322
4322
  const d = tokens[i++] ?? "";
4323
4323
  svgElements.push(`<path d="${escapeXml(d)}" fill="${fill}" stroke="${stroke}" stroke-width="${strokeWidth}"/>`);
4324
+ } else {
4325
+ throw new Error(`Unsupported drawing primitive: ${cmd}`);
4324
4326
  }
4325
4327
  }
4326
4328
  if (svgElements.length > 0) yield { kind: "svg", svg: `<svg xmlns="http://www.w3.org/2000/svg" width="${img.width}" height="${img.height}">${svgElements.join("")}</svg>` };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@poe-platform/safe-bash",
3
- "version": "0.1.830",
3
+ "version": "0.1.831",
4
4
  "description": "Extensible virtual shell with pluggable filesystems and streaming commands",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -1415,7 +1415,7 @@
1415
1415
  "access": "public"
1416
1416
  },
1417
1417
  "dependencies": {
1418
- "@poe-platform/safe-fs": "0.1.830",
1418
+ "@poe-platform/safe-fs": "0.1.831",
1419
1419
  "pdf-lib": "1.17.1",
1420
1420
  "@types/node": "^25.2.2",
1421
1421
  "@formatjs/intl-numberformat": "9.4.0",