reframe-video 0.1.0 → 0.1.2

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.
@@ -6,6 +6,11 @@ Verified against each asset page's license field on 2026-06-11.
6
6
  |---|---|---|---|
7
7
  | keypress-001/004/007/010/014.wav | [Keyboard Soundpack #1](https://opengameart.org/content/keyboard-soundpack-1-typing-and-single-keystrokes) (Cherry KC 1000 recordings) | unicaegames | CC0 |
8
8
  | click_002/003/004.ogg, confirmation_001.ogg | [Interface Sounds](https://opengameart.org/content/interface-sounds) | Kenney (kenney.nl) | CC0 |
9
+ | tick.wav (tick_001), pop.wav (drop_002), shimmer.wav (glass_002 + echo tail) | [Interface Sounds](https://opengameart.org/content/interface-sounds) | Kenney (kenney.nl) | CC0 |
10
+ | whoosh.wav (wind body), rise.wav (reversed slice) | [Air whoosh](https://opengameart.org/content/air-whoosh) | qubodup | CC0 |
11
+ | whoosh.wav (transient layer: swish-9) | [Swishes Sound Pack](https://opengameart.org/content/swishes-sound-pack) | artisticdude | CC0 |
12
+ | thud.wav (trimmed) | [Muffled Distant Explosion](https://opengameart.org/content/muffled-distant-explosion) | NenadSimic | CC0 |
13
+ | bgm-song21.mp3 | [Mysterious Ambience (song21)](https://opengameart.org/content/mysterious-ambience-song21) | cynicmusic (pixelsphere.org) | multi-licensed; used under its CC0 option |
9
14
 
10
15
  CC0 requires no attribution; this file records provenance anyway.
11
16
  Files placed here named after a procedural SFX (e.g. `whoosh.wav`) override
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
package/dist/analyze.js CHANGED
@@ -155,6 +155,43 @@ async function* frameStream(source, opts) {
155
155
  if (pending.length !== 0) throw new Error(`trailing partial frame (${pending.length} bytes)`);
156
156
  }
157
157
 
158
+ // ../../benchmark/harness/motion/grid.ts
159
+ var DEFAULT_GRID = { cols: 8, rows: 5 };
160
+ var cellOf = (x, y, w, h, spec) => {
161
+ const c = Math.min(spec.cols - 1, Math.floor(x * spec.cols / w));
162
+ const r = Math.min(spec.rows - 1, Math.floor(y * spec.rows / h));
163
+ return r * spec.cols + c;
164
+ };
165
+ function cellDiff(prev, next, w, h, spec) {
166
+ const n = spec.cols * spec.rows;
167
+ const sum = new Array(n).fill(0);
168
+ const cnt = new Array(n).fill(0);
169
+ for (let y = 0; y < h; y++) {
170
+ for (let x = 0; x < w; x++) {
171
+ const idx = cellOf(x, y, w, h, spec);
172
+ sum[idx] += Math.abs(next[y * w + x] - prev[y * w + x]);
173
+ cnt[idx]++;
174
+ }
175
+ }
176
+ return sum.map((s, i) => cnt[i] ? s / cnt[i] : 0);
177
+ }
178
+ function frameOccupancy(frame, w, h, spec) {
179
+ const n = spec.cols * spec.rows;
180
+ const sum = new Array(n).fill(0);
181
+ const cnt = new Array(n).fill(0);
182
+ for (let y = 0; y < h; y++) {
183
+ for (let x = 0; x < w; x++) {
184
+ const here = frame[y * w + x];
185
+ const gx = x + 1 < w ? Math.abs(frame[y * w + x + 1] - here) : 0;
186
+ const gy = y + 1 < h ? Math.abs(frame[(y + 1) * w + x] - here) : 0;
187
+ const idx = cellOf(x, y, w, h, spec);
188
+ sum[idx] += gx + gy;
189
+ cnt[idx]++;
190
+ }
191
+ }
192
+ return sum.map((s, i) => cnt[i] ? s / cnt[i] : 0);
193
+ }
194
+
158
195
  // ../../benchmark/harness/motion/analyze.ts
159
196
  var ANALYSIS_WIDTH = 480;
160
197
  var ANALYSIS_HEIGHT = 270;
@@ -243,6 +280,7 @@ async function analyzeMotion(inputPath, opts = {}) {
243
280
  height: ANALYSIS_HEIGHT,
244
281
  ...opts.changedThreshold !== void 0 && { changedThreshold: opts.changedThreshold }
245
282
  };
283
+ const gridSpec = opts.grid ? typeof opts.grid === "object" ? opts.grid : DEFAULT_GRID : null;
246
284
  const source = await resolveSource(resolve(inputPath));
247
285
  const keys = [
248
286
  "blockSpeedMean",
@@ -256,13 +294,17 @@ async function analyzeMotion(inputPath, opts = {}) {
256
294
  "activeBlocks"
257
295
  ];
258
296
  const series = Object.fromEntries([...keys.map((k) => [k, []]), ["t", []]]);
297
+ const gridDiff = [];
298
+ const gridOcc = [];
259
299
  let prev = null;
260
300
  let pair = 0;
261
301
  for await (const frame of frameStream(source, blockOpts)) {
302
+ if (gridSpec) gridOcc.push(frameOccupancy(frame, ANALYSIS_WIDTH, ANALYSIS_HEIGHT, gridSpec));
262
303
  if (prev) {
263
304
  const stats = analyzePair(prev, frame, blockOpts);
264
305
  for (const k of keys) series[k].push(stats[k]);
265
306
  series.t.push((pair + 0.5) / fps);
307
+ if (gridSpec) gridDiff.push(cellDiff(prev, frame, ANALYSIS_WIDTH, ANALYSIS_HEIGHT, gridSpec));
266
308
  pair++;
267
309
  }
268
310
  prev = frame;
@@ -310,7 +352,8 @@ async function analyzeMotion(inputPath, opts = {}) {
310
352
  saturatedPairs: series.saturatedFraction.map((s, i) => s > 0.3 ? i : -1).filter((i) => i >= 0),
311
353
  diffPeriodicityHz: dominantPeriodicity(d, fps)
312
354
  },
313
- segments
355
+ segments,
356
+ ...gridSpec && { grid: { spec: gridSpec, diff: gridDiff, occupancy: gridOcc } }
314
357
  };
315
358
  }
316
359
  async function main() {