@hyperframes/engine 0.6.56 → 0.6.58

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.
@@ -1 +1 @@
1
- {"version":3,"file":"audioVolumeEnvelope.d.ts","sourceRoot":"","sources":["../../src/services/audioVolumeEnvelope.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAIH,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAwFjE;;;;;GAKG;AACH,wBAAgB,wBAAwB,CACtC,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,mBAAmB,EAAE,EAChC,UAAU,EAAE,MAAM,EAClB,UAAU,EAAE,MAAM,GACjB,OAAO,CA8CT"}
1
+ {"version":3,"file":"audioVolumeEnvelope.d.ts","sourceRoot":"","sources":["../../src/services/audioVolumeEnvelope.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAIH,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAyDjE;;;;;GAKG;AACH,wBAAgB,wBAAwB,CACtC,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,mBAAmB,EAAE,EAChC,UAAU,EAAE,MAAM,EAClB,UAAU,EAAE,MAAM,GACjB,OAAO,CAkDT"}
@@ -16,6 +16,7 @@
16
16
  */
17
17
  import { readFileSync, renameSync, writeFileSync } from "fs";
18
18
  import { randomBytes } from "crypto";
19
+ import { normaliseEnvelope } from "@hyperframes/core/media-volume-envelope";
19
20
  const PCM_FORMAT = 1; // WAVE_FORMAT_PCM
20
21
  const SUPPORTED_BITS = 16;
21
22
  /**
@@ -64,34 +65,6 @@ function parseWavLayout(buffer) {
64
65
  dataSize: data.size,
65
66
  };
66
67
  }
67
- /**
68
- * Normalise keyframes to track-relative seconds, sorted and de-duplicated, with
69
- * `baseVolume` filling any gap before the first keyframe. Returns the breakpoints
70
- * the gain envelope is linearly interpolated between.
71
- */
72
- function toRelativeEnvelope(keyframes, trackStart, baseVolume) {
73
- const points = keyframes
74
- .filter((k) => Number.isFinite(k.time) && Number.isFinite(k.volume))
75
- .map((k) => ({
76
- time: Math.max(0, k.time - trackStart),
77
- volume: Math.max(0, Math.min(1, k.volume)),
78
- }))
79
- .sort((a, b) => a.time - b.time);
80
- const deduped = [];
81
- for (const point of points) {
82
- const previous = deduped.at(-1);
83
- if (previous && Math.abs(previous.time - point.time) < 1e-9)
84
- previous.volume = point.volume;
85
- else
86
- deduped.push(point);
87
- }
88
- if (deduped.length === 0)
89
- return deduped;
90
- if (deduped[0].time > 0) {
91
- deduped.unshift({ time: 0, volume: Math.max(0, Math.min(1, baseVolume)) });
92
- }
93
- return deduped;
94
- }
95
68
  /**
96
69
  * Multiply a prepared WAV's samples by a time-varying gain envelope in place.
97
70
  *
@@ -99,7 +72,7 @@ function toRelativeEnvelope(keyframes, trackStart, baseVolume) {
99
72
  * expected 16-bit PCM (caller should fall back to the expression path).
100
73
  */
101
74
  export function applyVolumeEnvelopeToWav(wavPath, keyframes, trackStart, baseVolume) {
102
- const envelope = toRelativeEnvelope(keyframes, trackStart, baseVolume);
75
+ const envelope = normaliseEnvelope(keyframes, trackStart, baseVolume);
103
76
  if (envelope.length === 0)
104
77
  return false;
105
78
  try {
@@ -111,6 +84,10 @@ export function applyVolumeEnvelopeToWav(wavPath, keyframes, trackStart, baseVol
111
84
  const bytesPerSample = SUPPORTED_BITS / 8;
112
85
  const frameBytes = numChannels * bytesPerSample;
113
86
  const frameCount = Math.floor(dataSize / frameBytes);
87
+ // Maintain an incremental segment cursor so the per-frame envelope lookup
88
+ // is O(N+M) overall, not O(N×M). interpolateVolumeGain restarts from 0 on
89
+ // each call — fine for the preview path (one call per RAF tick) but not for
90
+ // the PCM path (one call per sample, 48k×duration frames total).
114
91
  let segment = 0;
115
92
  for (let frame = 0; frame < frameCount; frame += 1) {
116
93
  const time = frame / sampleRate;
@@ -1 +1 @@
1
- {"version":3,"file":"audioVolumeEnvelope.js","sourceRoot":"","sources":["../../src/services/audioVolumeEnvelope.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"audioVolumeEnvelope.js","sourceRoot":"","sources":["../../src/services/audioVolumeEnvelope.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hyperframes/engine",
3
- "version": "0.6.56",
3
+ "version": "0.6.58",
4
4
  "description": "Seekable web page to video rendering engine (Puppeteer + FFmpeg)",
5
5
  "repository": {
6
6
  "type": "git",
@@ -21,7 +21,7 @@
21
21
  "linkedom": "^0.18.12",
22
22
  "puppeteer": "^24.0.0",
23
23
  "puppeteer-core": "^24.39.1",
24
- "@hyperframes/core": "^0.6.56"
24
+ "@hyperframes/core": "^0.6.58"
25
25
  },
26
26
  "devDependencies": {
27
27
  "@types/node": "^25.0.10",
@@ -18,6 +18,7 @@
18
18
  import { readFileSync, renameSync, writeFileSync } from "fs";
19
19
  import { randomBytes } from "crypto";
20
20
  import type { AudioVolumeKeyframe } from "./audioMixer.types.js";
21
+ import { normaliseEnvelope } from "@hyperframes/core/media-volume-envelope";
21
22
 
22
23
  const PCM_FORMAT = 1; // WAVE_FORMAT_PCM
23
24
  const SUPPORTED_BITS = 16;
@@ -73,38 +74,6 @@ function parseWavLayout(buffer: Buffer): WavLayout | null {
73
74
  };
74
75
  }
75
76
 
76
- /**
77
- * Normalise keyframes to track-relative seconds, sorted and de-duplicated, with
78
- * `baseVolume` filling any gap before the first keyframe. Returns the breakpoints
79
- * the gain envelope is linearly interpolated between.
80
- */
81
- function toRelativeEnvelope(
82
- keyframes: AudioVolumeKeyframe[],
83
- trackStart: number,
84
- baseVolume: number,
85
- ): { time: number; volume: number }[] {
86
- const points = keyframes
87
- .filter((k) => Number.isFinite(k.time) && Number.isFinite(k.volume))
88
- .map((k) => ({
89
- time: Math.max(0, k.time - trackStart),
90
- volume: Math.max(0, Math.min(1, k.volume)),
91
- }))
92
- .sort((a, b) => a.time - b.time);
93
-
94
- const deduped: { time: number; volume: number }[] = [];
95
- for (const point of points) {
96
- const previous = deduped.at(-1);
97
- if (previous && Math.abs(previous.time - point.time) < 1e-9) previous.volume = point.volume;
98
- else deduped.push(point);
99
- }
100
-
101
- if (deduped.length === 0) return deduped;
102
- if (deduped[0]!.time > 0) {
103
- deduped.unshift({ time: 0, volume: Math.max(0, Math.min(1, baseVolume)) });
104
- }
105
- return deduped;
106
- }
107
-
108
77
  /**
109
78
  * Multiply a prepared WAV's samples by a time-varying gain envelope in place.
110
79
  *
@@ -117,7 +86,7 @@ export function applyVolumeEnvelopeToWav(
117
86
  trackStart: number,
118
87
  baseVolume: number,
119
88
  ): boolean {
120
- const envelope = toRelativeEnvelope(keyframes, trackStart, baseVolume);
89
+ const envelope = normaliseEnvelope(keyframes, trackStart, baseVolume);
121
90
  if (envelope.length === 0) return false;
122
91
 
123
92
  try {
@@ -130,6 +99,10 @@ export function applyVolumeEnvelopeToWav(
130
99
  const frameBytes = numChannels * bytesPerSample;
131
100
  const frameCount = Math.floor(dataSize / frameBytes);
132
101
 
102
+ // Maintain an incremental segment cursor so the per-frame envelope lookup
103
+ // is O(N+M) overall, not O(N×M). interpolateVolumeGain restarts from 0 on
104
+ // each call — fine for the preview path (one call per RAF tick) but not for
105
+ // the PCM path (one call per sample, 48k×duration frames total).
133
106
  let segment = 0;
134
107
  for (let frame = 0; frame < frameCount; frame += 1) {
135
108
  const time = frame / sampleRate;