@hyperframes/producer 0.8.191 → 0.8.192

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,7 +18,8 @@ import {
18
18
  import {
19
19
  getEncoderPreset as getEncoderPreset4,
20
20
  normalizeVp9CpuUsed,
21
- resolveConfig as resolveConfig3
21
+ resolveConfig as resolveConfig3,
22
+ declareContentAddressedUrl
22
23
  } from "@hyperframes/engine";
23
24
 
24
25
  // src/logger.ts
@@ -4281,6 +4282,10 @@ async function runProbeStage(input) {
4281
4282
  if (el.loop && !existing.loop) {
4282
4283
  existing.loop = true;
4283
4284
  }
4285
+ const audio = composition.audios.find(
4286
+ (audio2) => audio2.type === "video" && audio2.id === `${el.id}-audio`
4287
+ );
4288
+ if (audio) audio.loop = existing.loop;
4284
4289
  }
4285
4290
  } else if (!compiled.droppedMediaIds.has(el.id)) {
4286
4291
  composition.videos.push({
@@ -4318,6 +4323,7 @@ async function runProbeStage(input) {
4318
4323
  el,
4319
4324
  authoredStarts.get(el.id) ?? existing.mediaStart
4320
4325
  );
4326
+ existing.loop = el.loop;
4321
4327
  if (el.volume > 0 && Math.abs((existing.volume ?? 1) - el.volume) > BROWSER_MEDIA_EPSILON) {
4322
4328
  existing.volume = el.volume;
4323
4329
  }
@@ -4329,6 +4335,7 @@ async function runProbeStage(input) {
4329
4335
  start: el.start,
4330
4336
  end: resolveBrowserMediaEnd(el.start, el.end, el.duration),
4331
4337
  mediaStart: el.mediaStart,
4338
+ loop: el.loop,
4332
4339
  layer: 0,
4333
4340
  volume: el.volume,
4334
4341
  type: "audio"
@@ -4583,6 +4590,10 @@ import {
4583
4590
  extractMediaMetadata as extractMediaMetadata3,
4584
4591
  isVideoPastTimelineEnd,
4585
4592
  isHdrColorSpace as isHdrColorSpace2,
4593
+ rebaseVideoToWindow,
4594
+ resolveFinalFrameExtractionWindow as resolveFinalFrameExtractionWindow2,
4595
+ resolveVideoExtractionWindow as resolveVideoExtractionWindow2,
4596
+ isHttpUrl as isHttpUrl2,
4586
4597
  resolveProjectRelativeSrc as resolveProjectRelativeSrc3,
4587
4598
  runVideoExtractionWithRetry,
4588
4599
  safeVideoExtractionSourceIdentity
@@ -4948,6 +4959,8 @@ function appendAutoDetectedVideoAudio(composition, extracted) {
4948
4959
  start: video.start,
4949
4960
  end: video.end,
4950
4961
  mediaStart: video.mediaStart,
4962
+ playbackRate: video.playbackRate,
4963
+ loop: video.loop,
4951
4964
  layer: 0,
4952
4965
  volume: 1,
4953
4966
  type: "video"
@@ -4955,6 +4968,33 @@ function appendAutoDetectedVideoAudio(composition, extracted) {
4955
4968
  existingAudioSrcs.add(video.src);
4956
4969
  }
4957
4970
  }
4971
+ async function appendVideoAudioFromProbe(input) {
4972
+ const { projectDir, compiledDir, composition, urlByAbsentLocalPath } = input;
4973
+ const videos = composition.videos.filter(
4974
+ (video) => !isVideoPastTimelineEnd(video, composition.duration)
4975
+ );
4976
+ const probed = await Promise.all(
4977
+ videos.map(async (video) => {
4978
+ const path = isHttpUrl2(video.src) ? video.src : resolveProjectRelativeSrc3(video.src, projectDir, compiledDir);
4979
+ const readFrom = urlByAbsentLocalPath?.get(path) ?? path;
4980
+ if (!isHttpUrl2(readFrom) && !existsSync7(readFrom)) return null;
4981
+ const metadata = await extractMediaMetadata3(readFrom);
4982
+ const window2 = await resolveFinalFrameExtractionWindow2(
4983
+ readFrom,
4984
+ video,
4985
+ metadata,
4986
+ resolveVideoExtractionWindow2(video, metadata, composition.duration)
4987
+ );
4988
+ if (window2.durationSeconds <= 0) return null;
4989
+ rebaseVideoToWindow(video, window2);
4990
+ return { videoId: video.id, metadata };
4991
+ })
4992
+ );
4993
+ appendAutoDetectedVideoAudio(
4994
+ composition,
4995
+ probed.filter((entry) => entry !== null)
4996
+ );
4997
+ }
4958
4998
 
4959
4999
  // src/services/render/stages/audioStage.ts
4960
5000
  import { join as join10 } from "node:path";
@@ -8579,6 +8619,7 @@ async function compilePlanComposition(projectDir, config, planDir, options) {
8579
8619
  const needsAlpha = outputNeedsAlpha(config.format);
8580
8620
  const remoteFiles = Object.entries(options.remoteFiles ?? {});
8581
8621
  const remoteLocalPath = (rel) => join21(projectDir, ...rel.split("/"));
8622
+ for (const [, file] of remoteFiles) declareContentAddressedUrl(file.url, file.sha256);
8582
8623
  const urlByAbsentLocalPath = new Map(
8583
8624
  remoteFiles.map(([rel, file]) => [remoteLocalPath(rel), file.url])
8584
8625
  );
@@ -8977,7 +9018,7 @@ async function buildPlanAudio(projectDir, config, workRoot, outputPath, options
8977
9018
  });
8978
9019
  try {
8979
9020
  let stageStarted = Date.now();
8980
- await extractPlanVideos(c, true);
9021
+ await appendVideoAudioFromProbe(c);
8981
9022
  logPlanStage(c.log, "extract", stageStarted);
8982
9023
  stageStarted = Date.now();
8983
9024
  const mixed = await mixPlanAudio(c, c.compiledDir);
@@ -10045,7 +10086,7 @@ function cfrEncodeArgs(inputArgs, encoder, fpsArg) {
10045
10086
  "-r",
10046
10087
  fpsArg
10047
10088
  ];
10048
- appendSoftwareEncoderThreadsArg(args);
10089
+ appendSoftwareEncoderThreadsArg(args, "libx264");
10049
10090
  return args;
10050
10091
  }
10051
10092
  async function reencodeCfr(ctx, chunkPaths, encoder) {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": "0.1.0",
3
3
  "buildId": "dev",
4
- "sha256": "cd5f930c1b25aea193005449687af10c1b706fc870e51d1ff160dd46751d1581",
4
+ "sha256": "a44a8127a863733eafcb4dfa80f2517a3a74266a32bbaf072be4b7401ea46c42",
5
5
  "artifacts": {
6
6
  "iife": "hyperframe.runtime.iife.js",
7
7
  "esm": "hyperframe.runtime.mjs"