@hyperframes/producer 0.8.190 → 0.8.191

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.
@@ -39,6 +39,7 @@ export { muxChunkWithAudio } from "./services/distributed/chunkAudio.js";
39
39
  export { buildStitchedHeader, readMp4Layout, type Mp4Layout, type ReadRange, } from "./services/distributed/mp4Stitch.js";
40
40
  export { InvalidConfigError, type SerializableDistributedRenderConfig, validateDistributedRenderConfig, validateVariablesPayload, } from "./services/distributed/renderConfigValidation.js";
41
41
  export { hashProjectDir, listSiteFiles } from "./services/distributed/projectHash.js";
42
+ export { AUDIO_SIDECAR_MIN_BYTES, buildAudioSidecar, wantsAudioSidecar, type AudioSidecarOutcome, } from "./services/distributed/audioSidecar.js";
42
43
  export { CURRENT_PLAN_PROTOCOL, DISTRIBUTED_RENDER_CAPABILITIES, getDistributedRenderCapabilities, PLAN_ARTIFACT_LAYOUT, PLAN_HASH_SCHEMA, PLAN_PROTOCOL_V1, PLAN_PROTOCOL_V2, PLAN_PROTOCOL_UNSUPPORTED, PLAN_SCHEMA_VERSION, PLAN_V2_ARTIFACT_LAYOUT, PLAN_V2_HASH_SCHEMA, PLAN_V2_SCHEMA_VERSION, PlanProtocolUnsupportedError, readPlanProtocol, readPlanProtocolV1, type DistributedRenderCapabilities, type PlanProtocolConsumerCapabilities, type PlanProtocolDescriptor, type PlanProtocolV1Descriptor, type PlanProtocolV2Descriptor, type SupportedPlanProtocolDescriptor, } from "./services/distributed/planProtocol.js";
43
44
  export { PlanVideosMetadataError, type DistributedFormat } from "./services/distributed/shared.js";
44
45
  export { isPlanAudioArtifactPath, PLAN_AUDIO_LEGACY_RELATIVE_PATH, PLAN_AUDIO_RELATIVE_PATH, resolvePlanAudioPath, } from "./services/distributed/shared.js";
@@ -3395,7 +3395,7 @@ async function compileForRender(projectDir, htmlPath, downloadDir, options = {})
3395
3395
  );
3396
3396
  if (analysis.isProblematic) {
3397
3397
  defaultLogger.warn(
3398
- `[Compiler] WARNING: Video "${video.id}" has sparse keyframes (max interval: ${analysis.maxIntervalSeconds}s). This causes seek failures and frame freezing. Re-encode with: ${reencode}`
3398
+ `[Compiler] WARNING: Video "${video.id}" has sparse keyframes (max interval: ${analysis.maxIntervalSeconds}s). Long GOPs can make preview seeking slower; rendering is unaffected. If preview seeking is slow, re-encode with: ${reencode}`
3399
3399
  );
3400
3400
  }
3401
3401
  if (metadata.isVFR) {
@@ -5446,6 +5446,7 @@ async function mixAudioForDelivery(input, duration, pcmSourcePath) {
5446
5446
  audios,
5447
5447
  masterFxChain,
5448
5448
  urlByAbsentLocalPath,
5449
+ audioSidecarUrlByLocalPath,
5449
5450
  abortSignal,
5450
5451
  assertNotAborted,
5451
5452
  log
@@ -5469,6 +5470,7 @@ async function mixAudioForDelivery(input, duration, pcmSourcePath) {
5469
5470
  audioGain,
5470
5471
  masterFxChain,
5471
5472
  urlByAbsentLocalPath,
5473
+ audioSidecarUrlByLocalPath,
5472
5474
  keepEncoderInputAt: pcmSourcePath
5473
5475
  },
5474
5476
  compiledDir
@@ -8583,6 +8585,11 @@ async function compilePlanComposition(projectDir, config, planDir, options) {
8583
8585
  const localPathByUrl = new Map(
8584
8586
  remoteFiles.map(([rel, file]) => [file.url, remoteLocalPath(rel)])
8585
8587
  );
8588
+ const audioSidecarUrlByLocalPath = new Map(
8589
+ remoteFiles.flatMap(
8590
+ ([rel, file]) => file.audioSidecarUrl ? [[remoteLocalPath(rel), file.audioSidecarUrl]] : []
8591
+ )
8592
+ );
8586
8593
  stageStarted = Date.now();
8587
8594
  const compileResult = await runCompileStage({
8588
8595
  urlByAbsentLocalPath,
@@ -8667,6 +8674,7 @@ async function compilePlanComposition(projectDir, config, planDir, options) {
8667
8674
  finalCompiledDir,
8668
8675
  remoteFiles,
8669
8676
  urlByAbsentLocalPath,
8677
+ audioSidecarUrlByLocalPath,
8670
8678
  localPathByUrl,
8671
8679
  compileResult,
8672
8680
  compiled,
@@ -8684,6 +8692,7 @@ function mixPlanAudio(c, compiledDir) {
8684
8692
  workDir: c.workDir,
8685
8693
  compiledDir,
8686
8694
  urlByAbsentLocalPath: c.urlByAbsentLocalPath,
8695
+ audioSidecarUrlByLocalPath: c.audioSidecarUrlByLocalPath,
8687
8696
  totalFrames: c.totalFrames,
8688
8697
  fps: c.job.config.fps,
8689
8698
  ffmpegProcessTimeout: c.cfg.ffmpegProcessTimeout,
@@ -11164,7 +11173,36 @@ function hashProjectDir(projectDir, files = listSiteFiles(projectDir)) {
11164
11173
  }
11165
11174
  return hash.digest("hex").slice(0, 16);
11166
11175
  }
11176
+
11177
+ // src/services/distributed/audioSidecar.ts
11178
+ import { extractAudioMetadata as extractAudioMetadata4, runFfmpeg as runFfmpeg8 } from "@hyperframes/engine";
11179
+ import { extname as extname5 } from "node:path";
11180
+ var AUDIO_SIDECAR_MIN_BYTES = 32 * 1024 * 1024;
11181
+ var AUDIO_SIDECAR_SOURCE_EXTENSIONS = /* @__PURE__ */ new Set([".mp4", ".mov", ".m4v"]);
11182
+ function wantsAudioSidecar(path, sizeBytes) {
11183
+ return sizeBytes >= AUDIO_SIDECAR_MIN_BYTES && AUDIO_SIDECAR_SOURCE_EXTENSIONS.has(extname5(path).toLowerCase());
11184
+ }
11185
+ async function buildAudioSidecar(inputPath, outputPath, signal) {
11186
+ const audio = await extractAudioMetadata4(inputPath, { signal }).catch(() => null);
11187
+ if (!audio) return await ffmpegIsMissing(signal) ? "unavailable" : "none";
11188
+ if (audio.audioStreamCount !== 1 || (audio.audioStreamLeadSeconds ?? 0) > 0) return "none";
11189
+ const result = await runFfmpeg8(
11190
+ ["-v", "error", "-y", "-i", inputPath, "-map", "0:a:0", "-vn", "-c:a", "copy"].concat([
11191
+ "-movflags",
11192
+ "+faststart",
11193
+ "-f",
11194
+ "mp4",
11195
+ outputPath
11196
+ ]),
11197
+ { signal }
11198
+ );
11199
+ if (result.success) return "built";
11200
+ return isMissing(result) ? "unavailable" : "none";
11201
+ }
11202
+ var isMissing = (result) => result.error?.code === "ENOENT";
11203
+ var ffmpegIsMissing = async (signal) => isMissing(await runFfmpeg8(["-version"], { signal }));
11167
11204
  export {
11205
+ AUDIO_SIDECAR_MIN_BYTES,
11168
11206
  CHUNK_EXCEEDS_WORKER_TIMEOUT,
11169
11207
  CHUNK_FRAME_RANGE_INVALID,
11170
11208
  CURRENT_PLAN_PROTOCOL,
@@ -11207,6 +11245,7 @@ export {
11207
11245
  applyRuntimeEnvSnapshot,
11208
11246
  assemble,
11209
11247
  assembleV2,
11248
+ buildAudioSidecar,
11210
11249
  buildChunkSlices,
11211
11250
  buildPlanAudio,
11212
11251
  buildStitchedHeader,
@@ -11242,5 +11281,6 @@ export {
11242
11281
  stitchesSeparateAudio,
11243
11282
  validateDistributedRenderConfig,
11244
11283
  validatePlanV2MaterializedTarget,
11245
- validateVariablesPayload
11284
+ validateVariablesPayload,
11285
+ wantsAudioSidecar
11246
11286
  };
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": "0.1.0",
3
3
  "buildId": "dev",
4
- "sha256": "54a6d80fb24c9d14b82e50000abc5ff73819d53fe7951b53299a20e941371b5b",
4
+ "sha256": "cd5f930c1b25aea193005449687af10c1b706fc870e51d1ff160dd46751d1581",
5
5
  "artifacts": {
6
6
  "iife": "hyperframe.runtime.iife.js",
7
7
  "esm": "hyperframe.runtime.mjs"