@hyperframes/engine 0.9.12 → 0.9.13

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.
@@ -178,7 +178,7 @@ export interface ExtractionPhaseBreakdown {
178
178
  /** Number of per-source transient failures retried inside this extraction. */
179
179
  transientRetries?: number;
180
180
  }
181
- export type VideoExtractionFailureKind = "cancelled" | "external_interruption" | "source_missing" | "source_rejected" | "download_not_found" | "download_transient" | "invalid_media" | "media_start_out_of_range" | "ffmpeg_unavailable" | "ffmpeg_timeout" | "ffmpeg_transient" | "ffmpeg_failed" | "zero_output" | "internal";
181
+ export type VideoExtractionFailureKind = "cancelled" | "external_interruption" | "source_missing" | "source_rejected" | "download_not_found" | "download_transient" | "invalid_media" | "media_start_out_of_range" | "ffmpeg_unavailable" | "ffmpeg_timeout" | "ffmpeg_transient" | "ffmpeg_failed" | "disk_full" | "zero_output" | "internal";
182
182
  export interface VideoExtractionFailure {
183
183
  videoId: string;
184
184
  /** Always populated by this engine version; optional for source compatibility with older consumers. */
@@ -259,6 +259,8 @@ function ffmpegReasonFrom(stderr, paths) {
259
259
  .join(" | ")
260
260
  .slice(-FFMPEG_REASON_CHARS);
261
261
  }
262
+ // ffmpeg ends a full disk with its last frames' summary, so the strerror text is the only sign of it
263
+ const DISK_FULL = /no space left on device|disk quota exceeded/i;
262
264
  export function isVideoSourceExtractionError(error) {
263
265
  return (typeof error === "object" &&
264
266
  error !== null &&
@@ -879,7 +881,7 @@ outputDirOverride) {
879
881
  !processResult.success &&
880
882
  !processResult.failureReason;
881
883
  const videoToolboxWasOptional = decodeWithVideoToolbox && !keepsHdrForChrome;
882
- if (ffmpegExitedFailing && videoToolboxWasOptional)
884
+ if (ffmpegExitedFailing && videoToolboxWasOptional && !DISK_FULL.test(processResult.stderr))
883
885
  processResult = await extract([]);
884
886
  if (processResult.failureReason === "external_interruption") {
885
887
  throw new VideoSourceExtractionError("external_interruption", true, "Video frame extraction interrupted by host lifecycle", `FFmpeg exited with code ${processResult.exitCode}: ${processResult.stderr.slice(-500)}`);
@@ -910,6 +912,9 @@ outputDirOverride) {
910
912
  if (timedOut) {
911
913
  throw new VideoSourceExtractionError("ffmpeg_timeout", true, "Video frame extraction timed out", diagnostic, ffmpegReason);
912
914
  }
915
+ if (DISK_FULL.test(processResult.stderr)) {
916
+ throw new VideoSourceExtractionError("disk_full", false, "The disk filled up while video frames were extracted", diagnostic, ffmpegReason);
917
+ }
913
918
  const transientIo = /resource temporarily unavailable|device or resource busy|input\/output error/i.test(processResult.stderr);
914
919
  throw new VideoSourceExtractionError(transientIo ? "ffmpeg_transient" : "ffmpeg_failed", transientIo, transientIo
915
920
  ? "Video frame extraction hit a transient I/O failure"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hyperframes/engine",
3
- "version": "0.9.12",
3
+ "version": "0.9.13",
4
4
  "description": "Seekable web page to video rendering engine (Puppeteer + FFmpeg)",
5
5
  "repository": {
6
6
  "type": "git",
@@ -9,6 +9,8 @@
9
9
  },
10
10
  "files": [
11
11
  "dist",
12
+ "!dist/services/__fixtures__/blurDifferential.*",
13
+ "!dist/services/__fixtures__/motionBlur",
12
14
  "README.md"
13
15
  ],
14
16
  "type": "module",
@@ -59,8 +61,8 @@
59
61
  "puppeteer": "~25.11.0",
60
62
  "puppeteer-core": "^25.11.0",
61
63
  "undici": "7.25.0",
62
- "@hyperframes/core": "^0.9.12",
63
- "@hyperframes/parsers": "^0.9.12"
64
+ "@hyperframes/parsers": "^0.9.13",
65
+ "@hyperframes/core": "^0.9.13"
64
66
  },
65
67
  "devDependencies": {
66
68
  "@types/node": "^25.0.10",