@hyperframes/core 0.8.120 → 0.8.122
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/compiler/htmlBundler.d.ts.map +1 -1
- package/dist/compiler/htmlBundler.js +2 -1
- package/dist/compiler/htmlBundler.js.map +1 -1
- package/dist/compiler/index.d.ts +1 -1
- package/dist/compiler/index.d.ts.map +1 -1
- package/dist/compiler/index.js +1 -1
- package/dist/compiler/index.js.map +1 -1
- package/dist/compiler/scriptRuns.d.ts +6 -0
- package/dist/compiler/scriptRuns.d.ts.map +1 -1
- package/dist/compiler/scriptRuns.js +59 -0
- package/dist/compiler/scriptRuns.js.map +1 -1
- package/dist/generated/runtime-inline.js +1 -1
- package/dist/generated/runtime-inline.js.map +1 -1
- package/dist/hyperframe.runtime.iife.js +54 -54
- package/dist/runtime/clock.d.ts +64 -0
- package/dist/runtime/clock.d.ts.map +1 -0
- package/dist/runtime/clock.js +204 -0
- package/dist/runtime/clock.js.map +1 -0
- package/dist/runtime/compositionDimension.d.ts +1 -1
- package/dist/runtime/compositionDimension.d.ts.map +1 -1
- package/dist/runtime/compositionDimension.js +3 -3
- package/dist/runtime/compositionDimension.js.map +1 -1
- package/dist/runtime/compositionLength.d.ts +44 -0
- package/dist/runtime/compositionLength.d.ts.map +1 -0
- package/dist/runtime/compositionLength.js +125 -0
- package/dist/runtime/compositionLength.js.map +1 -0
- package/dist/runtime/state.d.ts +95 -0
- package/dist/runtime/state.d.ts.map +1 -0
- package/dist/runtime/state.js +35 -0
- package/dist/runtime/state.js.map +1 -0
- package/package.json +8 -4
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { type RateSpec } from "../speedRamp.js";
|
|
2
|
+
export type TransportClockSnapshot = {
|
|
3
|
+
time: number;
|
|
4
|
+
playing: boolean;
|
|
5
|
+
rate: number;
|
|
6
|
+
duration: number;
|
|
7
|
+
source: "monotonic" | "audio";
|
|
8
|
+
};
|
|
9
|
+
export type AudioClockSource = {
|
|
10
|
+
el: HTMLMediaElement;
|
|
11
|
+
compositionStart: number;
|
|
12
|
+
mediaStart: number;
|
|
13
|
+
/** The clip's rate lane; a constant rate is read from `el.playbackRate`. */
|
|
14
|
+
rate?: RateSpec;
|
|
15
|
+
} | {
|
|
16
|
+
currentTimeSeconds: number;
|
|
17
|
+
};
|
|
18
|
+
export declare class TransportClock {
|
|
19
|
+
private _baseTime;
|
|
20
|
+
private _playStartMs;
|
|
21
|
+
private _rate;
|
|
22
|
+
private _duration;
|
|
23
|
+
private _playStart;
|
|
24
|
+
private _playEnd;
|
|
25
|
+
private _playHold;
|
|
26
|
+
private _nowMs;
|
|
27
|
+
private _audioSource;
|
|
28
|
+
/** Wall-clock time of the last `now()` read while playing; null while paused. */
|
|
29
|
+
private _lastReadMs;
|
|
30
|
+
private _lastNow;
|
|
31
|
+
constructor(opts?: {
|
|
32
|
+
initialTime?: number;
|
|
33
|
+
rate?: number;
|
|
34
|
+
duration?: number;
|
|
35
|
+
nowMs?: () => number;
|
|
36
|
+
});
|
|
37
|
+
now(): number;
|
|
38
|
+
private _elementTimeNeverBehind;
|
|
39
|
+
private _heldTimeWhenBehind;
|
|
40
|
+
/** Folds a >500ms gap since the last read into `_playStartMs` so it's never reported as played time. */
|
|
41
|
+
private _applyStallCorrection;
|
|
42
|
+
play(): boolean;
|
|
43
|
+
pause(): boolean;
|
|
44
|
+
seek(timeSeconds: number): void;
|
|
45
|
+
isPlaying(): boolean;
|
|
46
|
+
setRate(rate: number): void;
|
|
47
|
+
getRate(): number;
|
|
48
|
+
setDuration(duration: number): void;
|
|
49
|
+
getDuration(): number;
|
|
50
|
+
setPlayRange(start: number, end: number | null, fps: number): void;
|
|
51
|
+
getPlayStart(): number;
|
|
52
|
+
getEnd(): number;
|
|
53
|
+
/** Where a stop parks: the film's end, or a range's last frame, since the moment is [start, end). */
|
|
54
|
+
getStopTime(): number;
|
|
55
|
+
attachAudioSource(source: AudioClockSource): void;
|
|
56
|
+
detachAudioSource(): void;
|
|
57
|
+
/** The element the playhead currently follows, if the source is one. */
|
|
58
|
+
audioElement(): HTMLMediaElement | null;
|
|
59
|
+
hasAudioSource(): boolean;
|
|
60
|
+
getSource(): "monotonic" | "audio";
|
|
61
|
+
snapshot(): TransportClockSnapshot;
|
|
62
|
+
reachedEnd(): boolean;
|
|
63
|
+
}
|
|
64
|
+
//# sourceMappingURL=clock.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"clock.d.ts","sourceRoot":"","sources":["../../src/runtime/clock.ts"],"names":[],"mappings":"AAAA,OAAO,EAAoB,KAAK,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAIlE,MAAM,MAAM,sBAAsB,GAAG;IACnC,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC;CAC/B,CAAC;AAEF,MAAM,MAAM,gBAAgB,GACxB;IACE,EAAE,EAAE,gBAAgB,CAAC;IACrB,gBAAgB,EAAE,MAAM,CAAC;IACzB,UAAU,EAAE,MAAM,CAAC;IACnB,4EAA4E;IAC5E,IAAI,CAAC,EAAE,QAAQ,CAAC;CACjB,GACD;IACE,kBAAkB,EAAE,MAAM,CAAC;CAC5B,CAAC;AAON,qBAAa,cAAc;IACzB,OAAO,CAAC,SAAS,CAAK;IACtB,OAAO,CAAC,YAAY,CAAuB;IAC3C,OAAO,CAAC,KAAK,CAAK;IAClB,OAAO,CAAC,SAAS,CAAY;IAC7B,OAAO,CAAC,UAAU,CAAK;IACvB,OAAO,CAAC,QAAQ,CAAY;IAC5B,OAAO,CAAC,SAAS,CAAY;IAC7B,OAAO,CAAC,MAAM,CAAe;IAC7B,OAAO,CAAC,YAAY,CAAiC;IACrD,iFAAiF;IACjF,OAAO,CAAC,WAAW,CAAuB;IAC1C,OAAO,CAAC,QAAQ,CAAK;gBAET,IAAI,CAAC,EAAE;QACjB,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,KAAK,CAAC,EAAE,MAAM,MAAM,CAAC;KACtB;IAOD,GAAG,IAAI,MAAM;IAgCb,OAAO,CAAC,uBAAuB;IAW/B,OAAO,CAAC,mBAAmB;IAM3B,wGAAwG;IACxG,OAAO,CAAC,qBAAqB;IAY7B,IAAI,IAAI,OAAO;IAaf,KAAK,IAAI,OAAO;IAOhB,IAAI,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI;IAc/B,SAAS,IAAI,OAAO;IAIpB,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAU3B,OAAO,IAAI,MAAM;IAIjB,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI;IAOnC,WAAW,IAAI,MAAM;IAIrB,YAAY,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,IAAI,EAAE,GAAG,EAAE,MAAM,GAAG,IAAI;IAMlE,YAAY,IAAI,MAAM;IAItB,MAAM,IAAI,MAAM;IAIhB,qGAAqG;IACrG,WAAW,IAAI,MAAM;IAIrB,iBAAiB,CAAC,MAAM,EAAE,gBAAgB,GAAG,IAAI;IAIjD,iBAAiB,IAAI,IAAI;IAWzB,wEAAwE;IACxE,YAAY,IAAI,gBAAgB,GAAG,IAAI;IAIvC,cAAc,IAAI,OAAO;IAIzB,SAAS,IAAI,WAAW,GAAG,OAAO;IASlC,QAAQ,IAAI,sBAAsB;IAUlC,UAAU,IAAI,OAAO;CAItB"}
|
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
import { timeAtSourceTime } from "../speedRamp.js";
|
|
2
|
+
import { MEDIA_HARD_SYNC_SECONDS } from "./media.js";
|
|
3
|
+
import { playRangeHoldTime } from "./protocol.js";
|
|
4
|
+
/** GSAP's own `lagSmoothing` default — see the PR body for why this clock needs its own copy. */
|
|
5
|
+
const STALL_THRESHOLD_MS = 500;
|
|
6
|
+
const STALL_ADJUSTED_LAG_MS = 33;
|
|
7
|
+
const HAVE_FUTURE_DATA = 3;
|
|
8
|
+
export class TransportClock {
|
|
9
|
+
_baseTime = 0;
|
|
10
|
+
_playStartMs = null;
|
|
11
|
+
_rate = 1;
|
|
12
|
+
_duration = Infinity;
|
|
13
|
+
_playStart = 0;
|
|
14
|
+
_playEnd = Infinity;
|
|
15
|
+
_playHold = Infinity;
|
|
16
|
+
_nowMs;
|
|
17
|
+
_audioSource = null;
|
|
18
|
+
/** Wall-clock time of the last `now()` read while playing; null while paused. */
|
|
19
|
+
_lastReadMs = null;
|
|
20
|
+
_lastNow = 0;
|
|
21
|
+
constructor(opts) {
|
|
22
|
+
this._baseTime = opts?.initialTime ?? 0;
|
|
23
|
+
this._rate = opts?.rate ?? 1;
|
|
24
|
+
this._duration = opts?.duration ?? Infinity;
|
|
25
|
+
this._nowMs = opts?.nowMs ?? (() => performance.now());
|
|
26
|
+
}
|
|
27
|
+
now() {
|
|
28
|
+
if (this._playStartMs === null)
|
|
29
|
+
return this._baseTime;
|
|
30
|
+
// Audio-master: drift is impossible because audio IS the clock. Clearing
|
|
31
|
+
// `_lastReadMs` (not stamping it) means the next monotonic read starts
|
|
32
|
+
// fresh from `_playStartMs` instead of a timestamp audio just made
|
|
33
|
+
// meaningless — see the PR body.
|
|
34
|
+
if (this._audioSource) {
|
|
35
|
+
let audioTime = null;
|
|
36
|
+
if ("currentTimeSeconds" in this._audioSource) {
|
|
37
|
+
audioTime = this._audioSource.currentTimeSeconds;
|
|
38
|
+
}
|
|
39
|
+
else {
|
|
40
|
+
audioTime = this._elementTimeNeverBehind(this._audioSource);
|
|
41
|
+
}
|
|
42
|
+
if (audioTime !== null) {
|
|
43
|
+
const t = Math.min(audioTime, this.getEnd());
|
|
44
|
+
this._baseTime = Math.max(0, t);
|
|
45
|
+
this._playStartMs = this._nowMs();
|
|
46
|
+
this._lastReadMs = null;
|
|
47
|
+
this._lastNow = this._baseTime;
|
|
48
|
+
return this._baseTime;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
// Monotonic fallback
|
|
52
|
+
this._applyStallCorrection();
|
|
53
|
+
const elapsed = (this._nowMs() - this._playStartMs) / 1000;
|
|
54
|
+
const t = this._baseTime + elapsed * this._rate;
|
|
55
|
+
this._lastNow = Math.max(0, Math.min(t, this.getEnd()));
|
|
56
|
+
return this._lastNow;
|
|
57
|
+
}
|
|
58
|
+
_elementTimeNeverBehind(source) {
|
|
59
|
+
const { el, compositionStart, mediaStart, rate } = source;
|
|
60
|
+
if (el.paused || !Number.isFinite(el.currentTime))
|
|
61
|
+
return null;
|
|
62
|
+
if (el.seeking)
|
|
63
|
+
return this._lastNow;
|
|
64
|
+
const spec = rate ?? 1;
|
|
65
|
+
const time = timeAtSourceTime(spec, el.currentTime - mediaStart) + compositionStart;
|
|
66
|
+
return time >= this._lastNow ? time : this._heldTimeWhenBehind(el, this._lastNow - time, spec);
|
|
67
|
+
}
|
|
68
|
+
_heldTimeWhenBehind(el, behind, spec) {
|
|
69
|
+
if (el.loop && behind > timeAtSourceTime(spec, el.duration) / 2)
|
|
70
|
+
return null;
|
|
71
|
+
const buffering = el.readyState < HAVE_FUTURE_DATA;
|
|
72
|
+
return buffering || behind <= MEDIA_HARD_SYNC_SECONDS ? this._lastNow : null;
|
|
73
|
+
}
|
|
74
|
+
/** Folds a >500ms gap since the last read into `_playStartMs` so it's never reported as played time. */
|
|
75
|
+
_applyStallCorrection() {
|
|
76
|
+
if (this._playStartMs === null)
|
|
77
|
+
return;
|
|
78
|
+
const nowMs = this._nowMs();
|
|
79
|
+
if (this._lastReadMs !== null) {
|
|
80
|
+
const gapMs = nowMs - this._lastReadMs;
|
|
81
|
+
if (gapMs > STALL_THRESHOLD_MS) {
|
|
82
|
+
this._playStartMs += gapMs - STALL_ADJUSTED_LAG_MS;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
this._lastReadMs = nowMs;
|
|
86
|
+
}
|
|
87
|
+
play() {
|
|
88
|
+
if (this._playStartMs !== null)
|
|
89
|
+
return false;
|
|
90
|
+
if (this._baseTime >= this.getEnd())
|
|
91
|
+
return false;
|
|
92
|
+
this._playStartMs = this._nowMs();
|
|
93
|
+
this._lastNow = this._baseTime;
|
|
94
|
+
// Not a stall: the gap since the clock was last read (possibly a long
|
|
95
|
+
// paused idle) says nothing about lost playback time, since none was
|
|
96
|
+
// playing. `_applyStallCorrection` treats null as "nothing to compare
|
|
97
|
+
// against yet" and starts the window fresh from the next read.
|
|
98
|
+
this._lastReadMs = null;
|
|
99
|
+
return true;
|
|
100
|
+
}
|
|
101
|
+
pause() {
|
|
102
|
+
if (this._playStartMs === null)
|
|
103
|
+
return false;
|
|
104
|
+
this._baseTime = this.now();
|
|
105
|
+
this._playStartMs = null;
|
|
106
|
+
return true;
|
|
107
|
+
}
|
|
108
|
+
seek(timeSeconds) {
|
|
109
|
+
const clamped = Number.isFinite(this._duration)
|
|
110
|
+
? Math.max(0, Math.min(timeSeconds, this._duration))
|
|
111
|
+
: Math.max(0, timeSeconds);
|
|
112
|
+
this._baseTime = clamped;
|
|
113
|
+
this._lastNow = clamped;
|
|
114
|
+
if (this._playStartMs !== null) {
|
|
115
|
+
this._playStartMs = this._nowMs();
|
|
116
|
+
// Same reasoning as `play()`: the seek itself, not any elapsed gap
|
|
117
|
+
// since the last read, is why the reported time is moving now.
|
|
118
|
+
this._lastReadMs = null;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
isPlaying() {
|
|
122
|
+
return this._playStartMs !== null;
|
|
123
|
+
}
|
|
124
|
+
setRate(rate) {
|
|
125
|
+
const safe = Number.isFinite(rate) && rate > 0 ? Math.max(0.1, Math.min(5, rate)) : 1;
|
|
126
|
+
if (this._playStartMs !== null) {
|
|
127
|
+
this._baseTime = this.now();
|
|
128
|
+
this._playStartMs = this._nowMs();
|
|
129
|
+
this._lastReadMs = null;
|
|
130
|
+
}
|
|
131
|
+
this._rate = safe;
|
|
132
|
+
}
|
|
133
|
+
getRate() {
|
|
134
|
+
return this._rate;
|
|
135
|
+
}
|
|
136
|
+
setDuration(duration) {
|
|
137
|
+
this._duration = Number.isFinite(duration) && duration > 0 ? duration : Infinity;
|
|
138
|
+
if (this._baseTime > this._duration) {
|
|
139
|
+
this._baseTime = this._duration;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
getDuration() {
|
|
143
|
+
return this._duration;
|
|
144
|
+
}
|
|
145
|
+
setPlayRange(start, end, fps) {
|
|
146
|
+
this._playStart = Number.isFinite(start) && start > 0 ? start : 0;
|
|
147
|
+
this._playEnd = end !== null && Number.isFinite(end) && end > this._playStart ? end : Infinity;
|
|
148
|
+
this._playHold = playRangeHoldTime(this._playStart, this._playEnd, fps);
|
|
149
|
+
}
|
|
150
|
+
getPlayStart() {
|
|
151
|
+
return this._playStart;
|
|
152
|
+
}
|
|
153
|
+
getEnd() {
|
|
154
|
+
return Math.min(this._duration, this._playEnd);
|
|
155
|
+
}
|
|
156
|
+
/** Where a stop parks: the film's end, or a range's last frame, since the moment is [start, end). */
|
|
157
|
+
getStopTime() {
|
|
158
|
+
return this._playEnd < this._duration ? this._playHold : this.getEnd();
|
|
159
|
+
}
|
|
160
|
+
attachAudioSource(source) {
|
|
161
|
+
this._audioSource = source;
|
|
162
|
+
}
|
|
163
|
+
detachAudioSource() {
|
|
164
|
+
if (this._audioSource && this._playStartMs !== null) {
|
|
165
|
+
this._baseTime = this.now();
|
|
166
|
+
this._playStartMs = this._nowMs();
|
|
167
|
+
// Falling back to monotonic timing fresh, same reasoning as `play()`:
|
|
168
|
+
// any gap while audio was the time source is not a monotonic stall.
|
|
169
|
+
this._lastReadMs = null;
|
|
170
|
+
}
|
|
171
|
+
this._audioSource = null;
|
|
172
|
+
}
|
|
173
|
+
/** The element the playhead currently follows, if the source is one. */
|
|
174
|
+
audioElement() {
|
|
175
|
+
return this._audioSource && "el" in this._audioSource ? this._audioSource.el : null;
|
|
176
|
+
}
|
|
177
|
+
hasAudioSource() {
|
|
178
|
+
return this._audioSource !== null;
|
|
179
|
+
}
|
|
180
|
+
getSource() {
|
|
181
|
+
if (this._audioSource && this._playStartMs !== null) {
|
|
182
|
+
if ("currentTimeSeconds" in this._audioSource)
|
|
183
|
+
return "audio";
|
|
184
|
+
const { el } = this._audioSource;
|
|
185
|
+
if (!el.paused && Number.isFinite(el.currentTime))
|
|
186
|
+
return "audio";
|
|
187
|
+
}
|
|
188
|
+
return "monotonic";
|
|
189
|
+
}
|
|
190
|
+
snapshot() {
|
|
191
|
+
return {
|
|
192
|
+
time: this.now(),
|
|
193
|
+
playing: this.isPlaying(),
|
|
194
|
+
rate: this._rate,
|
|
195
|
+
duration: this._duration,
|
|
196
|
+
source: this.getSource(),
|
|
197
|
+
};
|
|
198
|
+
}
|
|
199
|
+
reachedEnd() {
|
|
200
|
+
const time = this.now();
|
|
201
|
+
return time >= this.getEnd() || (this._playStartMs === null && time >= this.getStopTime());
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
//# sourceMappingURL=clock.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"clock.js","sourceRoot":"","sources":["../../src/runtime/clock.ts"],"names":[],"mappings":"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"}
|
|
@@ -2,5 +2,5 @@
|
|
|
2
2
|
export declare function parseLayoutDimension(value: string | null | undefined): number | null;
|
|
3
3
|
/** The size the runtime reports to its host: whole px, read with `parseInt` as the renderer does. */
|
|
4
4
|
export declare function parseCompositionDimension(value: string | null | undefined): number | null;
|
|
5
|
-
export declare function findRootCompositionElement(): HTMLElement | null;
|
|
5
|
+
export declare function findRootCompositionElement(doc?: ParentNode): HTMLElement | null;
|
|
6
6
|
//# sourceMappingURL=compositionDimension.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"compositionDimension.d.ts","sourceRoot":"","sources":["../../src/runtime/compositionDimension.ts"],"names":[],"mappings":"AAEA,8FAA8F;AAC9F,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,MAAM,GAAG,IAAI,CAIpF;AAED,qGAAqG;AACrG,wBAAgB,yBAAyB,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,MAAM,GAAG,IAAI,CAIzF;AAED,wBAAgB,0BAA0B,
|
|
1
|
+
{"version":3,"file":"compositionDimension.d.ts","sourceRoot":"","sources":["../../src/runtime/compositionDimension.ts"],"names":[],"mappings":"AAEA,8FAA8F;AAC9F,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,MAAM,GAAG,IAAI,CAIpF;AAED,qGAAqG;AACrG,wBAAgB,yBAAyB,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,MAAM,GAAG,IAAI,CAIzF;AAED,wBAAgB,0BAA0B,CAAC,GAAG,GAAE,UAAqB,GAAG,WAAW,GAAG,IAAI,CAKzF"}
|
|
@@ -13,11 +13,11 @@ export function parseCompositionDimension(value) {
|
|
|
13
13
|
const parsed = Number.parseInt(value, 10);
|
|
14
14
|
return Number.isFinite(parsed) && parsed > 0 ? parsed : null;
|
|
15
15
|
}
|
|
16
|
-
export function findRootCompositionElement() {
|
|
17
|
-
const explicitRoot =
|
|
16
|
+
export function findRootCompositionElement(doc = document) {
|
|
17
|
+
const explicitRoot = doc.querySelector('[data-composition-id][data-root="true"]');
|
|
18
18
|
if (isHtmlElement(explicitRoot))
|
|
19
19
|
return explicitRoot;
|
|
20
20
|
// The first composition in document order never sits inside another one.
|
|
21
|
-
return
|
|
21
|
+
return doc.querySelector("[data-composition-id]");
|
|
22
22
|
}
|
|
23
23
|
//# sourceMappingURL=compositionDimension.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"compositionDimension.js","sourceRoot":"","sources":["../../src/runtime/compositionDimension.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAE3C,8FAA8F;AAC9F,MAAM,UAAU,oBAAoB,CAAC,KAAgC;IACnE,IAAI,KAAK,IAAI,IAAI,IAAI,KAAK,CAAC,IAAI,EAAE,KAAK,EAAE;QAAE,OAAO,IAAI,CAAC;IACtD,MAAM,MAAM,GAAG,MAAM,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;IACxC,OAAO,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC;AAC/D,CAAC;AAED,qGAAqG;AACrG,MAAM,UAAU,yBAAyB,CAAC,KAAgC;IACxE,IAAI,KAAK,IAAI,IAAI,IAAI,KAAK,CAAC,IAAI,EAAE,KAAK,EAAE;QAAE,OAAO,IAAI,CAAC;IACtD,MAAM,MAAM,GAAG,MAAM,CAAC,QAAQ,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;IAC1C,OAAO,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC;AAC/D,CAAC;AAED,MAAM,UAAU,0BAA0B;
|
|
1
|
+
{"version":3,"file":"compositionDimension.js","sourceRoot":"","sources":["../../src/runtime/compositionDimension.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAE3C,8FAA8F;AAC9F,MAAM,UAAU,oBAAoB,CAAC,KAAgC;IACnE,IAAI,KAAK,IAAI,IAAI,IAAI,KAAK,CAAC,IAAI,EAAE,KAAK,EAAE;QAAE,OAAO,IAAI,CAAC;IACtD,MAAM,MAAM,GAAG,MAAM,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;IACxC,OAAO,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC;AAC/D,CAAC;AAED,qGAAqG;AACrG,MAAM,UAAU,yBAAyB,CAAC,KAAgC;IACxE,IAAI,KAAK,IAAI,IAAI,IAAI,KAAK,CAAC,IAAI,EAAE,KAAK,EAAE;QAAE,OAAO,IAAI,CAAC;IACtD,MAAM,MAAM,GAAG,MAAM,CAAC,QAAQ,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;IAC1C,OAAO,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC;AAC/D,CAAC;AAED,MAAM,UAAU,0BAA0B,CAAC,MAAkB,QAAQ;IACnE,MAAM,YAAY,GAAG,GAAG,CAAC,aAAa,CAAC,yCAAyC,CAAC,CAAC;IAClF,IAAI,aAAa,CAAC,YAAY,CAAC;QAAE,OAAO,YAAY,CAAC;IACrD,yEAAyE;IACzE,OAAO,GAAG,CAAC,aAAa,CAAc,uBAAuB,CAAC,CAAC;AACjE,CAAC"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { type CompositionDurationResult } from "@hyperframes/parsers/composition-duration";
|
|
2
|
+
import { findRootCompositionElement } from "./compositionDimension";
|
|
3
|
+
import { createRuntimeStartTimeResolver } from "./startResolver";
|
|
4
|
+
export { findRootCompositionElement };
|
|
5
|
+
/** One frame at 60 fps: a timeline, floor or fallback this short or shorter is no length at all. */
|
|
6
|
+
export declare const MIN_VALID_TIMELINE_DURATION_SECONDS: number;
|
|
7
|
+
type StartResolver = Pick<ReturnType<typeof createRuntimeStartTimeResolver>, "resolveStartForElement" | "resolveDurationForElement">;
|
|
8
|
+
/** The size the runtime reports to its host. */
|
|
9
|
+
export declare function readCompositionSize(root: Element): {
|
|
10
|
+
width: number | null;
|
|
11
|
+
height: number | null;
|
|
12
|
+
};
|
|
13
|
+
/** The latest end among the document's timed video and audio, at their absolute starts. */
|
|
14
|
+
export declare function resolveMediaWindowDurationSeconds(doc: ParentNode, media: {
|
|
15
|
+
mediaStart: (el: HTMLMediaElement) => number;
|
|
16
|
+
mediaDuration: (el: HTMLMediaElement) => number | null;
|
|
17
|
+
}): number | null;
|
|
18
|
+
/** The latest of the root's declared length and its direct sub-compositions' ends. */
|
|
19
|
+
export declare function resolveAuthoredCompositionFloorSeconds(root: Element, startResolver: StartResolver): number | null;
|
|
20
|
+
/** The last-resort length: the latest end among the root's timed clips. Until every clip's length
|
|
21
|
+
* is known it is unresolved, so a renderer that reads it once cannot lock in a short one.
|
|
22
|
+
* `unregisteredLottie`: a Lottie library is loaded, so animations may still register. */
|
|
23
|
+
export declare function resolveContentDerivedDuration(root: Element, startResolver: StartResolver, { unregisteredLottie }: {
|
|
24
|
+
unregisteredLottie: boolean;
|
|
25
|
+
}): CompositionDurationResult;
|
|
26
|
+
export type CompositionLengthInputs = {
|
|
27
|
+
declared: number | null;
|
|
28
|
+
timeline: () => number | null;
|
|
29
|
+
floors: () => ReadonlyArray<number | null>;
|
|
30
|
+
fallback: number;
|
|
31
|
+
derived: () => number;
|
|
32
|
+
};
|
|
33
|
+
/** A declared root length is the length (a longer timeline is cut off); else the timeline, the
|
|
34
|
+
* floors and the fallback, whichever is longest; else the length derived from the clips. */
|
|
35
|
+
export declare function resolveCompositionLengthSeconds(input: CompositionLengthInputs): number;
|
|
36
|
+
/** Size, frame rate and length of a composition nothing is running (a server-parsed or detached
|
|
37
|
+
* document): no timelines, no adapters, and media without a known source length is pending. */
|
|
38
|
+
export declare function readStaticCompositionMeta(doc: Document): {
|
|
39
|
+
width: number | null;
|
|
40
|
+
height: number | null;
|
|
41
|
+
fps: number;
|
|
42
|
+
durationSeconds: number;
|
|
43
|
+
} | null;
|
|
44
|
+
//# sourceMappingURL=compositionLength.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"compositionLength.d.ts","sourceRoot":"","sources":["../../src/runtime/compositionLength.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,yBAAyB,EAC/B,MAAM,2CAA2C,CAAC;AACnD,OAAO,EAAE,0BAA0B,EAA6B,MAAM,wBAAwB,CAAC;AAG/F,OAAO,EAAE,8BAA8B,EAAE,MAAM,iBAAiB,CAAC;AAGjE,OAAO,EAAE,0BAA0B,EAAE,CAAC;AAEtC,oGAAoG;AACpG,eAAO,MAAM,mCAAmC,QAAS,CAAC;AAE1D,KAAK,aAAa,GAAG,IAAI,CACvB,UAAU,CAAC,OAAO,8BAA8B,CAAC,EACjD,wBAAwB,GAAG,2BAA2B,CACvD,CAAC;AAKF,gDAAgD;AAChD,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,OAAO,GAAG;IAClD,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;CACvB,CAKA;AAED,2FAA2F;AAC3F,wBAAgB,iCAAiC,CAC/C,GAAG,EAAE,UAAU,EACf,KAAK,EAAE;IACL,UAAU,EAAE,CAAC,EAAE,EAAE,gBAAgB,KAAK,MAAM,CAAC;IAC7C,aAAa,EAAE,CAAC,EAAE,EAAE,gBAAgB,KAAK,MAAM,GAAG,IAAI,CAAC;CACxD,GACA,MAAM,GAAG,IAAI,CAef;AAED,sFAAsF;AACtF,wBAAgB,sCAAsC,CACpD,IAAI,EAAE,OAAO,EACb,aAAa,EAAE,aAAa,GAC3B,MAAM,GAAG,IAAI,CAgBf;AAKD;;0FAE0F;AAC1F,wBAAgB,6BAA6B,CAC3C,IAAI,EAAE,OAAO,EACb,aAAa,EAAE,aAAa,EAC5B,EAAE,kBAAkB,EAAE,EAAE;IAAE,kBAAkB,EAAE,OAAO,CAAA;CAAE,GACtD,yBAAyB,CAiB3B;AAED,MAAM,MAAM,uBAAuB,GAAG;IACpC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IAExB,QAAQ,EAAE,MAAM,MAAM,GAAG,IAAI,CAAC;IAC9B,MAAM,EAAE,MAAM,aAAa,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IAC3C,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,MAAM,CAAC;CACvB,CAAC;AAEF;6FAC6F;AAC7F,wBAAgB,+BAA+B,CAAC,KAAK,EAAE,uBAAuB,GAAG,MAAM,CAgBtF;AAED;gGACgG;AAChG,wBAAgB,yBAAyB,CACvC,GAAG,EAAE,QAAQ,GACZ;IAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,eAAe,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAuB9F"}
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
import { resolveCompositionDuration, } from "@hyperframes/parsers/composition-duration";
|
|
2
|
+
import { findRootCompositionElement, parseCompositionDimension } from "./compositionDimension.js";
|
|
3
|
+
import { isMediaElement } from "./domRealm.js";
|
|
4
|
+
import { parseStrictFiniteTimingNumber, resolveMediaElementDurationSeconds } from "./playbackRate.js";
|
|
5
|
+
import { createRuntimeStartTimeResolver } from "./startResolver.js";
|
|
6
|
+
import { createRuntimeState } from "./state.js";
|
|
7
|
+
export { findRootCompositionElement };
|
|
8
|
+
/** One frame at 60 fps: a timeline, floor or fallback this short or shorter is no length at all. */
|
|
9
|
+
export const MIN_VALID_TIMELINE_DURATION_SECONDS = 1 / 60;
|
|
10
|
+
const aboveOneFrame = (seconds) => seconds !== null && seconds > MIN_VALID_TIMELINE_DURATION_SECONDS ? seconds : null;
|
|
11
|
+
/** The size the runtime reports to its host. */
|
|
12
|
+
export function readCompositionSize(root) {
|
|
13
|
+
return {
|
|
14
|
+
width: parseCompositionDimension(root.getAttribute("data-width")),
|
|
15
|
+
height: parseCompositionDimension(root.getAttribute("data-height")),
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
/** The latest end among the document's timed video and audio, at their absolute starts. */
|
|
19
|
+
export function resolveMediaWindowDurationSeconds(doc, media) {
|
|
20
|
+
const clipEnds = [];
|
|
21
|
+
for (const node of doc.querySelectorAll("video[data-start], audio[data-start]")) {
|
|
22
|
+
const start = media.mediaStart(node);
|
|
23
|
+
if (!Number.isFinite(start))
|
|
24
|
+
continue;
|
|
25
|
+
const duration = media.mediaDuration(node);
|
|
26
|
+
if (duration == null || duration <= MIN_VALID_TIMELINE_DURATION_SECONDS)
|
|
27
|
+
continue;
|
|
28
|
+
clipEnds.push(Math.max(0, start) + duration);
|
|
29
|
+
}
|
|
30
|
+
return aboveOneFrame(resolveCompositionDuration({ authoredDurationSeconds: null, clipEndsSeconds: clipEnds })
|
|
31
|
+
.seconds);
|
|
32
|
+
}
|
|
33
|
+
/** The latest of the root's declared length and its direct sub-compositions' ends. */
|
|
34
|
+
export function resolveAuthoredCompositionFloorSeconds(root, startResolver) {
|
|
35
|
+
const subCompositionEnds = [];
|
|
36
|
+
for (const node of root.querySelectorAll("[data-composition-id][data-start]")) {
|
|
37
|
+
if (node.parentElement?.closest("[data-composition-id]") !== root)
|
|
38
|
+
continue;
|
|
39
|
+
const start = startResolver.resolveStartForElement(node, 0);
|
|
40
|
+
const duration = startResolver.resolveDurationForElement(node);
|
|
41
|
+
if (!Number.isFinite(start) || duration == null || duration <= 0)
|
|
42
|
+
continue;
|
|
43
|
+
subCompositionEnds.push(Math.max(0, start) + duration);
|
|
44
|
+
}
|
|
45
|
+
const declared = parseStrictFiniteTimingNumber(root.getAttribute("data-duration"));
|
|
46
|
+
return aboveOneFrame(resolveCompositionDuration({
|
|
47
|
+
authoredDurationSeconds: null,
|
|
48
|
+
clipEndsSeconds: [declared, ...subCompositionEnds],
|
|
49
|
+
}).seconds);
|
|
50
|
+
}
|
|
51
|
+
const isCompositionHost = (node) => node.hasAttribute("data-composition-id") || node.hasAttribute("data-composition-src");
|
|
52
|
+
/** The last-resort length: the latest end among the root's timed clips. Until every clip's length
|
|
53
|
+
* is known it is unresolved, so a renderer that reads it once cannot lock in a short one.
|
|
54
|
+
* `unregisteredLottie`: a Lottie library is loaded, so animations may still register. */
|
|
55
|
+
export function resolveContentDerivedDuration(root, startResolver, { unregisteredLottie }) {
|
|
56
|
+
const clipEnds = [];
|
|
57
|
+
for (const node of root.querySelectorAll("[data-start]")) {
|
|
58
|
+
const start = startResolver.resolveStartForElement(node, 0);
|
|
59
|
+
if (!Number.isFinite(start))
|
|
60
|
+
continue;
|
|
61
|
+
const duration = startResolver.resolveDurationForElement(node);
|
|
62
|
+
if (duration != null)
|
|
63
|
+
clipEnds.push(Math.max(0, start) + duration);
|
|
64
|
+
else if (isMediaElement(node) || isCompositionHost(node))
|
|
65
|
+
clipEnds.push(null);
|
|
66
|
+
}
|
|
67
|
+
if (unregisteredLottie || root.querySelector("[data-lottie-src]"))
|
|
68
|
+
clipEnds.push(null);
|
|
69
|
+
const result = resolveCompositionDuration({
|
|
70
|
+
authoredDurationSeconds: null,
|
|
71
|
+
clipEndsSeconds: clipEnds,
|
|
72
|
+
});
|
|
73
|
+
return result.pendingClips > 0
|
|
74
|
+
? { ...result, seconds: null, source: "unresolved", reason: "a clip's length is pending" }
|
|
75
|
+
: result;
|
|
76
|
+
}
|
|
77
|
+
/** A declared root length is the length (a longer timeline is cut off); else the timeline, the
|
|
78
|
+
* floors and the fallback, whichever is longest; else the length derived from the clips. */
|
|
79
|
+
export function resolveCompositionLengthSeconds(input) {
|
|
80
|
+
if (input.declared !== null && Number.isFinite(input.declared) && input.declared > 0) {
|
|
81
|
+
return input.declared;
|
|
82
|
+
}
|
|
83
|
+
const timeline = aboveOneFrame(input.timeline());
|
|
84
|
+
const floor = Math.max(0, ...input.floors().map((seconds) => seconds ?? 0));
|
|
85
|
+
const fallback = Number.isFinite(input.fallback) && input.fallback > MIN_VALID_TIMELINE_DURATION_SECONDS
|
|
86
|
+
? input.fallback
|
|
87
|
+
: 0;
|
|
88
|
+
let seconds;
|
|
89
|
+
if (timeline !== null)
|
|
90
|
+
seconds = Math.max(timeline, floor, fallback);
|
|
91
|
+
else if (aboveOneFrame(floor) !== null)
|
|
92
|
+
seconds = Math.max(floor, fallback);
|
|
93
|
+
else if (fallback > 0)
|
|
94
|
+
seconds = fallback;
|
|
95
|
+
else
|
|
96
|
+
seconds = input.derived();
|
|
97
|
+
return seconds > 0 ? seconds : 0;
|
|
98
|
+
}
|
|
99
|
+
/** Size, frame rate and length of a composition nothing is running (a server-parsed or detached
|
|
100
|
+
* document): no timelines, no adapters, and media without a known source length is pending. */
|
|
101
|
+
export function readStaticCompositionMeta(doc) {
|
|
102
|
+
const root = findRootCompositionElement(doc);
|
|
103
|
+
if (!root)
|
|
104
|
+
return null;
|
|
105
|
+
const resolver = createRuntimeStartTimeResolver({
|
|
106
|
+
timelineRegistry: {},
|
|
107
|
+
includeAuthoredTimingAttrs: true,
|
|
108
|
+
documentRef: doc,
|
|
109
|
+
});
|
|
110
|
+
const durationSeconds = resolveCompositionLengthSeconds({
|
|
111
|
+
declared: parseStrictFiniteTimingNumber(root.getAttribute("data-duration")),
|
|
112
|
+
timeline: () => null,
|
|
113
|
+
floors: () => [
|
|
114
|
+
resolveMediaWindowDurationSeconds(doc, {
|
|
115
|
+
mediaStart: resolver.resolveMediaStartForElement,
|
|
116
|
+
mediaDuration: resolveMediaElementDurationSeconds,
|
|
117
|
+
}),
|
|
118
|
+
resolveAuthoredCompositionFloorSeconds(root, resolver),
|
|
119
|
+
],
|
|
120
|
+
fallback: 0,
|
|
121
|
+
derived: () => resolveContentDerivedDuration(root, resolver, { unregisteredLottie: false }).seconds ?? 0,
|
|
122
|
+
});
|
|
123
|
+
return { ...readCompositionSize(root), fps: createRuntimeState().canonicalFps, durationSeconds };
|
|
124
|
+
}
|
|
125
|
+
//# sourceMappingURL=compositionLength.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"compositionLength.js","sourceRoot":"","sources":["../../src/runtime/compositionLength.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import type { RuntimeDeterministicAdapter, RuntimeTimelineLike } from "./types";
|
|
2
|
+
import type { RuntimeMediaClip } from "./media";
|
|
3
|
+
import type { TransportClock } from "./clock";
|
|
4
|
+
export type RuntimeState = {
|
|
5
|
+
capturedTimeline: RuntimeTimelineLike | null;
|
|
6
|
+
isPlaying: boolean;
|
|
7
|
+
currentTime: number;
|
|
8
|
+
deterministicAdapters: RuntimeDeterministicAdapter[];
|
|
9
|
+
canonicalFps: number;
|
|
10
|
+
bridgeMuted: boolean;
|
|
11
|
+
bridgeVolume: number;
|
|
12
|
+
/**
|
|
13
|
+
* Internal mute of audible media output, owned by the audio-ownership
|
|
14
|
+
* protocol between the parent (`<hyperframes-player>`) and this runtime.
|
|
15
|
+
* Independent of `bridgeMuted` (the user's mute preference). When the
|
|
16
|
+
* parent takes over audible playback via parent-frame proxies, it sets
|
|
17
|
+
* this to `true` so the runtime keeps driving timed media for frame
|
|
18
|
+
* accuracy but produces no audio of its own.
|
|
19
|
+
*/
|
|
20
|
+
mediaOutputMuted: boolean;
|
|
21
|
+
/**
|
|
22
|
+
* Disable runtime ownership of native media elements. Slideshow presenter
|
|
23
|
+
* mode keeps the slide timeline paused while users interact with embedded
|
|
24
|
+
* media, so the runtime must not auto-play, auto-pause, seek, or volume-sync
|
|
25
|
+
* those native elements on every transport tick.
|
|
26
|
+
*/
|
|
27
|
+
nativeMediaSyncDisabled: boolean;
|
|
28
|
+
/**
|
|
29
|
+
* Disable the runtime's WebAudio replacement for native <audio> elements.
|
|
30
|
+
* Slideshow presenter/audience windows mirror native media element events
|
|
31
|
+
* across browsers, so muting those elements for WebAudio ownership breaks
|
|
32
|
+
* audible presenter playback and remote sync.
|
|
33
|
+
*/
|
|
34
|
+
webAudioMediaDisabled: boolean;
|
|
35
|
+
/**
|
|
36
|
+
* Latch so the `media-autoplay-blocked` outbound message is posted at most
|
|
37
|
+
* once per runtime session. The parent only needs the first signal — it
|
|
38
|
+
* takes over playback and further rejections are the same problem.
|
|
39
|
+
*/
|
|
40
|
+
mediaAutoplayBlockedPosted: boolean;
|
|
41
|
+
/**
|
|
42
|
+
* One-shot flag: force a hard media sync on the next tick. Set on
|
|
43
|
+
* play/pause/seek/rate transitions to immediately correct any
|
|
44
|
+
* accumulated sub-threshold drift from pause/play toggling.
|
|
45
|
+
* Consumed (reset to false) by `syncMediaForCurrentState`.
|
|
46
|
+
*/
|
|
47
|
+
mediaForceSyncNextTick: boolean;
|
|
48
|
+
playbackRate: number;
|
|
49
|
+
bridgeLastPostedFrame: number;
|
|
50
|
+
bridgeLastPostedAt: number;
|
|
51
|
+
bridgeLastPostedPlaying: boolean;
|
|
52
|
+
bridgeLastPostedMuted: boolean;
|
|
53
|
+
/**
|
|
54
|
+
* Max interval (ms) between outbound timeline samples on the parent-frame
|
|
55
|
+
* control bridge. The bridge posts on every changed frame, but also at
|
|
56
|
+
* least once per this interval so a paused/idle timeline still confirms
|
|
57
|
+
* its position to any listener.
|
|
58
|
+
*
|
|
59
|
+
* **Cross-reference (do not change in isolation)**: the parent-frame
|
|
60
|
+
* audio-mirror loop in `<hyperframes-player>` waits for
|
|
61
|
+
* `MIRROR_REQUIRED_CONSECUTIVE_DRIFT_SAMPLES` consecutive over-threshold
|
|
62
|
+
* samples before issuing a `currentTime` correction. The product of
|
|
63
|
+
* those two constants is the worst-case A/V re-sync latency:
|
|
64
|
+
*
|
|
65
|
+
* worst_case_correction_latency_ms
|
|
66
|
+
* ≈ MIRROR_REQUIRED_CONSECUTIVE_DRIFT_SAMPLES × bridgeMaxPostIntervalMs
|
|
67
|
+
*
|
|
68
|
+
* Today: `2 × 80 ms = 160 ms`, which sits comfortably under the
|
|
69
|
+
* perceptual A/V re-sync tolerance. If you raise this interval, audit
|
|
70
|
+
* `MIRROR_REQUIRED_CONSECUTIVE_DRIFT_SAMPLES` in
|
|
71
|
+
* `packages/player/src/parent-media.ts` — leaving it at `2` will
|
|
72
|
+
* silently push correction latency past the tolerance budget.
|
|
73
|
+
*/
|
|
74
|
+
bridgeMaxPostIntervalMs: number;
|
|
75
|
+
controlBridgeHandler: ((event: MessageEvent) => void) | null;
|
|
76
|
+
beforeUnloadHandler: (() => void) | null;
|
|
77
|
+
injectedCompStyles: HTMLStyleElement[];
|
|
78
|
+
injectedCompScripts: HTMLScriptElement[];
|
|
79
|
+
injectedCompLinks: HTMLLinkElement[];
|
|
80
|
+
cachedTimedMediaEls: Array<HTMLVideoElement | HTMLAudioElement>;
|
|
81
|
+
cachedMediaClips: RuntimeMediaClip[];
|
|
82
|
+
cachedVideoClips: RuntimeMediaClip[];
|
|
83
|
+
cachedMediaTimelineDurationSeconds: number;
|
|
84
|
+
tornDown: boolean;
|
|
85
|
+
/**
|
|
86
|
+
* Single-clock transport. The sole time authority — GSAP is always
|
|
87
|
+
* paused and seeked to `clock.now()` on each rAF tick. Eliminates
|
|
88
|
+
* the two-clock drift problem described in issue #668.
|
|
89
|
+
*/
|
|
90
|
+
transportClock: TransportClock | null;
|
|
91
|
+
/** rAF ID for the single-clock tick loop. */
|
|
92
|
+
transportRafId: number | null;
|
|
93
|
+
};
|
|
94
|
+
export declare function createRuntimeState(): RuntimeState;
|
|
95
|
+
//# sourceMappingURL=state.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"state.d.ts","sourceRoot":"","sources":["../../src/runtime/state.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,2BAA2B,EAAE,mBAAmB,EAAE,MAAM,SAAS,CAAC;AAChF,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAChD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAE9C,MAAM,MAAM,YAAY,GAAG;IACzB,gBAAgB,EAAE,mBAAmB,GAAG,IAAI,CAAC;IAC7C,SAAS,EAAE,OAAO,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,qBAAqB,EAAE,2BAA2B,EAAE,CAAC;IACrD,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,OAAO,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;IACrB;;;;;;;OAOG;IACH,gBAAgB,EAAE,OAAO,CAAC;IAC1B;;;;;OAKG;IACH,uBAAuB,EAAE,OAAO,CAAC;IACjC;;;;;OAKG;IACH,qBAAqB,EAAE,OAAO,CAAC;IAC/B;;;;OAIG;IACH,0BAA0B,EAAE,OAAO,CAAC;IACpC;;;;;OAKG;IACH,sBAAsB,EAAE,OAAO,CAAC;IAChC,YAAY,EAAE,MAAM,CAAC;IACrB,qBAAqB,EAAE,MAAM,CAAC;IAC9B,kBAAkB,EAAE,MAAM,CAAC;IAC3B,uBAAuB,EAAE,OAAO,CAAC;IACjC,qBAAqB,EAAE,OAAO,CAAC;IAC/B;;;;;;;;;;;;;;;;;;;;OAoBG;IACH,uBAAuB,EAAE,MAAM,CAAC;IAChC,oBAAoB,EAAE,CAAC,CAAC,KAAK,EAAE,YAAY,KAAK,IAAI,CAAC,GAAG,IAAI,CAAC;IAC7D,mBAAmB,EAAE,CAAC,MAAM,IAAI,CAAC,GAAG,IAAI,CAAC;IACzC,kBAAkB,EAAE,gBAAgB,EAAE,CAAC;IACvC,mBAAmB,EAAE,iBAAiB,EAAE,CAAC;IACzC,iBAAiB,EAAE,eAAe,EAAE,CAAC;IACrC,mBAAmB,EAAE,KAAK,CAAC,gBAAgB,GAAG,gBAAgB,CAAC,CAAC;IAChE,gBAAgB,EAAE,gBAAgB,EAAE,CAAC;IACrC,gBAAgB,EAAE,gBAAgB,EAAE,CAAC;IACrC,kCAAkC,EAAE,MAAM,CAAC;IAC3C,QAAQ,EAAE,OAAO,CAAC;IAClB;;;;OAIG;IACH,cAAc,EAAE,cAAc,GAAG,IAAI,CAAC;IACtC,6CAA6C;IAC7C,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;CAC/B,CAAC;AAEF,wBAAgB,kBAAkB,IAAI,YAAY,CAiCjD"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
export function createRuntimeState() {
|
|
2
|
+
return {
|
|
3
|
+
capturedTimeline: null,
|
|
4
|
+
isPlaying: false,
|
|
5
|
+
currentTime: 0,
|
|
6
|
+
deterministicAdapters: [],
|
|
7
|
+
canonicalFps: 30,
|
|
8
|
+
bridgeMuted: false,
|
|
9
|
+
bridgeVolume: 1,
|
|
10
|
+
mediaOutputMuted: false,
|
|
11
|
+
nativeMediaSyncDisabled: false,
|
|
12
|
+
webAudioMediaDisabled: false,
|
|
13
|
+
mediaAutoplayBlockedPosted: false,
|
|
14
|
+
mediaForceSyncNextTick: false,
|
|
15
|
+
playbackRate: 1,
|
|
16
|
+
bridgeLastPostedFrame: -1,
|
|
17
|
+
bridgeLastPostedAt: 0,
|
|
18
|
+
bridgeLastPostedPlaying: false,
|
|
19
|
+
bridgeLastPostedMuted: false,
|
|
20
|
+
bridgeMaxPostIntervalMs: 80,
|
|
21
|
+
controlBridgeHandler: null,
|
|
22
|
+
beforeUnloadHandler: null,
|
|
23
|
+
injectedCompStyles: [],
|
|
24
|
+
injectedCompScripts: [],
|
|
25
|
+
injectedCompLinks: [],
|
|
26
|
+
cachedTimedMediaEls: [],
|
|
27
|
+
cachedMediaClips: [],
|
|
28
|
+
cachedVideoClips: [],
|
|
29
|
+
cachedMediaTimelineDurationSeconds: 0,
|
|
30
|
+
tornDown: false,
|
|
31
|
+
transportClock: null,
|
|
32
|
+
transportRafId: null,
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
//# sourceMappingURL=state.js.map
|