@hyperframes/inspector 0.8.206 → 0.8.208
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.
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/** Clip-edge fades: `data-fade-in` / `data-fade-out` in seconds, linear, multiplied on the resolved level. */
|
|
2
|
+
export declare const HF_AUDIO_FADE_IN_ATTR = "data-fade-in";
|
|
3
|
+
export declare const HF_AUDIO_FADE_OUT_ATTR = "data-fade-out";
|
|
4
|
+
export declare const HF_AUDIO_FADE_IN_DATA_KEY: string;
|
|
5
|
+
export declare const HF_AUDIO_FADE_OUT_DATA_KEY: string;
|
|
6
|
+
export interface AudioFades {
|
|
7
|
+
/** Seconds from the clip start over which gain rises 0 → 1. */
|
|
8
|
+
fadeIn: number;
|
|
9
|
+
/** Seconds before the clip end over which gain falls 1 → 0. */
|
|
10
|
+
fadeOut: number;
|
|
11
|
+
}
|
|
12
|
+
export declare const NO_FADES: Readonly<AudioFades>;
|
|
13
|
+
/** Attribute text as seconds: finite and positive, else 0 (no fade). */
|
|
14
|
+
export declare function readFadeSeconds(raw: string | null | undefined): number;
|
|
15
|
+
export declare function readElementFades(el: {
|
|
16
|
+
getAttribute(name: string): string | null;
|
|
17
|
+
}): AudioFades;
|
|
18
|
+
/** Scale fades that outrun the clip so they meet inside it. Infinite duration keeps them as authored. */
|
|
19
|
+
export declare function clampFadesToDuration(fades: AudioFades, duration: number): AudioFades;
|
|
20
|
+
/** Gain at `elapsed` into a clip of `duration`. 1 where no fade runs; the two multiply where they meet. */
|
|
21
|
+
export declare function fadeGain(elapsed: number, duration: number, fades: AudioFades): number;
|
|
22
|
+
/** Attribute text Studio writes: up to 2 decimals, no trailing zeros. */
|
|
23
|
+
export declare function formatFadeSeconds(seconds: number): string;
|
|
@@ -62,7 +62,7 @@ export declare function parseAttributeSelector(predicate: string): {
|
|
|
62
62
|
name: string;
|
|
63
63
|
rawName: string;
|
|
64
64
|
namespace: AttributeNamespace;
|
|
65
|
-
operator: "=" | "
|
|
65
|
+
operator: "=" | "*=" | "|=" | "^=" | "~=" | "$=";
|
|
66
66
|
value: string;
|
|
67
67
|
flag: string | undefined;
|
|
68
68
|
} | null;
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import type { RuntimeTimelineLike } from "./types.js";
|
|
2
|
+
/**
|
|
3
|
+
* Shared volume-automation utilities used by both the renderer (offline PCM
|
|
4
|
+
* baking in audioVolumeEnvelope.ts) and the preview runtime (per-tick gain
|
|
5
|
+
* applied in syncRuntimeMedia).
|
|
6
|
+
*
|
|
7
|
+
* Keeping the two concerns in one place ensures preview and render derive the
|
|
8
|
+
* envelope from the same logic and the same probe samples.
|
|
9
|
+
*/
|
|
10
|
+
export interface VolumeKeyframe {
|
|
11
|
+
time: number;
|
|
12
|
+
volume: number;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Normalise raw keyframes to track-relative seconds: subtract `trackStart`,
|
|
16
|
+
* clamp to [0,1], sort, de-duplicate, and prepend a `baseVolume` anchor at
|
|
17
|
+
* t=0 when the first keyframe starts after the clip's begin.
|
|
18
|
+
*
|
|
19
|
+
* Returns an empty array when all keyframes are invalid — the caller should
|
|
20
|
+
* treat an empty envelope as "no automation, use static volume."
|
|
21
|
+
*/
|
|
22
|
+
export declare function normaliseEnvelope(keyframes: VolumeKeyframe[], trackStart: number, baseVolume: number): VolumeKeyframe[];
|
|
23
|
+
/**
|
|
24
|
+
* Linearly interpolate the gain at time `t` (track-relative seconds) from a
|
|
25
|
+
* normalised envelope produced by `normaliseEnvelope`. Returns 1 when the
|
|
26
|
+
* envelope is empty.
|
|
27
|
+
*/
|
|
28
|
+
export declare function interpolateVolumeGain(envelope: VolumeKeyframe[], t: number): number;
|
|
29
|
+
/**
|
|
30
|
+
* Probe a single media element's volume automation by seeking a GSAP timeline
|
|
31
|
+
* through the element's active window.
|
|
32
|
+
*
|
|
33
|
+
* Runs synchronously in the browser. The timeline is left at its current
|
|
34
|
+
* position after the probe (the next transport tick re-seeks it to `t`).
|
|
35
|
+
*
|
|
36
|
+
* Returns null when the element has no detectable automation (volume never
|
|
37
|
+
* changes from its initial `data-volume` value).
|
|
38
|
+
*/
|
|
39
|
+
export declare function probeElementVolumeKeyframes(el: HTMLAudioElement | HTMLVideoElement, seekTimeline: (t: number) => void, compositionDuration: number, sampleFps: number): VolumeKeyframe[] | null;
|
|
40
|
+
export type RuntimeTimelineRef = Partial<Pick<RuntimeTimelineLike, "totalTime" | "seek" | "getChildren">>;
|
|
41
|
+
export interface VolumeProbeOptions {
|
|
42
|
+
/**
|
|
43
|
+
* Render/probe pages must not sample the live visual timeline during runtime
|
|
44
|
+
* initialization. The producer discovers audio automation in its own
|
|
45
|
+
* isolated pass and bakes it before frame capture, so seeking here is both
|
|
46
|
+
* redundant and capable of materializing future zero-duration GSAP state.
|
|
47
|
+
*
|
|
48
|
+
* Preview callers omit this option and retain live automation discovery.
|
|
49
|
+
*/
|
|
50
|
+
allowLiveTimelineSeek?: boolean;
|
|
51
|
+
movers?: () => VolumeMovers;
|
|
52
|
+
}
|
|
53
|
+
export interface VolumeMovers {
|
|
54
|
+
elements: Set<unknown>;
|
|
55
|
+
anySetter: boolean;
|
|
56
|
+
unknown: boolean;
|
|
57
|
+
}
|
|
58
|
+
export declare function volumeMoversOf(timeline: RuntimeTimelineRef): VolumeMovers;
|
|
59
|
+
/**
|
|
60
|
+
* Probe a media element and, if volume automation is detected, store a
|
|
61
|
+
* NORMALISED envelope in `cache`. Safe to call with a null timeline — returns
|
|
62
|
+
* early.
|
|
63
|
+
*
|
|
64
|
+
* `probeElementVolumeKeyframes` stamps each keyframe with the timeline seek
|
|
65
|
+
* time it was sampled at. Everything downstream of this cache — like the
|
|
66
|
+
* renderer's PCM baker — indexes an envelope by track-relative seconds, so the
|
|
67
|
+
* rebase belongs here, at the one point that fills the cache, rather than at
|
|
68
|
+
* each read.
|
|
69
|
+
*/
|
|
70
|
+
export declare function probeAndCacheElementVolume(mediaEl: HTMLMediaElement, timeline: RuntimeTimelineRef | null | undefined, compositionDuration: number, cache: WeakMap<HTMLMediaElement, VolumeKeyframe[]>, options?: VolumeProbeOptions): void;
|
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
import type { HfColorGradingTarget } from "../colorGrading.js";
|
|
2
2
|
import type { RuntimeAnalyticsEvent } from "./analytics.js";
|
|
3
|
+
import type { AudioFades } from "../audioFade.js";
|
|
4
|
+
import type { RateSpec } from "../speedRamp.js";
|
|
5
|
+
import type { VolumeKeyframe } from "./mediaVolumeEnvelope.js";
|
|
3
6
|
export type RuntimeJson = string | number | boolean | null | RuntimeJson[] | {
|
|
4
7
|
[key: string]: RuntimeJson;
|
|
5
8
|
};
|
|
@@ -378,4 +381,22 @@ type RuntimeDataControlFields = {
|
|
|
378
381
|
};
|
|
379
382
|
type RuntimeBridgeControlAction = RuntimeBridgeControlActionBase | "set-runtime-data" | "clear-runtime-data";
|
|
380
383
|
export type RuntimeBridgeControlMessage = RuntimeBridgeControlMessageBase & RuntimeDataControlFields;
|
|
384
|
+
export type RuntimeMediaClip = {
|
|
385
|
+
el: HTMLVideoElement | HTMLAudioElement;
|
|
386
|
+
start: number;
|
|
387
|
+
/** The clip's own t=0 when a host's in-point cut its head; source time, lanes and fades run from it. */
|
|
388
|
+
origin?: number;
|
|
389
|
+
mediaStart: number;
|
|
390
|
+
duration: number;
|
|
391
|
+
end: number;
|
|
392
|
+
volume: number | null;
|
|
393
|
+
playbackRate: number;
|
|
394
|
+
/** The rate lane when the clip has one; otherwise `playbackRate`. */
|
|
395
|
+
rate?: RateSpec;
|
|
396
|
+
loop: boolean;
|
|
397
|
+
sourceDuration: number | null;
|
|
398
|
+
/** Probed from the GSAP timeline as the renderer does; when set they drive volume, not `data-volume`. */
|
|
399
|
+
volumeKeyframes?: VolumeKeyframe[];
|
|
400
|
+
fades?: AudioFades;
|
|
401
|
+
};
|
|
381
402
|
export {};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hyperframes/inspector",
|
|
3
|
-
"version": "0.8.
|
|
3
|
+
"version": "0.8.208",
|
|
4
4
|
"repository": {
|
|
5
5
|
"type": "git",
|
|
6
6
|
"url": "https://github.com/heygen-com/hyperframes",
|
|
@@ -43,8 +43,8 @@
|
|
|
43
43
|
"htmlparser2": "^10.1.0",
|
|
44
44
|
"postcss": "^8.5.8",
|
|
45
45
|
"puppeteer-core": "^25.8.0",
|
|
46
|
-
"@hyperframes/core": "0.8.
|
|
47
|
-
"@hyperframes/parsers": "0.8.
|
|
46
|
+
"@hyperframes/core": "0.8.208",
|
|
47
|
+
"@hyperframes/parsers": "0.8.208"
|
|
48
48
|
},
|
|
49
49
|
"devDependencies": {
|
|
50
50
|
"@types/node": "^25.0.10",
|