hyperframes 0.8.62 → 0.8.64
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.
- package/dist/cli.js +1333 -524
- package/dist/fontLocalizeCli.js +916 -226
- package/dist/hyperframe-runtime.js +191 -28
- package/dist/hyperframe.manifest.json +1 -1
- package/dist/hyperframe.runtime.iife.js +191 -28
- package/dist/hyperframes-player.global.js +1 -1
- package/dist/renderSetupWorker.js +4 -4
- package/dist/skills/media-use/scripts/lib/transcriptCutFade.mjs +21 -0
- package/dist/skills/media-use/scripts/lib/transcriptCutFade.test.mjs +33 -0
- package/dist/skills/media-use/scripts/transcript-cut.mjs +39 -8
- package/dist/skills/media-use/scripts/transcript-cut.test.mjs +117 -0
- package/dist/studio/assets/{hyperframes-player-BMHU9-3w.js → hyperframes-player-pWkneUHC.js} +1 -1
- package/dist/studio/assets/{index-Dg0Vjj_i.js → index-BEyJVAiH.js} +1 -1
- package/dist/studio/assets/{index-DS0kLbuM.css → index-BnsYeuxA.css} +1 -1
- package/dist/studio/assets/{index-DLYk_vu_.js → index-DLjjm1nC.js} +150 -150
- package/dist/studio/assets/{index-Ce1SRT2i.js → index-RRyhgH2k.js} +1 -1
- package/dist/studio/index.d.ts +44 -1
- package/dist/studio/index.html +2 -2
- package/dist/studio/index.js +4970 -5002
- package/dist/studio/index.js.map +1 -1
- package/dist/studio/styles.css +1 -1
- package/package.json +1 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
"use strict";var HyperframesPlayer=(()=>{var Ee=Object.defineProperty;var pn=Object.getOwnPropertyDescriptor;var fn=Object.getOwnPropertyNames;var hn=Object.prototype.hasOwnProperty;var bn=(n,e)=>{for(var t in e)Ee(n,t,{get:e[t],enumerable:!0})},gn=(n,e,t,i)=>{if(e&&typeof e=="object"||typeof e=="function")for(let r of fn(e))!hn.call(n,r)&&r!==t&&Ee(n,r,{get:()=>e[r],enumerable:!(i=pn(e,r))||i.enumerable});return n};var _n=n=>gn(Ee({},"__esModule",{value:!0}),n);var Yi={};bn(Yi,{HyperframesPlayer:()=>Ae,SPEED_PRESETS:()=>xe,formatSpeed:()=>G,formatTime:()=>ie});function dt(n){return n.hasRuntime||n.runtimeInjected?!1:!!(n.hasNestedCompositions||n.hasTimelines&&n.attempts>=5)}function H(n){return typeof n=="object"&&n!==null}function ct(n){return H(n)&&typeof n.getDuration=="function"}function mt(n){return H(n)&&typeof n.duration=="function"&&typeof n.time=="function"&&typeof n.seek=="function"&&typeof n.play=="function"&&typeof n.pause=="function"}var L="https://cdn.jsdelivr.net/npm/@hyperframes/core@0.8.
|
|
1
|
+
"use strict";var HyperframesPlayer=(()=>{var Ee=Object.defineProperty;var pn=Object.getOwnPropertyDescriptor;var fn=Object.getOwnPropertyNames;var hn=Object.prototype.hasOwnProperty;var bn=(n,e)=>{for(var t in e)Ee(n,t,{get:e[t],enumerable:!0})},gn=(n,e,t,i)=>{if(e&&typeof e=="object"||typeof e=="function")for(let r of fn(e))!hn.call(n,r)&&r!==t&&Ee(n,r,{get:()=>e[r],enumerable:!(i=pn(e,r))||i.enumerable});return n};var _n=n=>gn(Ee({},"__esModule",{value:!0}),n);var Yi={};bn(Yi,{HyperframesPlayer:()=>Ae,SPEED_PRESETS:()=>xe,formatSpeed:()=>G,formatTime:()=>ie});function dt(n){return n.hasRuntime||n.runtimeInjected?!1:!!(n.hasNestedCompositions||n.hasTimelines&&n.attempts>=5)}function H(n){return typeof n=="object"&&n!==null}function ct(n){return H(n)&&typeof n.getDuration=="function"}function mt(n){return H(n)&&typeof n.duration=="function"&&typeof n.time=="function"&&typeof n.seek=="function"&&typeof n.play=="function"&&typeof n.pause=="function"}var L="https://cdn.jsdelivr.net/npm/@hyperframes/core@0.8.64/dist/hyperframe.runtime.iife.js";function V(n){if(n===null)return null;let e=Number.parseInt(n,10);return Number.isFinite(e)&&e>0?e:null}function yn(n){let e=n?.querySelector("[data-composition-id][data-width][data-height]")??n?.querySelector("[data-width][data-height]");if(!e)return null;let t=V(e.getAttribute("data-width")),i=V(e.getAttribute("data-height"));return t!==null&&i!==null?{width:t,height:i}:null}var ne=class{constructor(e,t){this._iframe=e;this._callbacks=t}_iframe;_callbacks;_interval=null;_runtimeInjected=!1;get runtimeInjected(){return this._runtimeInjected}start(){this.stop(),this._runtimeInjected=!1;let e=0;this._interval=setInterval(()=>{e++;try{let t=this._iframe.contentWindow;if(!t)return;let i=!!(t.__hf||t.__player),r=!!(t.__timelines&&Object.keys(t.__timelines).length>0),o=!!this._iframe.contentDocument?.querySelector("[data-composition-src]");if(dt({hasRuntime:i,hasTimelines:r,hasNestedCompositions:o,runtimeInjected:this._runtimeInjected,attempts:e})){this._injectRuntime();return}if(this._runtimeInjected&&!i)return;let a=this._resolvePlaybackDurationAdapter(t);if(a&&a.getDuration()>0){this.stop();let s=yn(this._iframe.contentDocument);this._callbacks.onReady({duration:a.getDuration(),adapter:a,compositionSize:s});return}}catch{}e>=40&&(this.stop(),this._callbacks.onError("Composition timeline not found after 8s"))},200)}stop(){this._interval!==null&&(clearInterval(this._interval),this._interval=null)}resolveDirectTimelineAdapter(){try{let e=this._iframe.contentWindow;return e?this._resolveDirectTimelineAdapterFromWindow(e):null}catch{return null}}resolveDirectTimelineAdapterFromWindow(e){return this._resolveDirectTimelineAdapterFromWindow(e)}hasRuntimeBridge(e){return Reflect.get(e,"__hf")!==void 0||H(Reflect.get(e,"__player"))}_injectRuntime(){this._runtimeInjected=!0;try{let e=this._iframe.contentDocument;if(!e)return;let t=e.createElement("script");t.src=L,(e.head||e.documentElement).appendChild(t),this._callbacks.onRuntimeInjected?.()}catch{}}_resolveDirectTimelineAdapterFromWindow(e){if(this.hasRuntimeBridge(e))return null;let t=Reflect.get(e,"__timelines");if(!H(t))return null;let i=Object.keys(t);if(i.length===0)return null;let r=this._iframe.contentDocument?.querySelector("[data-composition-id]")?.getAttribute("data-composition-id"),o=r&&r in t?r:i[i.length-1],a=t[o];return mt(a)?a:null}_resolvePlaybackDurationAdapter(e){let t=Reflect.get(e,"__player");if(ct(t))return{kind:"runtime",getDuration:()=>t.getDuration()};let i=this._resolveDirectTimelineAdapterFromWindow(e);return i?{kind:"direct-timeline",timeline:i,getDuration:()=>i.duration()}:null}};var pt=`
|
|
2
2
|
:host {
|
|
3
3
|
display: block;
|
|
4
4
|
position: relative;
|
|
@@ -56408,10 +56408,10 @@ function collectSubCompositionSrcs(html) {
|
|
|
56408
56408
|
function cleanAssetUrl(url) {
|
|
56409
56409
|
return url.trim().split(/[?#]/, 1)[0] ?? "";
|
|
56410
56410
|
}
|
|
56411
|
-
function isWithinProjectRoot(projectDir, candidate) {
|
|
56412
|
-
const projectRoot = resolve(projectDir);
|
|
56413
|
-
const relativePath = relative(projectRoot, candidate);
|
|
56414
|
-
return relativePath === "" || !relativePath.startsWith("..") && !isAbsolute(relativePath);
|
|
56411
|
+
function isWithinProjectRoot(projectDir, candidate, pathModule = { resolve, relative, isAbsolute }) {
|
|
56412
|
+
const projectRoot = pathModule.resolve(projectDir);
|
|
56413
|
+
const relativePath = pathModule.relative(projectRoot, candidate);
|
|
56414
|
+
return relativePath === "" || !relativePath.startsWith("..") && !pathModule.isAbsolute(relativePath);
|
|
56415
56415
|
}
|
|
56416
56416
|
function addCandidate(candidates, candidate) {
|
|
56417
56417
|
if (!candidates.includes(candidate)) candidates.push(candidate);
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
function round3(n) {
|
|
2
|
+
return Math.round(Number(n) * 1000) / 1000;
|
|
3
|
+
}
|
|
4
|
+
|
|
5
|
+
// 30ms in/out ramps kill the click at every concat boundary. A segment shorter
|
|
6
|
+
// than 4x the ramp would spend its whole length fading, so scale down there and
|
|
7
|
+
// skip entirely on a degenerate one. fadeIn/fadeOut are false at the export's
|
|
8
|
+
// own true start/end, where there is no splice to smooth.
|
|
9
|
+
export function fadeFilterFor(durationSeconds, { fadeIn, fadeOut }) {
|
|
10
|
+
if (!fadeIn && !fadeOut) return null;
|
|
11
|
+
const FADE_SECONDS = 0.03;
|
|
12
|
+
if (!Number.isFinite(durationSeconds) || durationSeconds <= 0.01) return null;
|
|
13
|
+
const d = Math.min(FADE_SECONDS, durationSeconds / 4);
|
|
14
|
+
const parts = [];
|
|
15
|
+
if (fadeIn) parts.push(`afade=t=in:st=0:d=${round3(d)}`);
|
|
16
|
+
if (fadeOut) {
|
|
17
|
+
const out = round3(durationSeconds - d);
|
|
18
|
+
if (out > 0) parts.push(`afade=t=out:st=${out}:d=${round3(d)}`);
|
|
19
|
+
}
|
|
20
|
+
return parts.length ? parts.join(",") : null;
|
|
21
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import assert from "node:assert/strict";
|
|
2
|
+
import test from "node:test";
|
|
3
|
+
import { fadeFilterFor } from "./transcriptCutFade.mjs";
|
|
4
|
+
|
|
5
|
+
test("fades in only at the first segment's trailing splice", () => {
|
|
6
|
+
assert.equal(fadeFilterFor(2, { fadeIn: false, fadeOut: true }), "afade=t=out:st=1.97:d=0.03");
|
|
7
|
+
});
|
|
8
|
+
|
|
9
|
+
test("fades both edges of a middle segment's two splices", () => {
|
|
10
|
+
assert.equal(
|
|
11
|
+
fadeFilterFor(2, { fadeIn: true, fadeOut: true }),
|
|
12
|
+
"afade=t=in:st=0:d=0.03,afade=t=out:st=1.97:d=0.03",
|
|
13
|
+
);
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
test("fades out only at the last segment's leading splice", () => {
|
|
17
|
+
assert.equal(fadeFilterFor(2, { fadeIn: true, fadeOut: false }), "afade=t=in:st=0:d=0.03");
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
test("a single kept segment borders no splice at all", () => {
|
|
21
|
+
assert.equal(fadeFilterFor(2, { fadeIn: false, fadeOut: false }), null);
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
test("still scales the ramp down on a short segment with both edges faded", () => {
|
|
25
|
+
assert.equal(
|
|
26
|
+
fadeFilterFor(0.08, { fadeIn: true, fadeOut: true }),
|
|
27
|
+
"afade=t=in:st=0:d=0.02,afade=t=out:st=0.06:d=0.02",
|
|
28
|
+
);
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
test("skips a degenerate segment even when a splice is requested", () => {
|
|
32
|
+
assert.equal(fadeFilterFor(0.005, { fadeIn: true, fadeOut: true }), null);
|
|
33
|
+
});
|
|
@@ -6,6 +6,7 @@ import { tmpdir } from "node:os";
|
|
|
6
6
|
import { dirname, extname, join, resolve } from "node:path";
|
|
7
7
|
import { parseArgs } from "node:util";
|
|
8
8
|
import { compileCutList } from "./lib/cutlist.mjs";
|
|
9
|
+
import { fadeFilterFor } from "./lib/transcriptCutFade.mjs";
|
|
9
10
|
import { track } from "./lib/telemetry.mjs";
|
|
10
11
|
|
|
11
12
|
const { values: args } = parseArgs({
|
|
@@ -92,11 +93,23 @@ function run() {
|
|
|
92
93
|
|
|
93
94
|
try {
|
|
94
95
|
const parts = segments.map((segment, index) => {
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
96
|
+
// Intermediates carry PCM audio, not the final codec. Encoding each
|
|
97
|
+
// segment to a lossy codec separately makes the encoder pad every segment
|
|
98
|
+
// with priming silence (~25-35ms for AAC), which concat then bakes in as a
|
|
99
|
+
// gap at each cut -- a defect distinct from, and surviving, the fades
|
|
100
|
+
// below. PCM has no priming, so audio is encoded exactly once, at concat.
|
|
101
|
+
const ext = args.copy ? extname(outPath) || ".mp4" : isAudioOnly(outPath) ? ".wav" : ".mkv";
|
|
102
|
+
const out = join(tmpDir, `segment-${String(index).padStart(4, "0")}${ext}`);
|
|
103
|
+
// --copy stays fade-free (stream copy cannot filter). A segment's true
|
|
104
|
+
// start/end (index 0's start, the last segment's end) borders nothing
|
|
105
|
+
// kept, so only an interior splice edge gets a ramp.
|
|
106
|
+
const fade = args.copy
|
|
107
|
+
? null
|
|
108
|
+
: fadeFilterFor(segment.end - segment.start, {
|
|
109
|
+
fadeIn: index > 0,
|
|
110
|
+
fadeOut: index < segments.length - 1,
|
|
111
|
+
});
|
|
112
|
+
cutSegment(inputPath, segment, out, args.copy, fade);
|
|
100
113
|
return out;
|
|
101
114
|
});
|
|
102
115
|
const listPath = join(tmpDir, "list.txt");
|
|
@@ -107,9 +120,16 @@ function run() {
|
|
|
107
120
|
// Encode to a sibling temp (same extension so ffmpeg picks the right muxer),
|
|
108
121
|
// then atomic-rename so a SIGKILL mid-encode can't leave a truncated outPath.
|
|
109
122
|
const tmpOut = `${outPath}.part${extname(outPath) || ".mp4"}`;
|
|
123
|
+
// --copy already produced final-codec segments, so concat can stream-copy.
|
|
124
|
+
// Otherwise the PCM intermediates are encoded here, once, for the whole file.
|
|
125
|
+
const concatCodecs = args.copy
|
|
126
|
+
? ["-c", "copy"]
|
|
127
|
+
: isAudioOnly(outPath)
|
|
128
|
+
? encodeArgsFor(extname(outPath).toLowerCase())
|
|
129
|
+
: ["-c:v", "copy", "-c:a", "aac", "-b:a", "192k", "-movflags", "+faststart"];
|
|
110
130
|
execFileSync(
|
|
111
131
|
"ffmpeg",
|
|
112
|
-
["-y", "-f", "concat", "-safe", "0", "-i", listPath,
|
|
132
|
+
["-y", "-f", "concat", "-safe", "0", "-i", listPath, ...concatCodecs, tmpOut],
|
|
113
133
|
{
|
|
114
134
|
stdio: "ignore",
|
|
115
135
|
},
|
|
@@ -158,7 +178,7 @@ function run() {
|
|
|
158
178
|
console.log(`next: resolve --from ${outPath} --type <type>`);
|
|
159
179
|
}
|
|
160
180
|
|
|
161
|
-
function cutSegment(inputPath, segment, outPath, copy) {
|
|
181
|
+
function cutSegment(inputPath, segment, outPath, copy, fade) {
|
|
162
182
|
const argv = [
|
|
163
183
|
"-y",
|
|
164
184
|
"-nostdin",
|
|
@@ -171,8 +191,15 @@ function cutSegment(inputPath, segment, outPath, copy) {
|
|
|
171
191
|
];
|
|
172
192
|
if (copy) {
|
|
173
193
|
argv.push("-c", "copy", "-avoid_negative_ts", "make_zero");
|
|
194
|
+
} else if (extname(outPath).toLowerCase() === ".mkv") {
|
|
195
|
+
// Concat splices raw segment edges together; without a short ramp the
|
|
196
|
+
// waveform steps discontinuously at every boundary and you hear a click.
|
|
197
|
+
if (fade) argv.push("-af", fade);
|
|
198
|
+
// Video intermediate: keep the picture cheap and the audio uncompressed.
|
|
199
|
+
argv.push("-c:v", "libx264", "-preset", "veryfast", "-crf", "18", "-c:a", "pcm_s16le");
|
|
174
200
|
} else {
|
|
175
|
-
argv.push(
|
|
201
|
+
if (fade) argv.push("-af", fade);
|
|
202
|
+
argv.push("-c:a", "pcm_s16le");
|
|
176
203
|
}
|
|
177
204
|
argv.push(outPath);
|
|
178
205
|
execFileSync("ffmpeg", argv, { stdio: "ignore" });
|
|
@@ -180,6 +207,10 @@ function cutSegment(inputPath, segment, outPath, copy) {
|
|
|
180
207
|
|
|
181
208
|
// Codec set per output container. Audio-only outputs must not get the
|
|
182
209
|
// video-centric aac/x264 set (aac inside .wav breaks timing entirely).
|
|
210
|
+
function isAudioOnly(filePath) {
|
|
211
|
+
return [".wav", ".mp3", ".m4a", ".aac", ".flac"].includes(extname(filePath).toLowerCase());
|
|
212
|
+
}
|
|
213
|
+
|
|
183
214
|
function encodeArgsFor(ext) {
|
|
184
215
|
if (ext === ".wav") return ["-c:a", "pcm_s16le"];
|
|
185
216
|
if (ext === ".mp3") return ["-c:a", "libmp3lame", "-q:a", "2"];
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import assert from "node:assert/strict";
|
|
2
|
+
import { execFileSync, spawnSync } from "node:child_process";
|
|
3
|
+
import { mkdtempSync, rmSync, writeFileSync } from "node:fs";
|
|
4
|
+
import { tmpdir } from "node:os";
|
|
5
|
+
import { join } from "node:path";
|
|
6
|
+
import test from "node:test";
|
|
7
|
+
import { fileURLToPath } from "node:url";
|
|
8
|
+
|
|
9
|
+
const SCRIPT = fileURLToPath(new URL("./transcript-cut.mjs", import.meta.url));
|
|
10
|
+
const HAS_FFMPEG =
|
|
11
|
+
spawnSync("ffmpeg", ["-version"], { stdio: "ignore" }).status === 0 &&
|
|
12
|
+
spawnSync("ffprobe", ["-version"], { stdio: "ignore" }).status === 0;
|
|
13
|
+
|
|
14
|
+
const SAMPLE_RATE = 44100;
|
|
15
|
+
// A continuous tone's own slope between samples never exceeds amplitude * 2*pi*f/rate
|
|
16
|
+
// (~2054 for 440Hz at full scale here); a raw splice between two independently-cut
|
|
17
|
+
// points on the same tone lands at two unrelated phases, so an unfaded join jumps far
|
|
18
|
+
// past that. This threshold sits well above normal tone motion and well below a splice.
|
|
19
|
+
const MAX_CONTINUOUS_STEP = 6000;
|
|
20
|
+
const MIN_SUSPICIOUS_ZERO_RUN = 20;
|
|
21
|
+
|
|
22
|
+
function fixture() {
|
|
23
|
+
const dir = mkdtempSync(join(tmpdir(), "media-use-transcript-cut-"));
|
|
24
|
+
return { dir, cleanup: () => rmSync(dir, { recursive: true, force: true }) };
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
function run(args) {
|
|
28
|
+
return spawnSync(process.execPath, [SCRIPT, ...args], { encoding: "utf8" });
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
function readPcm(filePath) {
|
|
32
|
+
const raw = execFileSync("ffmpeg", [
|
|
33
|
+
"-hide_banner",
|
|
34
|
+
"-loglevel",
|
|
35
|
+
"error",
|
|
36
|
+
"-i",
|
|
37
|
+
filePath,
|
|
38
|
+
"-f",
|
|
39
|
+
"s16le",
|
|
40
|
+
"-ac",
|
|
41
|
+
"1",
|
|
42
|
+
"-ar",
|
|
43
|
+
String(SAMPLE_RATE),
|
|
44
|
+
"-",
|
|
45
|
+
]);
|
|
46
|
+
const samples = new Int16Array(raw.buffer, raw.byteOffset, raw.length / 2);
|
|
47
|
+
return samples;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
test(
|
|
51
|
+
"keeps a spliced tone continuous at every cut, with no raw phase jump or silence gap",
|
|
52
|
+
{ skip: !HAS_FFMPEG },
|
|
53
|
+
(t) => {
|
|
54
|
+
const { dir, cleanup } = fixture();
|
|
55
|
+
t.after(cleanup);
|
|
56
|
+
|
|
57
|
+
const source = join(dir, "tone.wav");
|
|
58
|
+
execFileSync("ffmpeg", [
|
|
59
|
+
"-y",
|
|
60
|
+
"-hide_banner",
|
|
61
|
+
"-loglevel",
|
|
62
|
+
"error",
|
|
63
|
+
"-f",
|
|
64
|
+
"lavfi",
|
|
65
|
+
"-i",
|
|
66
|
+
`sine=frequency=440:duration=6:sample_rate=${SAMPLE_RATE}`,
|
|
67
|
+
source,
|
|
68
|
+
]);
|
|
69
|
+
|
|
70
|
+
const transcriptPath = join(dir, "transcript.json");
|
|
71
|
+
writeFileSync(transcriptPath, JSON.stringify({ words: [{ text: "tone", start: 0, end: 6 }] }));
|
|
72
|
+
|
|
73
|
+
const output = join(dir, "out.wav");
|
|
74
|
+
// Two "ugly" removal ranges: neither aligned to the 440Hz period, so the kept
|
|
75
|
+
// segments' cut edges land at unrelated phases of the same continuous tone --
|
|
76
|
+
// exactly the shape that clicks without a fade, and the shape jrusso1020's
|
|
77
|
+
// review proved this branch never actually fades.
|
|
78
|
+
const result = run([
|
|
79
|
+
"--input",
|
|
80
|
+
source,
|
|
81
|
+
"--transcript",
|
|
82
|
+
transcriptPath,
|
|
83
|
+
"--remove",
|
|
84
|
+
"1.37-1.83,3.29-3.71",
|
|
85
|
+
"--out",
|
|
86
|
+
output,
|
|
87
|
+
"--json",
|
|
88
|
+
]);
|
|
89
|
+
assert.equal(result.status, 0, result.stderr || result.stdout);
|
|
90
|
+
|
|
91
|
+
const samples = readPcm(output);
|
|
92
|
+
assert.ok(samples.length > SAMPLE_RATE, "expected several seconds of audio");
|
|
93
|
+
|
|
94
|
+
let maxStep = 0;
|
|
95
|
+
let zeroRun = 0;
|
|
96
|
+
let maxZeroRun = 0;
|
|
97
|
+
for (let i = 1; i < samples.length; i++) {
|
|
98
|
+
const step = Math.abs(samples[i] - samples[i - 1]);
|
|
99
|
+
if (step > maxStep) maxStep = step;
|
|
100
|
+
if (samples[i] === 0) {
|
|
101
|
+
zeroRun++;
|
|
102
|
+
if (zeroRun > maxZeroRun) maxZeroRun = zeroRun;
|
|
103
|
+
} else {
|
|
104
|
+
zeroRun = 0;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
assert.ok(
|
|
109
|
+
maxStep <= MAX_CONTINUOUS_STEP,
|
|
110
|
+
`largest sample-to-sample step was ${maxStep}, expected <= ${MAX_CONTINUOUS_STEP} (a raw, unfaded splice)`,
|
|
111
|
+
);
|
|
112
|
+
assert.ok(
|
|
113
|
+
maxZeroRun < MIN_SUSPICIOUS_ZERO_RUN,
|
|
114
|
+
`found a run of ${maxZeroRun} consecutive zero samples, expected < ${MIN_SUSPICIOUS_ZERO_RUN} (a priming-silence gap)`,
|
|
115
|
+
);
|
|
116
|
+
},
|
|
117
|
+
);
|
package/dist/studio/assets/{hyperframes-player-BMHU9-3w.js → hyperframes-player-pWkneUHC.js}
RENAMED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
var we=Object.defineProperty;var Ae=(s,i,e)=>i in s?we(s,i,{enumerable:!0,configurable:!0,writable:!0,value:e}):s[i]=e;var h=(s,i,e)=>Ae(s,typeof i!="symbol"?i+"":i,e);import{r as he,i as Ee,a as w,b as ue,c as Ce,d as Te,s as Re,e as Se,F as Le}from"./index-
|
|
1
|
+
var we=Object.defineProperty;var Ae=(s,i,e)=>i in s?we(s,i,{enumerable:!0,configurable:!0,writable:!0,value:e}):s[i]=e;var h=(s,i,e)=>Ae(s,typeof i!="symbol"?i+"":i,e);import{r as he,i as Ee,a as w,b as ue,c as Ce,d as Te,s as Re,e as Se,F as Le}from"./index-DLjjm1nC.js";function xe(s){return s.hasRuntime||s.runtimeInjected?!1:!!(s.hasNestedCompositions||s.hasTimelines&&s.attempts>=5)}function $(s){return typeof s=="object"&&s!==null}function Me(s){return $(s)&&typeof s.getDuration=="function"}function De(s){return $(s)&&typeof s.duration=="function"&&typeof s.time=="function"&&typeof s.seek=="function"&&typeof s.play=="function"&&typeof s.pause=="function"}function Pe(s){if(!/^\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?(?:\+[0-9A-Za-z.-]+)?$/.test(s))throw new Error(`Invalid HyperFrames runtime version: ${s}`);return`https://cdn.jsdelivr.net/npm/@hyperframes/core@${s}/dist/hyperframe.runtime.iife.js`}const H=typeof __HYPERFRAMES_RUNTIME_CDN_URL__=="string"?__HYPERFRAMES_RUNTIME_CDN_URL__:Pe("0.0.0-dev");function V(s){if(s===null)return null;const i=Number.parseInt(s,10);return Number.isFinite(i)&&i>0?i:null}function ke(s){const i=(s==null?void 0:s.querySelector("[data-composition-id][data-width][data-height]"))??(s==null?void 0:s.querySelector("[data-width][data-height]"));if(!i)return null;const e=V(i.getAttribute("data-width")),t=V(i.getAttribute("data-height"));return e!==null&&t!==null?{width:e,height:t}:null}class Ie{constructor(i,e){h(this,"_interval",null);h(this,"_runtimeInjected",!1);this._iframe=i,this._callbacks=e}get runtimeInjected(){return this._runtimeInjected}start(){this.stop(),this._runtimeInjected=!1;let i=0;this._interval=setInterval(()=>{var e;i++;try{const t=this._iframe.contentWindow;if(!t)return;const r=!!(t.__hf||t.__player),n=!!(t.__timelines&&Object.keys(t.__timelines).length>0),a=!!((e=this._iframe.contentDocument)!=null&&e.querySelector("[data-composition-src]"));if(xe({hasRuntime:r,hasTimelines:n,hasNestedCompositions:a,runtimeInjected:this._runtimeInjected,attempts:i})){this._injectRuntime();return}if(this._runtimeInjected&&!r)return;const d=this._resolvePlaybackDurationAdapter(t);if(d&&d.getDuration()>0){this.stop();const c=ke(this._iframe.contentDocument);this._callbacks.onReady({duration:d.getDuration(),adapter:d,compositionSize:c});return}}catch{}i>=40&&(this.stop(),this._callbacks.onError("Composition timeline not found after 8s"))},200)}stop(){this._interval!==null&&(clearInterval(this._interval),this._interval=null)}resolveDirectTimelineAdapter(){try{const i=this._iframe.contentWindow;return i?this._resolveDirectTimelineAdapterFromWindow(i):null}catch{return null}}resolveDirectTimelineAdapterFromWindow(i){return this._resolveDirectTimelineAdapterFromWindow(i)}hasRuntimeBridge(i){return Reflect.get(i,"__hf")!==void 0||$(Reflect.get(i,"__player"))}_injectRuntime(){var i,e;this._runtimeInjected=!0;try{const t=this._iframe.contentDocument;if(!t)return;const r=t.createElement("script");r.src=H,(t.head||t.documentElement).appendChild(r),(e=(i=this._callbacks).onRuntimeInjected)==null||e.call(i)}catch{}}_resolveDirectTimelineAdapterFromWindow(i){var d,c;if(this.hasRuntimeBridge(i))return null;const e=Reflect.get(i,"__timelines");if(!$(e))return null;const t=Object.keys(e);if(t.length===0)return null;const r=(c=(d=this._iframe.contentDocument)==null?void 0:d.querySelector("[data-composition-id]"))==null?void 0:c.getAttribute("data-composition-id"),n=r&&r in e?r:t[t.length-1],a=e[n];return De(a)?a:null}_resolvePlaybackDurationAdapter(i){const e=Reflect.get(i,"__player");if(Me(e))return{kind:"runtime",getDuration:()=>e.getDuration()};const t=this._resolveDirectTimelineAdapterFromWindow(i);return t?{kind:"direct-timeline",timeline:t,getDuration:()=>t.duration()}:null}}const Oe=`
|
|
2
2
|
:host {
|
|
3
3
|
display: block;
|
|
4
4
|
position: relative;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{g as P}from"./index-
|
|
1
|
+
import{g as P}from"./index-DLjjm1nC.js";function j(c,d){for(var s=0;s<d.length;s++){const a=d[s];if(typeof a!="string"&&!Array.isArray(a)){for(const i in a)if(i!=="default"&&!(i in c)){const l=Object.getOwnPropertyDescriptor(a,i);l&&Object.defineProperty(c,i,l.get?l:{enumerable:!0,get:()=>a[i]})}}}return Object.freeze(Object.defineProperty(c,Symbol.toStringTag,{value:"Module"}))}var v={},w;function k(){if(w)return v;w=1,Object.defineProperty(v,"__esModule",{value:!0}),v.default=d;var c=window.OfflineAudioContext||window.webkitOfflineAudioContext;function d(e){var r=a(e);return r.start(0),[i,y,O(e.sampleRate),s].reduce(function(t,o){return o(t)},r.buffer.getChannelData(0))}function s(e){return e.sort(function(r,t){return t.count-r.count}).splice(0,5)[0].tempo}function a(e){var r=e.length,t=e.numberOfChannels,o=e.sampleRate,n=new c(t,r,o),u=n.createBufferSource();u.buffer=e;var f=n.createBiquadFilter();return f.type="lowpass",u.connect(f),f.connect(n.destination),u}function i(e){for(var r=[],t=.9,o=.3,n=15;r.length<n&&t>=o;)r=l(e,t),t-=.05;if(r.length<n)throw new Error("Could not find enough samples for a reliable detection.");return r}function l(e,r){for(var t=[],o=0,n=e.length;o<n;o+=1)e[o]>r&&(t.push(o),o+=1e4);return t}function y(e){var r=[];return e.forEach(function(t,o){for(var n=function(x){var g=e[o+x]-t,_=r.some(function(h){if(h.interval===g)return h.count+=1});_||r.push({interval:g,count:1})},u=0;u<10;u+=1)n(u)}),r}function O(e){return function(r){var t=[];return r.forEach(function(o){if(o.interval!==0){for(var n=60/(o.interval/e);n<90;)n*=2;for(;n>180;)n/=2;n=Math.round(n);var u=t.some(function(f){if(f.tempo===n)return f.count+=o.count});u||t.push({tempo:n,count:o.count})}}),t}}return v}var p,b;function q(){return b||(b=1,p=k().default),p}var m=q();const A=P(m),D=j({__proto__:null,default:A},[m]);export{D as i};
|