@hyperframes/producer 0.4.11 → 0.4.12

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.
@@ -101460,7 +101460,7 @@ var DEFAULT_CONFIG = {
101460
101460
  ffmpegStreamingTimeout: 6e5,
101461
101461
  hdr: false,
101462
101462
  hdrAutoDetect: true,
101463
- audioGain: 1.35,
101463
+ audioGain: 1,
101464
101464
  frameDataUriCacheLimit: 256,
101465
101465
  playerReadyTimeout: 45e3,
101466
101466
  renderReadyTimeout: 15e3,
@@ -105572,6 +105572,37 @@ async function convertSdrToHdr(inputPath, outputPath, signal, config2) {
105572
105572
  );
105573
105573
  }
105574
105574
  }
105575
+ async function convertVfrToCfr(inputPath, outputPath, targetFps, startTime, duration, signal, config2) {
105576
+ const timeout2 = config2?.ffmpegProcessTimeout ?? DEFAULT_CONFIG.ffmpegProcessTimeout;
105577
+ const args = [
105578
+ "-ss",
105579
+ String(startTime),
105580
+ "-i",
105581
+ inputPath,
105582
+ "-t",
105583
+ String(duration),
105584
+ "-fps_mode",
105585
+ "cfr",
105586
+ "-r",
105587
+ String(targetFps),
105588
+ "-c:v",
105589
+ "libx264",
105590
+ "-preset",
105591
+ "fast",
105592
+ "-crf",
105593
+ "18",
105594
+ "-c:a",
105595
+ "copy",
105596
+ "-y",
105597
+ outputPath
105598
+ ];
105599
+ const result = await runFfmpeg(args, { signal, timeout: timeout2 });
105600
+ if (!result.success) {
105601
+ throw new Error(
105602
+ `VFR\u2192CFR conversion failed (exit ${result.exitCode}): ${result.stderr.slice(-300)}`
105603
+ );
105604
+ }
105605
+ }
105575
105606
  async function extractAllVideoFrames(videos, baseDir, options, signal, config2, compiledDir) {
105576
105607
  const startTime = Date.now();
105577
105608
  const extracted = [];
@@ -105629,6 +105660,39 @@ async function extractAllVideoFrames(videos, baseDir, options, signal, config2,
105629
105660
  }
105630
105661
  }
105631
105662
  }
105663
+ const vfrNormDir = join8(options.outputDir, "_vfr_normalized");
105664
+ for (let i = 0; i < resolvedVideos.length; i++) {
105665
+ if (signal?.aborted) break;
105666
+ const entry = resolvedVideos[i];
105667
+ if (!entry) continue;
105668
+ const metadata = await extractVideoMetadata(entry.videoPath);
105669
+ if (!metadata.isVFR) continue;
105670
+ let segDuration = entry.video.end - entry.video.start;
105671
+ if (!Number.isFinite(segDuration) || segDuration <= 0) {
105672
+ const sourceRemaining = metadata.durationSeconds - entry.video.mediaStart;
105673
+ segDuration = sourceRemaining > 0 ? sourceRemaining : metadata.durationSeconds;
105674
+ }
105675
+ mkdirSync5(vfrNormDir, { recursive: true });
105676
+ const normalizedPath = join8(vfrNormDir, `${entry.video.id}_cfr.mp4`);
105677
+ try {
105678
+ await convertVfrToCfr(
105679
+ entry.videoPath,
105680
+ normalizedPath,
105681
+ options.fps,
105682
+ entry.video.mediaStart,
105683
+ segDuration,
105684
+ signal,
105685
+ config2
105686
+ );
105687
+ entry.videoPath = normalizedPath;
105688
+ entry.video = { ...entry.video, mediaStart: 0 };
105689
+ } catch (err) {
105690
+ errors.push({
105691
+ videoId: entry.video.id,
105692
+ error: err instanceof Error ? err.message : String(err)
105693
+ });
105694
+ }
105695
+ }
105632
105696
  const results = await Promise.all(
105633
105697
  resolvedVideos.map(async ({ video, videoPath }) => {
105634
105698
  if (signal?.aborted) {
@@ -106304,7 +106368,7 @@ async function processCompositionAudio(elements, baseDir, workDir, outputPath, t
106304
106368
  end: element.end,
106305
106369
  mediaStart: element.mediaStart,
106306
106370
  duration: element.end - element.start,
106307
- volume: element.volume || 1
106371
+ volume: element.volume ?? 1
106308
106372
  });
106309
106373
  } catch (err) {
106310
106374
  errors.push(`Error: ${element.id} \u2014 ${err instanceof Error ? err.message : String(err)}`);
@@ -109203,8 +109267,8 @@ async function compileForRender(projectDir, htmlPath, downloadDir) {
109203
109267
  );
109204
109268
  }
109205
109269
  if (metadata.isVFR) {
109206
- console.warn(
109207
- `[Compiler] WARNING: Video "${video.id}" is variable frame rate (VFR). Screen recordings and phone videos are often VFR, which causes stuttering and frame skipping in renders. Re-encode with: ${reencode}`
109270
+ console.info(
109271
+ `[Compiler] Video "${video.id}" is variable frame rate (VFR); the engine will normalize it to CFR before frame extraction. If rendering feels slow on this video, pre-encode once with: ${reencode}`
109208
109272
  );
109209
109273
  }
109210
109274
  }).catch(() => {