@meframe/core 0.0.2 → 0.0.4
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/Meframe.d.ts.map +1 -1
- package/dist/Meframe.js +6 -4
- package/dist/Meframe.js.map +1 -1
- package/dist/cache/CacheManager.d.ts +2 -2
- package/dist/cache/CacheManager.d.ts.map +1 -1
- package/dist/cache/CacheManager.js +4 -3
- package/dist/cache/CacheManager.js.map +1 -1
- package/dist/cache/l1/VideoL1Cache.d.ts +2 -2
- package/dist/cache/l1/VideoL1Cache.d.ts.map +1 -1
- package/dist/cache/l1/VideoL1Cache.js +13 -8
- package/dist/cache/l1/VideoL1Cache.js.map +1 -1
- package/dist/config/defaults.d.ts.map +1 -1
- package/dist/config/defaults.js +3 -1
- package/dist/config/defaults.js.map +1 -1
- package/dist/config/types.d.ts +6 -0
- package/dist/config/types.d.ts.map +1 -1
- package/dist/controllers/PlaybackController.d.ts +7 -8
- package/dist/controllers/PlaybackController.d.ts.map +1 -1
- package/dist/controllers/PlaybackController.js +56 -76
- package/dist/controllers/PlaybackController.js.map +1 -1
- package/dist/controllers/types.d.ts +2 -3
- package/dist/controllers/types.d.ts.map +1 -1
- package/dist/event/events.d.ts +1 -4
- package/dist/event/events.d.ts.map +1 -1
- package/dist/event/events.js.map +1 -1
- package/dist/model/CompositionModel.d.ts +1 -0
- package/dist/model/CompositionModel.d.ts.map +1 -1
- package/dist/model/CompositionModel.js +2 -0
- package/dist/model/CompositionModel.js.map +1 -1
- package/dist/model/patch.d.ts +6 -2
- package/dist/model/patch.d.ts.map +1 -1
- package/dist/model/patch.js +76 -2
- package/dist/model/patch.js.map +1 -1
- package/dist/model/types.d.ts +1 -0
- package/dist/model/types.d.ts.map +1 -1
- package/dist/orchestrator/CompositionPlanner.d.ts +8 -7
- package/dist/orchestrator/CompositionPlanner.d.ts.map +1 -1
- package/dist/orchestrator/CompositionPlanner.js +33 -56
- package/dist/orchestrator/CompositionPlanner.js.map +1 -1
- package/dist/orchestrator/Orchestrator.d.ts +0 -1
- package/dist/orchestrator/Orchestrator.d.ts.map +1 -1
- package/dist/orchestrator/Orchestrator.js +40 -19
- package/dist/orchestrator/Orchestrator.js.map +1 -1
- package/dist/orchestrator/VideoClipSession.d.ts +3 -5
- package/dist/orchestrator/VideoClipSession.d.ts.map +1 -1
- package/dist/orchestrator/VideoClipSession.js +66 -69
- package/dist/orchestrator/VideoClipSession.js.map +1 -1
- package/dist/orchestrator/types.d.ts +2 -0
- package/dist/orchestrator/types.d.ts.map +1 -1
- package/dist/stages/compose/GlobalAudioSession.d.ts +6 -0
- package/dist/stages/compose/GlobalAudioSession.d.ts.map +1 -1
- package/dist/stages/compose/GlobalAudioSession.js +17 -1
- package/dist/stages/compose/GlobalAudioSession.js.map +1 -1
- package/dist/stages/compose/types.d.ts +2 -1
- package/dist/stages/compose/types.d.ts.map +1 -1
- package/dist/stages/demux/MP4Demuxer.d.ts +0 -1
- package/dist/stages/demux/MP4Demuxer.d.ts.map +1 -1
- package/dist/stages/load/ResourceLoader.d.ts +22 -1
- package/dist/stages/load/ResourceLoader.d.ts.map +1 -1
- package/dist/stages/load/ResourceLoader.js +71 -25
- package/dist/stages/load/ResourceLoader.js.map +1 -1
- package/dist/stages/load/TaskManager.d.ts +1 -1
- package/dist/stages/load/TaskManager.d.ts.map +1 -1
- package/dist/stages/load/TaskManager.js +3 -2
- package/dist/stages/load/TaskManager.js.map +1 -1
- package/dist/stages/load/types.d.ts +2 -0
- package/dist/stages/load/types.d.ts.map +1 -1
- package/dist/utils/time-utils.d.ts +3 -2
- package/dist/utils/time-utils.d.ts.map +1 -1
- package/dist/utils/time-utils.js +2 -1
- package/dist/utils/time-utils.js.map +1 -1
- package/dist/vite-plugin.d.ts +5 -3
- package/dist/vite-plugin.d.ts.map +1 -1
- package/dist/vite-plugin.js +109 -52
- package/dist/vite-plugin.js.map +1 -1
- package/dist/worker/WorkerPool.d.ts +9 -0
- package/dist/worker/WorkerPool.d.ts.map +1 -1
- package/dist/worker/WorkerPool.js +32 -5
- package/dist/worker/WorkerPool.js.map +1 -1
- package/dist/{stages/demux → workers}/MP4Demuxer.js +4 -13
- package/dist/workers/MP4Demuxer.js.map +1 -0
- package/dist/workers/WorkerChannel.js +486 -0
- package/dist/workers/WorkerChannel.js.map +1 -0
- package/dist/{assets/video-demux.worker-D019I7GQ.js → workers/mp4box.all.js} +4 -912
- package/dist/workers/mp4box.all.js.map +1 -0
- package/dist/{assets/audio-compose.worker-nGVvHD5Q.js → workers/stages/compose/audio-compose.worker.js} +7 -481
- package/dist/workers/stages/compose/audio-compose.worker.js.map +1 -0
- package/dist/{assets/video-compose.worker-DPzsC21d.js → workers/stages/compose/video-compose.worker.js} +120 -562
- package/dist/workers/stages/compose/video-compose.worker.js.map +1 -0
- package/dist/{assets/decode.worker-DpWHsc7R.js → workers/stages/decode/decode.worker.js} +7 -481
- package/dist/workers/stages/decode/decode.worker.js.map +1 -0
- package/dist/{stages → workers/stages}/demux/audio-demux.worker.js +184 -4
- package/dist/workers/stages/demux/audio-demux.worker.js.map +1 -0
- package/dist/{stages → workers/stages}/demux/video-demux.worker.js +2 -3
- package/dist/workers/stages/demux/video-demux.worker.js.map +1 -0
- package/dist/{stages → workers/stages}/encode/encode.worker.js +238 -4
- package/dist/workers/stages/encode/encode.worker.js.map +1 -0
- package/dist/{stages/mux/MP4Muxer.js → workers/stages/mux/mux.worker.js} +244 -5
- package/dist/workers/stages/mux/mux.worker.js.map +1 -0
- package/package.json +21 -21
- package/dist/assets/audio-compose.worker-nGVvHD5Q.js.map +0 -1
- package/dist/assets/audio-demux.worker-xwWBtbAe.js +0 -8299
- package/dist/assets/audio-demux.worker-xwWBtbAe.js.map +0 -1
- package/dist/assets/decode.worker-DpWHsc7R.js.map +0 -1
- package/dist/assets/encode.worker-nfOb3kw6.js +0 -1026
- package/dist/assets/encode.worker-nfOb3kw6.js.map +0 -1
- package/dist/assets/mux.worker-uEMQY066.js +0 -8019
- package/dist/assets/mux.worker-uEMQY066.js.map +0 -1
- package/dist/assets/video-compose.worker-DPzsC21d.js.map +0 -1
- package/dist/assets/video-demux.worker-D019I7GQ.js.map +0 -1
- package/dist/controllers/PreviewHandle.d.ts +0 -25
- package/dist/controllers/PreviewHandle.d.ts.map +0 -1
- package/dist/controllers/PreviewHandle.js +0 -45
- package/dist/controllers/PreviewHandle.js.map +0 -1
- package/dist/model/dirty-range.js +0 -220
- package/dist/model/dirty-range.js.map +0 -1
- package/dist/model/types.js +0 -5
- package/dist/model/types.js.map +0 -1
- package/dist/plugins/BackpressureMonitor.js +0 -62
- package/dist/plugins/BackpressureMonitor.js.map +0 -1
- package/dist/stages/compose/AudioDucker.js +0 -161
- package/dist/stages/compose/AudioDucker.js.map +0 -1
- package/dist/stages/compose/AudioMixer.js +0 -373
- package/dist/stages/compose/AudioMixer.js.map +0 -1
- package/dist/stages/compose/FilterProcessor.js +0 -226
- package/dist/stages/compose/FilterProcessor.js.map +0 -1
- package/dist/stages/compose/LayerRenderer.js +0 -215
- package/dist/stages/compose/LayerRenderer.js.map +0 -1
- package/dist/stages/compose/TransitionProcessor.js +0 -189
- package/dist/stages/compose/TransitionProcessor.js.map +0 -1
- package/dist/stages/compose/VideoComposer.js +0 -186
- package/dist/stages/compose/VideoComposer.js.map +0 -1
- package/dist/stages/compose/audio-compose.worker.d.ts +0 -79
- package/dist/stages/compose/audio-compose.worker.d.ts.map +0 -1
- package/dist/stages/compose/audio-compose.worker.js +0 -540
- package/dist/stages/compose/audio-compose.worker.js.map +0 -1
- package/dist/stages/compose/audio-compose.worker2.js +0 -5
- package/dist/stages/compose/audio-compose.worker2.js.map +0 -1
- package/dist/stages/compose/video-compose.worker.d.ts +0 -60
- package/dist/stages/compose/video-compose.worker.d.ts.map +0 -1
- package/dist/stages/compose/video-compose.worker.js +0 -379
- package/dist/stages/compose/video-compose.worker.js.map +0 -1
- package/dist/stages/compose/video-compose.worker2.js +0 -5
- package/dist/stages/compose/video-compose.worker2.js.map +0 -1
- package/dist/stages/decode/AudioChunkDecoder.js +0 -82
- package/dist/stages/decode/AudioChunkDecoder.js.map +0 -1
- package/dist/stages/decode/BaseDecoder.js +0 -130
- package/dist/stages/decode/BaseDecoder.js.map +0 -1
- package/dist/stages/decode/VideoChunkDecoder.js +0 -199
- package/dist/stages/decode/VideoChunkDecoder.js.map +0 -1
- package/dist/stages/decode/decode.worker.d.ts +0 -70
- package/dist/stages/decode/decode.worker.d.ts.map +0 -1
- package/dist/stages/decode/decode.worker.js +0 -423
- package/dist/stages/decode/decode.worker.js.map +0 -1
- package/dist/stages/decode/decode.worker2.js +0 -5
- package/dist/stages/decode/decode.worker2.js.map +0 -1
- package/dist/stages/demux/MP3FrameParser.js +0 -186
- package/dist/stages/demux/MP3FrameParser.js.map +0 -1
- package/dist/stages/demux/MP4Demuxer.js.map +0 -1
- package/dist/stages/demux/audio-demux.worker.d.ts +0 -51
- package/dist/stages/demux/audio-demux.worker.d.ts.map +0 -1
- package/dist/stages/demux/audio-demux.worker.js.map +0 -1
- package/dist/stages/demux/audio-demux.worker2.js +0 -5
- package/dist/stages/demux/audio-demux.worker2.js.map +0 -1
- package/dist/stages/demux/video-demux.worker.d.ts +0 -51
- package/dist/stages/demux/video-demux.worker.d.ts.map +0 -1
- package/dist/stages/demux/video-demux.worker.js.map +0 -1
- package/dist/stages/demux/video-demux.worker2.js +0 -5
- package/dist/stages/demux/video-demux.worker2.js.map +0 -1
- package/dist/stages/encode/AudioChunkEncoder.js +0 -37
- package/dist/stages/encode/AudioChunkEncoder.js.map +0 -1
- package/dist/stages/encode/BaseEncoder.js +0 -164
- package/dist/stages/encode/BaseEncoder.js.map +0 -1
- package/dist/stages/encode/VideoChunkEncoder.js +0 -50
- package/dist/stages/encode/VideoChunkEncoder.js.map +0 -1
- package/dist/stages/encode/encode.worker.d.ts +0 -3
- package/dist/stages/encode/encode.worker.d.ts.map +0 -1
- package/dist/stages/encode/encode.worker.js.map +0 -1
- package/dist/stages/encode/encode.worker2.js +0 -5
- package/dist/stages/encode/encode.worker2.js.map +0 -1
- package/dist/stages/mux/MP4Muxer.js.map +0 -1
- package/dist/stages/mux/mux.worker.d.ts +0 -65
- package/dist/stages/mux/mux.worker.d.ts.map +0 -1
- package/dist/stages/mux/mux.worker.js +0 -219
- package/dist/stages/mux/mux.worker.js.map +0 -1
- package/dist/stages/mux/mux.worker2.js +0 -5
- package/dist/stages/mux/mux.worker2.js.map +0 -1
- package/dist/stages/mux/utils.js +0 -34
- package/dist/stages/mux/utils.js.map +0 -1
- package/dist/worker/worker-registry.d.ts +0 -12
- package/dist/worker/worker-registry.d.ts.map +0 -1
- package/dist/worker/worker-registry.js +0 -20
- package/dist/worker/worker-registry.js.map +0 -1
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import { IPlaybackController,
|
|
2
|
-
import { TimeUs } from '../model/types';
|
|
1
|
+
import { IPlaybackController, PlaybackOptions, IEventBus, PreviewHandle, TimeUs } from './types';
|
|
3
2
|
import { GlobalAudioSession } from '../stages/compose/GlobalAudioSession';
|
|
4
3
|
import { Orchestrator } from '../orchestrator';
|
|
5
4
|
|
|
@@ -7,13 +6,13 @@ import { Orchestrator } from '../orchestrator';
|
|
|
7
6
|
* Playback controller for preview
|
|
8
7
|
* Internal implementation - not exposed directly to external consumers
|
|
9
8
|
*/
|
|
10
|
-
export declare class PlaybackController implements IPlaybackController {
|
|
9
|
+
export declare class PlaybackController implements IPlaybackController, PreviewHandle {
|
|
11
10
|
private orchestrator;
|
|
12
11
|
private eventBus;
|
|
13
12
|
private canvas;
|
|
14
13
|
private ctx;
|
|
15
|
-
|
|
16
|
-
private
|
|
14
|
+
currentTimeUs: TimeUs;
|
|
15
|
+
private state;
|
|
17
16
|
private playbackRate;
|
|
18
17
|
private volume;
|
|
19
18
|
private loop;
|
|
@@ -37,12 +36,12 @@ export declare class PlaybackController implements IPlaybackController {
|
|
|
37
36
|
setVolume(volume: number): void;
|
|
38
37
|
setMute(muted: boolean): void;
|
|
39
38
|
setLoop(loop: boolean): void;
|
|
40
|
-
get currentTime(): TimeUs;
|
|
41
39
|
get duration(): TimeUs;
|
|
42
|
-
get
|
|
43
|
-
get playing(): boolean;
|
|
40
|
+
get isPlaying(): boolean;
|
|
44
41
|
setAudioSession(session: GlobalAudioSession): void;
|
|
45
42
|
resume(): void;
|
|
43
|
+
on(event: string, handler: (payload: any) => void): void;
|
|
44
|
+
off(event: string, handler: (payload: any) => void): void;
|
|
46
45
|
private setupListeners;
|
|
47
46
|
private playbackLoop;
|
|
48
47
|
private updateTime;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PlaybackController.d.ts","sourceRoot":"","sources":["../../src/controllers/PlaybackController.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"PlaybackController.d.ts","sourceRoot":"","sources":["../../src/controllers/PlaybackController.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,mBAAmB,EAEnB,eAAe,EACf,SAAS,EACT,aAAa,EACb,MAAM,EACP,MAAM,SAAS,CAAC;AAGjB,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,sCAAsC,CAAC;AAC/E,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAEpD;;;GAGG;AACH,qBAAa,kBAAmB,YAAW,mBAAmB,EAAE,aAAa;IAC3E,OAAO,CAAC,YAAY,CAAe;IACnC,OAAO,CAAC,QAAQ,CAAY;IAC5B,OAAO,CAAC,MAAM,CAAsC;IACpD,OAAO,CAAC,GAAG,CAA+D;IAG1E,aAAa,EAAE,MAAM,CAAK;IAC1B,OAAO,CAAC,KAAK,CAAyB;IACtC,OAAO,CAAC,YAAY,CAAO;IAC3B,OAAO,CAAC,MAAM,CAAO;IACrB,OAAO,CAAC,IAAI,CAAS;IAGrB,OAAO,CAAC,KAAK,CAAuB;IACpC,OAAO,CAAC,SAAS,CAAK;IAGtB,OAAO,CAAC,UAAU,CAAK;IACvB,OAAO,CAAC,aAAa,CAAK;IAC1B,OAAO,CAAC,GAAG,CAAK;IAChB,OAAO,CAAC,YAAY,CAA6B;IACjD,OAAO,CAAC,WAAW,CAAsC;IACzD,OAAO,CAAC,aAAa,CAAyB;IAC9C,OAAO,CAAC,YAAY,CAAmC;IAGvD,OAAO,CAAC,WAAW,CAAS;gBAEhB,YAAY,EAAE,YAAY,EAAE,QAAQ,EAAE,SAAS,EAAE,OAAO,EAAE,eAAe;IAyCrF,IAAI,IAAI,IAAI;YAME,aAAa;IAgC3B,KAAK,IAAI,IAAI;IAeb,IAAI,IAAI,IAAI;IAiBN,IAAI,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IA+BzC,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAa3B,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAS/B,OAAO,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI;IAQ7B,OAAO,CAAC,IAAI,EAAE,OAAO,GAAG,IAAI;IAI5B,IAAI,QAAQ,IAAI,MAAM,CAOrB;IAED,IAAI,SAAS,IAAI,OAAO,CAEvB;IAED,eAAe,CAAC,OAAO,EAAE,kBAAkB,GAAG,IAAI;IAKlD,MAAM,IAAI,IAAI;IAId,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,OAAO,EAAE,GAAG,KAAK,IAAI,GAAG,IAAI;IAIxD,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,OAAO,EAAE,GAAG,KAAK,IAAI,GAAG,IAAI;IAIzD,OAAO,CAAC,cAAc;IAOtB,OAAO,CAAC,YAAY;IAwCpB,OAAO,CAAC,UAAU;YAuBJ,kBAAkB;YAwBlB,uBAAuB;IA8CrC,OAAO,CAAC,SAAS;IAKjB,OAAO,IAAI,IAAI;YAID,kBAAkB;IAWhC,OAAO,CAAC,kBAAkB;IAiC1B,OAAO,CAAC,iBAAiB;CAW1B"}
|
|
@@ -6,8 +6,8 @@ class PlaybackController {
|
|
|
6
6
|
canvas;
|
|
7
7
|
ctx;
|
|
8
8
|
// Playback state
|
|
9
|
-
|
|
10
|
-
|
|
9
|
+
currentTimeUs = 0;
|
|
10
|
+
state = "idle";
|
|
11
11
|
playbackRate = 1;
|
|
12
12
|
volume = 1;
|
|
13
13
|
loop = false;
|
|
@@ -40,7 +40,7 @@ class PlaybackController {
|
|
|
40
40
|
this.ctx.imageSmoothingEnabled = true;
|
|
41
41
|
this.ctx.imageSmoothingQuality = "high";
|
|
42
42
|
if (options.startUs !== void 0) {
|
|
43
|
-
this.
|
|
43
|
+
this.currentTimeUs = options.startUs;
|
|
44
44
|
}
|
|
45
45
|
if (options.rate !== void 0) {
|
|
46
46
|
this.playbackRate = options.rate;
|
|
@@ -55,37 +55,37 @@ class PlaybackController {
|
|
|
55
55
|
}
|
|
56
56
|
// Playback control
|
|
57
57
|
play() {
|
|
58
|
-
if (this.
|
|
58
|
+
if (this.state === "playing") return;
|
|
59
59
|
void this.startPlayback();
|
|
60
60
|
}
|
|
61
61
|
async startPlayback() {
|
|
62
|
-
const wasIdle = this.
|
|
63
|
-
this.
|
|
62
|
+
const wasIdle = this.state === "idle";
|
|
63
|
+
this.state = "buffering";
|
|
64
64
|
this.eventBus.emit(MeframeEvent.PlaybackBuffering);
|
|
65
65
|
try {
|
|
66
|
-
await this.orchestrator.ensureClipCache(this.
|
|
67
|
-
const ready = await this.orchestrator.waitForClipReady(this.
|
|
66
|
+
await this.orchestrator.ensureClipCache(this.currentTimeUs);
|
|
67
|
+
const ready = await this.orchestrator.waitForClipReady(this.currentTimeUs, {
|
|
68
68
|
minFrameCount: 30,
|
|
69
69
|
timeoutMs: 3e3
|
|
70
70
|
});
|
|
71
71
|
if (!ready) {
|
|
72
72
|
console.warn("[PlaybackController] Buffering timeout, starting anyway");
|
|
73
73
|
}
|
|
74
|
-
this.
|
|
75
|
-
this.startTime = performance.now() - this.
|
|
74
|
+
this.state = "playing";
|
|
75
|
+
this.startTime = performance.now() - this.currentTimeUs / 1e3 / this.playbackRate;
|
|
76
76
|
await this.ensureAudioContext();
|
|
77
77
|
this.startAudioPlayback();
|
|
78
78
|
this.playbackLoop();
|
|
79
79
|
this.eventBus.emit(MeframeEvent.PlaybackPlay);
|
|
80
80
|
} catch (error) {
|
|
81
81
|
console.error("[PlaybackController] Failed to start playback:", error);
|
|
82
|
-
this.
|
|
82
|
+
this.state = wasIdle ? "idle" : "paused";
|
|
83
83
|
this.eventBus.emit(MeframeEvent.PlaybackError, error);
|
|
84
84
|
}
|
|
85
85
|
}
|
|
86
86
|
pause() {
|
|
87
|
-
if (this.
|
|
88
|
-
this.
|
|
87
|
+
if (this.state !== "playing") return;
|
|
88
|
+
this.state = "paused";
|
|
89
89
|
if (this.rafId !== null) {
|
|
90
90
|
cancelAnimationFrame(this.rafId);
|
|
91
91
|
this.rafId = null;
|
|
@@ -95,8 +95,8 @@ class PlaybackController {
|
|
|
95
95
|
}
|
|
96
96
|
stop() {
|
|
97
97
|
this.pause();
|
|
98
|
-
this.
|
|
99
|
-
this.
|
|
98
|
+
this.currentTimeUs = 0;
|
|
99
|
+
this.state = "idle";
|
|
100
100
|
this.frameCount = 0;
|
|
101
101
|
this.lastFrameTime = 0;
|
|
102
102
|
this.fps = 0;
|
|
@@ -106,41 +106,27 @@ class PlaybackController {
|
|
|
106
106
|
this.eventBus.emit(MeframeEvent.PlaybackStop);
|
|
107
107
|
}
|
|
108
108
|
async seek(timeUs) {
|
|
109
|
-
const wasPlaying = this.
|
|
110
|
-
const previousState = this.
|
|
109
|
+
const wasPlaying = this.state === "playing";
|
|
110
|
+
const previousState = this.state;
|
|
111
111
|
if (wasPlaying) {
|
|
112
112
|
this.pause();
|
|
113
113
|
}
|
|
114
114
|
const clamped = this.clampTime(timeUs);
|
|
115
|
-
this.
|
|
116
|
-
this.
|
|
115
|
+
this.currentTimeUs = clamped;
|
|
116
|
+
this.state = "seeking";
|
|
117
117
|
this.stopAudioPlayback();
|
|
118
118
|
try {
|
|
119
|
-
await this.orchestrator.ensureClipCache(clamped);
|
|
120
|
-
const ready = await this.orchestrator.waitForClipReady(clamped, {
|
|
121
|
-
minFrameCount: 10,
|
|
122
|
-
timeoutMs: 3e3
|
|
123
|
-
});
|
|
124
|
-
if (!ready) {
|
|
125
|
-
console.warn("[PlaybackController] Seek buffering timeout");
|
|
126
|
-
}
|
|
127
119
|
await this.renderCurrentFrame(clamped);
|
|
128
|
-
this.eventBus.emit(MeframeEvent.PlaybackSeek, { timeUs: this.
|
|
129
|
-
} catch (error) {
|
|
130
|
-
console.error("[PlaybackController] Seek error:", error);
|
|
131
|
-
this.eventBus.emit(MeframeEvent.PlaybackError, error);
|
|
132
|
-
} finally {
|
|
120
|
+
this.eventBus.emit(MeframeEvent.PlaybackSeek, { timeUs: this.currentTimeUs });
|
|
133
121
|
if (wasPlaying) {
|
|
134
|
-
this.
|
|
135
|
-
this.startTime = performance.now() - this._currentTimeUs / 1e3 / this.playbackRate;
|
|
136
|
-
await this.ensureAudioContext();
|
|
137
|
-
this.startAudioPlayback();
|
|
138
|
-
if (!this.rafId) {
|
|
139
|
-
this.playbackLoop();
|
|
140
|
-
}
|
|
122
|
+
await this.startPlayback();
|
|
141
123
|
} else {
|
|
142
|
-
this.
|
|
124
|
+
this.state = previousState === "idle" ? "idle" : "paused";
|
|
143
125
|
}
|
|
126
|
+
} catch (error) {
|
|
127
|
+
console.error("[PlaybackController] Seek error:", error);
|
|
128
|
+
this.eventBus.emit(MeframeEvent.PlaybackError, error);
|
|
129
|
+
this.state = previousState === "idle" ? "idle" : "paused";
|
|
144
130
|
}
|
|
145
131
|
}
|
|
146
132
|
// Playback properties
|
|
@@ -163,21 +149,13 @@ class PlaybackController {
|
|
|
163
149
|
setMute(muted) {
|
|
164
150
|
if (muted) {
|
|
165
151
|
this.stopAudioPlayback();
|
|
166
|
-
} else if (this.
|
|
152
|
+
} else if (this.state === "playing") {
|
|
167
153
|
this.startAudioPlayback();
|
|
168
154
|
}
|
|
169
155
|
}
|
|
170
156
|
setLoop(loop) {
|
|
171
157
|
this.loop = loop;
|
|
172
158
|
}
|
|
173
|
-
// State properties
|
|
174
|
-
get currentTime() {
|
|
175
|
-
if (this._state === "playing") {
|
|
176
|
-
const elapsed = (performance.now() - this.startTime) * this.playbackRate;
|
|
177
|
-
this._currentTimeUs = Math.min(elapsed * 1e3, this.duration);
|
|
178
|
-
}
|
|
179
|
-
return this._currentTimeUs;
|
|
180
|
-
}
|
|
181
159
|
get duration() {
|
|
182
160
|
const modelDuration = this.orchestrator.compositionModel?.durationUs;
|
|
183
161
|
if (modelDuration !== void 0) {
|
|
@@ -185,11 +163,8 @@ class PlaybackController {
|
|
|
185
163
|
}
|
|
186
164
|
return 0;
|
|
187
165
|
}
|
|
188
|
-
get
|
|
189
|
-
return this.
|
|
190
|
-
}
|
|
191
|
-
get playing() {
|
|
192
|
-
return this._state === "playing";
|
|
166
|
+
get isPlaying() {
|
|
167
|
+
return this.state === "playing";
|
|
193
168
|
}
|
|
194
169
|
setAudioSession(session) {
|
|
195
170
|
this.audioSession = session;
|
|
@@ -198,6 +173,12 @@ class PlaybackController {
|
|
|
198
173
|
resume() {
|
|
199
174
|
this.play();
|
|
200
175
|
}
|
|
176
|
+
on(event, handler) {
|
|
177
|
+
this.eventBus.on(event, handler);
|
|
178
|
+
}
|
|
179
|
+
off(event, handler) {
|
|
180
|
+
this.eventBus.off(event, handler);
|
|
181
|
+
}
|
|
201
182
|
setupListeners() {
|
|
202
183
|
this.orchestrator.on(MeframeEvent.CacheCover, (event) => {
|
|
203
184
|
this.renderCurrentFrame(event.timeUs);
|
|
@@ -205,7 +186,7 @@ class PlaybackController {
|
|
|
205
186
|
}
|
|
206
187
|
// Private methods
|
|
207
188
|
playbackLoop() {
|
|
208
|
-
if (this.
|
|
189
|
+
if (this.state !== "playing") {
|
|
209
190
|
if (this.rafId !== null) {
|
|
210
191
|
cancelAnimationFrame(this.rafId);
|
|
211
192
|
this.rafId = null;
|
|
@@ -213,12 +194,12 @@ class PlaybackController {
|
|
|
213
194
|
return;
|
|
214
195
|
}
|
|
215
196
|
this.rafId = requestAnimationFrame(async () => {
|
|
216
|
-
if (this.
|
|
197
|
+
if (this.state !== "playing") {
|
|
217
198
|
return;
|
|
218
199
|
}
|
|
219
200
|
this.updateTime();
|
|
220
201
|
await this.renderCurrentFrame();
|
|
221
|
-
if (this.
|
|
202
|
+
if (this.state !== "playing") {
|
|
222
203
|
return;
|
|
223
204
|
}
|
|
224
205
|
const now = performance.now();
|
|
@@ -236,26 +217,26 @@ class PlaybackController {
|
|
|
236
217
|
const elapsed = (performance.now() - this.startTime) * this.playbackRate;
|
|
237
218
|
const rawTimeUs = elapsed * 1e3;
|
|
238
219
|
const fps = this.orchestrator.compositionModel?.fps;
|
|
239
|
-
this.
|
|
240
|
-
if (this.
|
|
220
|
+
this.currentTimeUs = quantizeTimestampToFrame(rawTimeUs, 0, fps, "nearest");
|
|
221
|
+
if (this.currentTimeUs >= this.duration) {
|
|
241
222
|
if (this.loop) {
|
|
242
|
-
this.
|
|
223
|
+
this.currentTimeUs = 0;
|
|
243
224
|
this.startTime = performance.now();
|
|
244
225
|
} else {
|
|
245
|
-
this.
|
|
226
|
+
this.currentTimeUs = this.duration;
|
|
246
227
|
this.pause();
|
|
247
|
-
this.
|
|
248
|
-
this.eventBus.emit(MeframeEvent.PlaybackEnded, { timeUs: this.
|
|
228
|
+
this.state = "ended";
|
|
229
|
+
this.eventBus.emit(MeframeEvent.PlaybackEnded, { timeUs: this.currentTimeUs });
|
|
249
230
|
}
|
|
250
231
|
}
|
|
251
|
-
this.eventBus.emit(MeframeEvent.PlaybackTimeUpdate, { timeUs: this.
|
|
232
|
+
this.eventBus.emit(MeframeEvent.PlaybackTimeUpdate, { timeUs: this.currentTimeUs });
|
|
252
233
|
}
|
|
253
234
|
async renderCurrentFrame(timeUs) {
|
|
254
235
|
try {
|
|
255
|
-
const targetTime = timeUs ?? this.
|
|
236
|
+
const targetTime = timeUs ?? this.currentTimeUs;
|
|
256
237
|
const rcFrame = await this.orchestrator.renderFrame(targetTime);
|
|
257
238
|
if (!rcFrame) {
|
|
258
|
-
if (this.
|
|
239
|
+
if (this.state === "playing") {
|
|
259
240
|
await this.handlePlaybackBuffering(targetTime);
|
|
260
241
|
}
|
|
261
242
|
return;
|
|
@@ -274,10 +255,10 @@ class PlaybackController {
|
|
|
274
255
|
if (this.isBuffering) {
|
|
275
256
|
return;
|
|
276
257
|
}
|
|
277
|
-
const wasPlaying = this.
|
|
258
|
+
const wasPlaying = this.state === "playing";
|
|
278
259
|
if (!wasPlaying) return;
|
|
279
260
|
this.isBuffering = true;
|
|
280
|
-
this.
|
|
261
|
+
this.state = "buffering";
|
|
281
262
|
this.eventBus.emit(MeframeEvent.PlaybackBuffering);
|
|
282
263
|
try {
|
|
283
264
|
await this.orchestrator.ensureClipCache(timeUs);
|
|
@@ -289,7 +270,7 @@ class PlaybackController {
|
|
|
289
270
|
if (!ready) {
|
|
290
271
|
console.warn("[PlaybackController] Buffering timeout during playback");
|
|
291
272
|
}
|
|
292
|
-
this.
|
|
273
|
+
this.state = "playing";
|
|
293
274
|
this.startTime = performance.now() - timeUs / 1e3 / this.playbackRate;
|
|
294
275
|
this.eventBus.emit(MeframeEvent.PlaybackPlay);
|
|
295
276
|
if (!this.rafId) {
|
|
@@ -297,7 +278,7 @@ class PlaybackController {
|
|
|
297
278
|
}
|
|
298
279
|
} catch (error) {
|
|
299
280
|
console.error("[PlaybackController] Buffering error:", error);
|
|
300
|
-
this.
|
|
281
|
+
this.state = "paused";
|
|
301
282
|
this.eventBus.emit(MeframeEvent.PlaybackError, error);
|
|
302
283
|
} finally {
|
|
303
284
|
this.isBuffering = false;
|
|
@@ -324,22 +305,21 @@ class PlaybackController {
|
|
|
324
305
|
return;
|
|
325
306
|
}
|
|
326
307
|
this.stopAudioPlayback();
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
if (!audioBuffer || !this.audioContext || !this.audioGainNode) {
|
|
308
|
+
this.audioSession.prepareAudioForPlayback(this.currentTimeUs).then((audioInfo) => {
|
|
309
|
+
if (!audioInfo || !this.audioContext || !this.audioGainNode) {
|
|
330
310
|
return;
|
|
331
311
|
}
|
|
332
312
|
const source = this.audioContext.createBufferSource();
|
|
333
|
-
source.buffer =
|
|
313
|
+
source.buffer = audioInfo.buffer;
|
|
334
314
|
source.playbackRate.value = this.playbackRate;
|
|
335
315
|
source.onended = () => {
|
|
336
316
|
this.audioSource = null;
|
|
337
|
-
if (this.
|
|
317
|
+
if (this.state === "playing") {
|
|
338
318
|
this.startAudioPlayback();
|
|
339
319
|
}
|
|
340
320
|
};
|
|
341
321
|
source.connect(this.audioGainNode);
|
|
342
|
-
source.start();
|
|
322
|
+
source.start(0, audioInfo.offsetSeconds, audioInfo.durationSeconds);
|
|
343
323
|
this.audioSource = source;
|
|
344
324
|
}).catch((error) => {
|
|
345
325
|
console.error("[PlaybackController] Audio playback error:", error);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PlaybackController.js","sources":["../../src/controllers/PlaybackController.ts"],"sourcesContent":["import type { IPlaybackController, PlaybackState, PlaybackOptions, IEventBus } from './types';\nimport type { TimeUs } from '../model/types';\nimport { MeframeEvent } from '../event/events';\nimport { quantizeTimestampToFrame } from '../utils/time-utils';\nimport type { GlobalAudioSession } from '../stages/compose/GlobalAudioSession';\nimport type { Orchestrator } from '../orchestrator';\n\n/**\n * Playback controller for preview\n * Internal implementation - not exposed directly to external consumers\n */\nexport class PlaybackController implements IPlaybackController {\n private orchestrator: Orchestrator;\n private eventBus: IEventBus;\n private canvas: HTMLCanvasElement | OffscreenCanvas;\n private ctx: CanvasRenderingContext2D | OffscreenCanvasRenderingContext2D;\n\n // Playback state\n private _currentTimeUs: TimeUs = 0;\n private _state: PlaybackState = 'idle';\n private playbackRate = 1.0;\n private volume = 1.0;\n private loop = false;\n\n // Animation loop\n private rafId: number | null = null;\n private startTime = 0;\n\n // Frame tracking\n private frameCount = 0;\n private lastFrameTime = 0;\n private fps = 0;\n private audioContext: AudioContext | null = null;\n private audioSource: AudioBufferSourceNode | null = null;\n private audioGainNode: GainNode | null = null;\n private audioSession: GlobalAudioSession | null = null;\n\n // Buffering state\n private isBuffering = false;\n\n constructor(orchestrator: Orchestrator, eventBus: IEventBus, options: PlaybackOptions) {\n this.orchestrator = orchestrator;\n this.eventBus = eventBus;\n this.canvas = options.canvas;\n\n // Get 2D context with high quality settings\n const ctx = this.canvas.getContext('2d', {\n alpha: false,\n desynchronized: true,\n colorSpace: 'srgb',\n } as any);\n if (!ctx) {\n throw new Error('Failed to get 2D context from canvas');\n }\n this.ctx = ctx as CanvasRenderingContext2D | OffscreenCanvasRenderingContext2D;\n\n // Configure high quality rendering\n this.ctx.imageSmoothingEnabled = true;\n this.ctx.imageSmoothingQuality = 'high';\n\n // Set initial time if provided\n if (options.startUs !== undefined) {\n this._currentTimeUs = options.startUs;\n }\n\n if (options.rate !== undefined) {\n this.playbackRate = options.rate;\n }\n\n if (options.loop !== undefined) {\n this.loop = options.loop;\n }\n\n if (options.autoStart) {\n this.play();\n }\n\n this.setupListeners();\n }\n\n // Playback control\n play(): void {\n if (this._state === 'playing') return;\n\n void this.startPlayback();\n }\n\n private async startPlayback(): Promise<void> {\n const wasIdle = this._state === 'idle';\n\n this._state = 'buffering';\n this.eventBus.emit(MeframeEvent.PlaybackBuffering);\n\n try {\n await this.orchestrator.ensureClipCache(this._currentTimeUs);\n\n const ready = await this.orchestrator.waitForClipReady(this._currentTimeUs, {\n minFrameCount: 30,\n timeoutMs: 3_000,\n });\n\n if (!ready) {\n console.warn('[PlaybackController] Buffering timeout, starting anyway');\n }\n\n this._state = 'playing';\n this.startTime = performance.now() - this._currentTimeUs / 1000 / this.playbackRate;\n await this.ensureAudioContext();\n this.startAudioPlayback();\n this.playbackLoop();\n\n this.eventBus.emit(MeframeEvent.PlaybackPlay);\n } catch (error) {\n console.error('[PlaybackController] Failed to start playback:', error);\n this._state = wasIdle ? 'idle' : 'paused';\n this.eventBus.emit(MeframeEvent.PlaybackError, error as Error);\n }\n }\n\n pause(): void {\n if (this._state !== 'playing') return;\n\n this._state = 'paused';\n\n if (this.rafId !== null) {\n cancelAnimationFrame(this.rafId);\n this.rafId = null;\n }\n\n this.stopAudioPlayback();\n\n this.eventBus.emit(MeframeEvent.PlaybackPause);\n }\n\n stop(): void {\n this.pause();\n this._currentTimeUs = 0;\n this._state = 'idle';\n this.frameCount = 0; // Reset frame counter\n this.lastFrameTime = 0; // Reset frame timing\n this.fps = 0; // Reset FPS\n\n // Clear canvas\n this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);\n\n this.audioSession?.reset();\n this.stopAudioPlayback();\n\n this.eventBus.emit(MeframeEvent.PlaybackStop);\n }\n\n async seek(timeUs: TimeUs): Promise<void> {\n const wasPlaying = this._state === 'playing';\n const previousState = this._state;\n\n if (wasPlaying) {\n this.pause();\n }\n\n const clamped = this.clampTime(timeUs);\n this._currentTimeUs = clamped;\n\n this._state = 'seeking';\n this.stopAudioPlayback();\n\n try {\n await this.orchestrator.ensureClipCache(clamped);\n\n const ready = await this.orchestrator.waitForClipReady(clamped, {\n minFrameCount: 10,\n timeoutMs: 3_000,\n });\n\n if (!ready) {\n console.warn('[PlaybackController] Seek buffering timeout');\n }\n\n await this.renderCurrentFrame(clamped);\n this.eventBus.emit(MeframeEvent.PlaybackSeek, { timeUs: this._currentTimeUs });\n } catch (error) {\n console.error('[PlaybackController] Seek error:', error);\n this.eventBus.emit(MeframeEvent.PlaybackError, error as Error);\n } finally {\n if (wasPlaying) {\n this._state = 'playing';\n this.startTime = performance.now() - this._currentTimeUs / 1000 / this.playbackRate;\n await this.ensureAudioContext();\n this.startAudioPlayback();\n if (!this.rafId) {\n this.playbackLoop();\n }\n } else {\n this._state = previousState === 'idle' ? 'idle' : 'paused';\n }\n }\n }\n\n // Playback properties\n setRate(rate: number): void {\n // Adjust start time to maintain current position\n const elapsed = performance.now() - this.startTime;\n this.playbackRate = rate;\n this.startTime = performance.now() - elapsed / rate;\n\n this.eventBus.emit(MeframeEvent.PlaybackRateChange, { rate });\n\n if (this.audioSource) {\n this.audioSource.playbackRate.value = this.playbackRate;\n }\n }\n\n setVolume(volume: number): void {\n this.volume = Math.max(0, Math.min(1, volume));\n this.eventBus.emit(MeframeEvent.PlaybackVolumeChange, { volume: this.volume });\n\n if (this.audioGainNode) {\n this.audioGainNode.gain.value = this.volume;\n }\n }\n\n setMute(muted: boolean): void {\n if (muted) {\n this.stopAudioPlayback();\n } else if (this._state === 'playing') {\n this.startAudioPlayback();\n }\n }\n\n setLoop(loop: boolean): void {\n this.loop = loop;\n }\n\n // State properties\n get currentTime(): TimeUs {\n if (this._state === 'playing') {\n const elapsed = (performance.now() - this.startTime) * this.playbackRate;\n this._currentTimeUs = Math.min(elapsed * 1000, this.duration);\n }\n return this._currentTimeUs;\n }\n\n get duration(): TimeUs {\n const modelDuration = this.orchestrator.compositionModel?.durationUs;\n if (modelDuration !== undefined) {\n return modelDuration;\n }\n\n return 0;\n }\n\n get state(): PlaybackState {\n return this._state;\n }\n\n get playing(): boolean {\n return this._state === 'playing';\n }\n\n setAudioSession(session: GlobalAudioSession): void {\n this.audioSession = session;\n }\n\n // Resume is just an alias for play\n resume(): void {\n this.play();\n }\n\n private setupListeners(): void {\n this.orchestrator.on(MeframeEvent.CacheCover, (event) => {\n this.renderCurrentFrame(event.timeUs);\n });\n }\n\n // Private methods\n private playbackLoop(): void {\n // Only continue loop if actively playing (not buffering/paused/etc)\n if (this._state !== 'playing') {\n if (this.rafId !== null) {\n cancelAnimationFrame(this.rafId);\n this.rafId = null;\n }\n return;\n }\n\n this.rafId = requestAnimationFrame(async () => {\n // Check state again after async boundary\n if (this._state !== 'playing') {\n return;\n }\n\n this.updateTime();\n\n await this.renderCurrentFrame();\n\n // Check if still playing after render (might have entered buffering)\n if (this._state !== 'playing') {\n return;\n }\n\n // Calculate FPS based on actual frame timing\n const now = performance.now();\n if (this.lastFrameTime > 0) {\n const deltaTime = now - this.lastFrameTime;\n const instantFps = 1000 / deltaTime;\n this.fps = this.fps > 0 ? this.fps * 0.9 + instantFps * 0.1 : instantFps;\n }\n this.lastFrameTime = now;\n\n this.frameCount++;\n\n this.playbackLoop();\n });\n }\n\n private updateTime(): void {\n const elapsed = (performance.now() - this.startTime) * this.playbackRate;\n const rawTimeUs = elapsed * 1000;\n const fps = this.orchestrator.compositionModel?.fps;\n this._currentTimeUs = quantizeTimestampToFrame(rawTimeUs, 0, fps, 'nearest');\n\n // Check if reached end\n if (this._currentTimeUs >= this.duration) {\n if (this.loop) {\n this._currentTimeUs = 0;\n this.startTime = performance.now();\n } else {\n this._currentTimeUs = this.duration;\n this.pause();\n this._state = 'ended';\n this.eventBus.emit(MeframeEvent.PlaybackEnded, { timeUs: this._currentTimeUs });\n }\n }\n\n // Emit time update\n this.eventBus.emit(MeframeEvent.PlaybackTimeUpdate, { timeUs: this._currentTimeUs });\n }\n\n private async renderCurrentFrame(timeUs?: TimeUs): Promise<void> {\n try {\n const targetTime = timeUs ?? this._currentTimeUs;\n const rcFrame = await this.orchestrator.renderFrame(targetTime);\n\n if (!rcFrame) {\n // Cache miss during playback - trigger buffering\n if (this._state === 'playing') {\n await this.handlePlaybackBuffering(targetTime);\n }\n return;\n }\n\n await rcFrame.use((frame) => {\n // Ensure high quality rendering for every frame\n this.ctx.imageSmoothingEnabled = true;\n this.ctx.imageSmoothingQuality = 'high';\n this.ctx.drawImage(frame, 0, 0, this.canvas.width, this.canvas.height);\n });\n } catch (error) {\n console.error('Render error:', error);\n this.eventBus.emit(MeframeEvent.PlaybackError, error as Error);\n }\n }\n\n private async handlePlaybackBuffering(timeUs: TimeUs): Promise<void> {\n // Prevent duplicate buffering requests\n if (this.isBuffering) {\n return;\n }\n\n // Pause the playback loop\n const wasPlaying = this._state === 'playing';\n if (!wasPlaying) return;\n\n this.isBuffering = true;\n this._state = 'buffering';\n this.eventBus.emit(MeframeEvent.PlaybackBuffering);\n\n try {\n // Ensure clip cache for current time\n await this.orchestrator.ensureClipCache(timeUs);\n\n // Wait for minimum frames (smaller buffer for clip transitions)\n const ready = await this.orchestrator.waitForClipReady(timeUs, {\n minFrameCount: 15, // 0.5s @30fps - faster resume\n timeoutMs: 2_000,\n });\n\n if (!ready) {\n console.warn('[PlaybackController] Buffering timeout during playback');\n }\n\n // Resume playback\n this._state = 'playing';\n this.startTime = performance.now() - timeUs / 1000 / this.playbackRate;\n this.eventBus.emit(MeframeEvent.PlaybackPlay);\n\n // Restart playback loop\n if (!this.rafId) {\n this.playbackLoop();\n }\n } catch (error) {\n console.error('[PlaybackController] Buffering error:', error);\n this._state = 'paused';\n this.eventBus.emit(MeframeEvent.PlaybackError, error as Error);\n } finally {\n this.isBuffering = false;\n }\n }\n\n private clampTime(timeUs: TimeUs): TimeUs {\n return Math.max(0, Math.min(timeUs, this.duration));\n }\n\n // Cleanup\n dispose(): void {\n this.stop();\n }\n\n private async ensureAudioContext(): Promise<void> {\n if (this.audioContext) {\n return;\n }\n\n this.audioContext = new AudioContext();\n this.audioGainNode = this.audioContext.createGain();\n this.audioGainNode.gain.value = this.volume;\n this.audioGainNode.connect(this.audioContext.destination);\n }\n\n private startAudioPlayback(): void {\n if (!this.audioContext || !this.audioSession || !this.audioGainNode) {\n return;\n }\n\n this.stopAudioPlayback();\n\n const startUs = this._currentTimeUs;\n\n this.audioSession\n .ensureMixedPCM(startUs)\n .then((audioBuffer) => {\n if (!audioBuffer || !this.audioContext || !this.audioGainNode) {\n return;\n }\n\n const source = this.audioContext.createBufferSource();\n source.buffer = audioBuffer;\n source.playbackRate.value = this.playbackRate;\n source.onended = () => {\n this.audioSource = null;\n if (this._state === 'playing') {\n this.startAudioPlayback();\n }\n };\n\n source.connect(this.audioGainNode);\n source.start();\n this.audioSource = source;\n })\n .catch((error) => {\n console.error('[PlaybackController] Audio playback error:', error);\n });\n }\n\n private stopAudioPlayback(): void {\n if (this.audioSource) {\n try {\n this.audioSource.stop();\n } catch (error) {\n console.warn('[PlaybackController] stop audio failed', error);\n }\n this.audioSource.disconnect();\n this.audioSource = null;\n }\n }\n}\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"PlaybackController.js","sources":["../../src/controllers/PlaybackController.ts"],"sourcesContent":["import type {\n IPlaybackController,\n PlaybackState,\n PlaybackOptions,\n IEventBus,\n PreviewHandle,\n TimeUs,\n} from './types';\nimport { MeframeEvent } from '../event/events';\nimport { quantizeTimestampToFrame } from '../utils/time-utils';\nimport type { GlobalAudioSession } from '../stages/compose/GlobalAudioSession';\nimport type { Orchestrator } from '../orchestrator';\n\n/**\n * Playback controller for preview\n * Internal implementation - not exposed directly to external consumers\n */\nexport class PlaybackController implements IPlaybackController, PreviewHandle {\n private orchestrator: Orchestrator;\n private eventBus: IEventBus;\n private canvas: HTMLCanvasElement | OffscreenCanvas;\n private ctx: CanvasRenderingContext2D | OffscreenCanvasRenderingContext2D;\n\n // Playback state\n currentTimeUs: TimeUs = 0;\n private state: PlaybackState = 'idle';\n private playbackRate = 1.0;\n private volume = 1.0;\n private loop = false;\n\n // Animation loop\n private rafId: number | null = null;\n private startTime = 0;\n\n // Frame tracking\n private frameCount = 0;\n private lastFrameTime = 0;\n private fps = 0;\n private audioContext: AudioContext | null = null;\n private audioSource: AudioBufferSourceNode | null = null;\n private audioGainNode: GainNode | null = null;\n private audioSession: GlobalAudioSession | null = null;\n\n // Buffering state\n private isBuffering = false;\n\n constructor(orchestrator: Orchestrator, eventBus: IEventBus, options: PlaybackOptions) {\n this.orchestrator = orchestrator;\n this.eventBus = eventBus;\n this.canvas = options.canvas;\n\n // Get 2D context with high quality settings\n const ctx = this.canvas.getContext('2d', {\n alpha: false,\n desynchronized: true,\n colorSpace: 'srgb',\n } as any);\n if (!ctx) {\n throw new Error('Failed to get 2D context from canvas');\n }\n this.ctx = ctx as CanvasRenderingContext2D | OffscreenCanvasRenderingContext2D;\n\n // Configure high quality rendering\n this.ctx.imageSmoothingEnabled = true;\n this.ctx.imageSmoothingQuality = 'high';\n\n // Set initial time if provided\n if (options.startUs !== undefined) {\n this.currentTimeUs = options.startUs;\n }\n\n if (options.rate !== undefined) {\n this.playbackRate = options.rate;\n }\n\n if (options.loop !== undefined) {\n this.loop = options.loop;\n }\n\n if (options.autoStart) {\n this.play();\n }\n\n this.setupListeners();\n }\n\n // Playback control\n play(): void {\n if (this.state === 'playing') return;\n\n void this.startPlayback();\n }\n\n private async startPlayback(): Promise<void> {\n const wasIdle = this.state === 'idle';\n\n this.state = 'buffering';\n this.eventBus.emit(MeframeEvent.PlaybackBuffering);\n\n try {\n await this.orchestrator.ensureClipCache(this.currentTimeUs);\n\n const ready = await this.orchestrator.waitForClipReady(this.currentTimeUs, {\n minFrameCount: 30,\n timeoutMs: 3_000,\n });\n\n if (!ready) {\n console.warn('[PlaybackController] Buffering timeout, starting anyway');\n }\n\n this.state = 'playing';\n this.startTime = performance.now() - this.currentTimeUs / 1000 / this.playbackRate;\n await this.ensureAudioContext();\n this.startAudioPlayback();\n this.playbackLoop();\n\n this.eventBus.emit(MeframeEvent.PlaybackPlay);\n } catch (error) {\n console.error('[PlaybackController] Failed to start playback:', error);\n this.state = wasIdle ? 'idle' : 'paused';\n this.eventBus.emit(MeframeEvent.PlaybackError, error as Error);\n }\n }\n\n pause(): void {\n if (this.state !== 'playing') return;\n\n this.state = 'paused';\n\n if (this.rafId !== null) {\n cancelAnimationFrame(this.rafId);\n this.rafId = null;\n }\n\n this.stopAudioPlayback();\n\n this.eventBus.emit(MeframeEvent.PlaybackPause);\n }\n\n stop(): void {\n this.pause();\n this.currentTimeUs = 0;\n this.state = 'idle';\n this.frameCount = 0; // Reset frame counter\n this.lastFrameTime = 0; // Reset frame timing\n this.fps = 0; // Reset FPS\n\n // Clear canvas\n this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);\n\n this.audioSession?.reset();\n this.stopAudioPlayback();\n\n this.eventBus.emit(MeframeEvent.PlaybackStop);\n }\n\n async seek(timeUs: TimeUs): Promise<void> {\n const wasPlaying = this.state === 'playing';\n const previousState = this.state;\n\n if (wasPlaying) {\n this.pause();\n }\n\n const clamped = this.clampTime(timeUs);\n this.currentTimeUs = clamped;\n\n this.state = 'seeking';\n this.stopAudioPlayback();\n\n try {\n await this.renderCurrentFrame(clamped);\n this.eventBus.emit(MeframeEvent.PlaybackSeek, { timeUs: this.currentTimeUs });\n\n if (wasPlaying) {\n await this.startPlayback();\n } else {\n this.state = previousState === 'idle' ? 'idle' : 'paused';\n }\n } catch (error) {\n console.error('[PlaybackController] Seek error:', error);\n this.eventBus.emit(MeframeEvent.PlaybackError, error as Error);\n this.state = previousState === 'idle' ? 'idle' : 'paused';\n }\n }\n\n // Playback properties\n setRate(rate: number): void {\n // Adjust start time to maintain current position\n const elapsed = performance.now() - this.startTime;\n this.playbackRate = rate;\n this.startTime = performance.now() - elapsed / rate;\n\n this.eventBus.emit(MeframeEvent.PlaybackRateChange, { rate });\n\n if (this.audioSource) {\n this.audioSource.playbackRate.value = this.playbackRate;\n }\n }\n\n setVolume(volume: number): void {\n this.volume = Math.max(0, Math.min(1, volume));\n this.eventBus.emit(MeframeEvent.PlaybackVolumeChange, { volume: this.volume });\n\n if (this.audioGainNode) {\n this.audioGainNode.gain.value = this.volume;\n }\n }\n\n setMute(muted: boolean): void {\n if (muted) {\n this.stopAudioPlayback();\n } else if (this.state === 'playing') {\n this.startAudioPlayback();\n }\n }\n\n setLoop(loop: boolean): void {\n this.loop = loop;\n }\n\n get duration(): TimeUs {\n const modelDuration = this.orchestrator.compositionModel?.durationUs;\n if (modelDuration !== undefined) {\n return modelDuration;\n }\n\n return 0;\n }\n\n get isPlaying(): boolean {\n return this.state === 'playing';\n }\n\n setAudioSession(session: GlobalAudioSession): void {\n this.audioSession = session;\n }\n\n // Resume is just an alias for play\n resume(): void {\n this.play();\n }\n\n on(event: string, handler: (payload: any) => void): void {\n this.eventBus.on(event as MeframeEvent, handler);\n }\n\n off(event: string, handler: (payload: any) => void): void {\n this.eventBus.off(event as MeframeEvent, handler);\n }\n\n private setupListeners(): void {\n this.orchestrator.on(MeframeEvent.CacheCover, (event) => {\n this.renderCurrentFrame(event.timeUs);\n });\n }\n\n // Private methods\n private playbackLoop(): void {\n // Only continue loop if actively playing (not buffering/paused/etc)\n if (this.state !== 'playing') {\n if (this.rafId !== null) {\n cancelAnimationFrame(this.rafId);\n this.rafId = null;\n }\n return;\n }\n\n this.rafId = requestAnimationFrame(async () => {\n // Check state again after async boundary\n if (this.state !== 'playing') {\n return;\n }\n\n this.updateTime();\n\n await this.renderCurrentFrame();\n\n // Check if still playing after render (might have entered buffering)\n if (this.state !== 'playing') {\n return;\n }\n\n // Calculate FPS based on actual frame timing\n const now = performance.now();\n if (this.lastFrameTime > 0) {\n const deltaTime = now - this.lastFrameTime;\n const instantFps = 1000 / deltaTime;\n this.fps = this.fps > 0 ? this.fps * 0.9 + instantFps * 0.1 : instantFps;\n }\n this.lastFrameTime = now;\n\n this.frameCount++;\n\n this.playbackLoop();\n });\n }\n\n private updateTime(): void {\n const elapsed = (performance.now() - this.startTime) * this.playbackRate;\n const rawTimeUs = elapsed * 1000;\n const fps = this.orchestrator.compositionModel?.fps;\n this.currentTimeUs = quantizeTimestampToFrame(rawTimeUs, 0, fps, 'nearest');\n\n // Check if reached end\n if (this.currentTimeUs >= this.duration) {\n if (this.loop) {\n this.currentTimeUs = 0;\n this.startTime = performance.now();\n } else {\n this.currentTimeUs = this.duration;\n this.pause();\n this.state = 'ended';\n this.eventBus.emit(MeframeEvent.PlaybackEnded, { timeUs: this.currentTimeUs });\n }\n }\n\n // Emit time update\n this.eventBus.emit(MeframeEvent.PlaybackTimeUpdate, { timeUs: this.currentTimeUs });\n }\n\n private async renderCurrentFrame(timeUs?: TimeUs): Promise<void> {\n try {\n const targetTime = timeUs ?? this.currentTimeUs;\n const rcFrame = await this.orchestrator.renderFrame(targetTime);\n if (!rcFrame) {\n // Cache miss during playback - trigger buffering\n if (this.state === 'playing') {\n await this.handlePlaybackBuffering(targetTime);\n }\n return;\n }\n\n await rcFrame.use((frame) => {\n // Ensure high quality rendering for every frame\n this.ctx.imageSmoothingEnabled = true;\n this.ctx.imageSmoothingQuality = 'high';\n this.ctx.drawImage(frame, 0, 0, this.canvas.width, this.canvas.height);\n });\n } catch (error) {\n console.error('Render error:', error);\n this.eventBus.emit(MeframeEvent.PlaybackError, error as Error);\n }\n }\n\n private async handlePlaybackBuffering(timeUs: TimeUs): Promise<void> {\n // Prevent duplicate buffering requests\n if (this.isBuffering) {\n return;\n }\n\n // Pause the playback loop\n const wasPlaying = this.state === 'playing';\n if (!wasPlaying) return;\n\n this.isBuffering = true;\n this.state = 'buffering';\n this.eventBus.emit(MeframeEvent.PlaybackBuffering);\n\n try {\n // Ensure clip cache for current time\n await this.orchestrator.ensureClipCache(timeUs);\n\n // Wait for minimum frames (smaller buffer for clip transitions)\n const ready = await this.orchestrator.waitForClipReady(timeUs, {\n minFrameCount: 15, // 0.5s @30fps - faster resume\n timeoutMs: 2_000,\n });\n\n if (!ready) {\n console.warn('[PlaybackController] Buffering timeout during playback');\n }\n\n // Resume playback\n this.state = 'playing';\n this.startTime = performance.now() - timeUs / 1000 / this.playbackRate;\n this.eventBus.emit(MeframeEvent.PlaybackPlay);\n\n // Restart playback loop\n if (!this.rafId) {\n this.playbackLoop();\n }\n } catch (error) {\n console.error('[PlaybackController] Buffering error:', error);\n this.state = 'paused';\n this.eventBus.emit(MeframeEvent.PlaybackError, error as Error);\n } finally {\n this.isBuffering = false;\n }\n }\n\n private clampTime(timeUs: TimeUs): TimeUs {\n return Math.max(0, Math.min(timeUs, this.duration));\n }\n\n // Cleanup\n dispose(): void {\n this.stop();\n }\n\n private async ensureAudioContext(): Promise<void> {\n if (this.audioContext) {\n return;\n }\n\n this.audioContext = new AudioContext();\n this.audioGainNode = this.audioContext.createGain();\n this.audioGainNode.gain.value = this.volume;\n this.audioGainNode.connect(this.audioContext.destination);\n }\n\n private startAudioPlayback(): void {\n if (!this.audioContext || !this.audioSession || !this.audioGainNode) {\n return;\n }\n\n this.stopAudioPlayback();\n\n this.audioSession\n .prepareAudioForPlayback(this.currentTimeUs)\n .then((audioInfo) => {\n if (!audioInfo || !this.audioContext || !this.audioGainNode) {\n return;\n }\n\n const source = this.audioContext.createBufferSource();\n source.buffer = audioInfo.buffer;\n source.playbackRate.value = this.playbackRate;\n source.onended = () => {\n this.audioSource = null;\n if (this.state === 'playing') {\n this.startAudioPlayback();\n }\n };\n\n source.connect(this.audioGainNode);\n source.start(0, audioInfo.offsetSeconds, audioInfo.durationSeconds);\n this.audioSource = source;\n })\n .catch((error) => {\n console.error('[PlaybackController] Audio playback error:', error);\n });\n }\n\n private stopAudioPlayback(): void {\n if (this.audioSource) {\n try {\n this.audioSource.stop();\n } catch (error) {\n console.warn('[PlaybackController] stop audio failed', error);\n }\n this.audioSource.disconnect();\n this.audioSource = null;\n }\n }\n}\n"],"names":[],"mappings":";;AAiBO,MAAM,mBAAiE;AAAA,EACpE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA;AAAA,EAGR,gBAAwB;AAAA,EAChB,QAAuB;AAAA,EACvB,eAAe;AAAA,EACf,SAAS;AAAA,EACT,OAAO;AAAA;AAAA,EAGP,QAAuB;AAAA,EACvB,YAAY;AAAA;AAAA,EAGZ,aAAa;AAAA,EACb,gBAAgB;AAAA,EAChB,MAAM;AAAA,EACN,eAAoC;AAAA,EACpC,cAA4C;AAAA,EAC5C,gBAAiC;AAAA,EACjC,eAA0C;AAAA;AAAA,EAG1C,cAAc;AAAA,EAEtB,YAAY,cAA4B,UAAqB,SAA0B;AACrF,SAAK,eAAe;AACpB,SAAK,WAAW;AAChB,SAAK,SAAS,QAAQ;AAGtB,UAAM,MAAM,KAAK,OAAO,WAAW,MAAM;AAAA,MACvC,OAAO;AAAA,MACP,gBAAgB;AAAA,MAChB,YAAY;AAAA,IAAA,CACN;AACR,QAAI,CAAC,KAAK;AACR,YAAM,IAAI,MAAM,sCAAsC;AAAA,IACxD;AACA,SAAK,MAAM;AAGX,SAAK,IAAI,wBAAwB;AACjC,SAAK,IAAI,wBAAwB;AAGjC,QAAI,QAAQ,YAAY,QAAW;AACjC,WAAK,gBAAgB,QAAQ;AAAA,IAC/B;AAEA,QAAI,QAAQ,SAAS,QAAW;AAC9B,WAAK,eAAe,QAAQ;AAAA,IAC9B;AAEA,QAAI,QAAQ,SAAS,QAAW;AAC9B,WAAK,OAAO,QAAQ;AAAA,IACtB;AAEA,QAAI,QAAQ,WAAW;AACrB,WAAK,KAAA;AAAA,IACP;AAEA,SAAK,eAAA;AAAA,EACP;AAAA;AAAA,EAGA,OAAa;AACX,QAAI,KAAK,UAAU,UAAW;AAE9B,SAAK,KAAK,cAAA;AAAA,EACZ;AAAA,EAEA,MAAc,gBAA+B;AAC3C,UAAM,UAAU,KAAK,UAAU;AAE/B,SAAK,QAAQ;AACb,SAAK,SAAS,KAAK,aAAa,iBAAiB;AAEjD,QAAI;AACF,YAAM,KAAK,aAAa,gBAAgB,KAAK,aAAa;AAE1D,YAAM,QAAQ,MAAM,KAAK,aAAa,iBAAiB,KAAK,eAAe;AAAA,QACzE,eAAe;AAAA,QACf,WAAW;AAAA,MAAA,CACZ;AAED,UAAI,CAAC,OAAO;AACV,gBAAQ,KAAK,yDAAyD;AAAA,MACxE;AAEA,WAAK,QAAQ;AACb,WAAK,YAAY,YAAY,IAAA,IAAQ,KAAK,gBAAgB,MAAO,KAAK;AACtE,YAAM,KAAK,mBAAA;AACX,WAAK,mBAAA;AACL,WAAK,aAAA;AAEL,WAAK,SAAS,KAAK,aAAa,YAAY;AAAA,IAC9C,SAAS,OAAO;AACd,cAAQ,MAAM,kDAAkD,KAAK;AACrE,WAAK,QAAQ,UAAU,SAAS;AAChC,WAAK,SAAS,KAAK,aAAa,eAAe,KAAc;AAAA,IAC/D;AAAA,EACF;AAAA,EAEA,QAAc;AACZ,QAAI,KAAK,UAAU,UAAW;AAE9B,SAAK,QAAQ;AAEb,QAAI,KAAK,UAAU,MAAM;AACvB,2BAAqB,KAAK,KAAK;AAC/B,WAAK,QAAQ;AAAA,IACf;AAEA,SAAK,kBAAA;AAEL,SAAK,SAAS,KAAK,aAAa,aAAa;AAAA,EAC/C;AAAA,EAEA,OAAa;AACX,SAAK,MAAA;AACL,SAAK,gBAAgB;AACrB,SAAK,QAAQ;AACb,SAAK,aAAa;AAClB,SAAK,gBAAgB;AACrB,SAAK,MAAM;AAGX,SAAK,IAAI,UAAU,GAAG,GAAG,KAAK,OAAO,OAAO,KAAK,OAAO,MAAM;AAE9D,SAAK,cAAc,MAAA;AACnB,SAAK,kBAAA;AAEL,SAAK,SAAS,KAAK,aAAa,YAAY;AAAA,EAC9C;AAAA,EAEA,MAAM,KAAK,QAA+B;AACxC,UAAM,aAAa,KAAK,UAAU;AAClC,UAAM,gBAAgB,KAAK;AAE3B,QAAI,YAAY;AACd,WAAK,MAAA;AAAA,IACP;AAEA,UAAM,UAAU,KAAK,UAAU,MAAM;AACrC,SAAK,gBAAgB;AAErB,SAAK,QAAQ;AACb,SAAK,kBAAA;AAEL,QAAI;AACF,YAAM,KAAK,mBAAmB,OAAO;AACrC,WAAK,SAAS,KAAK,aAAa,cAAc,EAAE,QAAQ,KAAK,eAAe;AAE5E,UAAI,YAAY;AACd,cAAM,KAAK,cAAA;AAAA,MACb,OAAO;AACL,aAAK,QAAQ,kBAAkB,SAAS,SAAS;AAAA,MACnD;AAAA,IACF,SAAS,OAAO;AACd,cAAQ,MAAM,oCAAoC,KAAK;AACvD,WAAK,SAAS,KAAK,aAAa,eAAe,KAAc;AAC7D,WAAK,QAAQ,kBAAkB,SAAS,SAAS;AAAA,IACnD;AAAA,EACF;AAAA;AAAA,EAGA,QAAQ,MAAoB;AAE1B,UAAM,UAAU,YAAY,IAAA,IAAQ,KAAK;AACzC,SAAK,eAAe;AACpB,SAAK,YAAY,YAAY,IAAA,IAAQ,UAAU;AAE/C,SAAK,SAAS,KAAK,aAAa,oBAAoB,EAAE,MAAM;AAE5D,QAAI,KAAK,aAAa;AACpB,WAAK,YAAY,aAAa,QAAQ,KAAK;AAAA,IAC7C;AAAA,EACF;AAAA,EAEA,UAAU,QAAsB;AAC9B,SAAK,SAAS,KAAK,IAAI,GAAG,KAAK,IAAI,GAAG,MAAM,CAAC;AAC7C,SAAK,SAAS,KAAK,aAAa,sBAAsB,EAAE,QAAQ,KAAK,QAAQ;AAE7E,QAAI,KAAK,eAAe;AACtB,WAAK,cAAc,KAAK,QAAQ,KAAK;AAAA,IACvC;AAAA,EACF;AAAA,EAEA,QAAQ,OAAsB;AAC5B,QAAI,OAAO;AACT,WAAK,kBAAA;AAAA,IACP,WAAW,KAAK,UAAU,WAAW;AACnC,WAAK,mBAAA;AAAA,IACP;AAAA,EACF;AAAA,EAEA,QAAQ,MAAqB;AAC3B,SAAK,OAAO;AAAA,EACd;AAAA,EAEA,IAAI,WAAmB;AACrB,UAAM,gBAAgB,KAAK,aAAa,kBAAkB;AAC1D,QAAI,kBAAkB,QAAW;AAC/B,aAAO;AAAA,IACT;AAEA,WAAO;AAAA,EACT;AAAA,EAEA,IAAI,YAAqB;AACvB,WAAO,KAAK,UAAU;AAAA,EACxB;AAAA,EAEA,gBAAgB,SAAmC;AACjD,SAAK,eAAe;AAAA,EACtB;AAAA;AAAA,EAGA,SAAe;AACb,SAAK,KAAA;AAAA,EACP;AAAA,EAEA,GAAG,OAAe,SAAuC;AACvD,SAAK,SAAS,GAAG,OAAuB,OAAO;AAAA,EACjD;AAAA,EAEA,IAAI,OAAe,SAAuC;AACxD,SAAK,SAAS,IAAI,OAAuB,OAAO;AAAA,EAClD;AAAA,EAEQ,iBAAuB;AAC7B,SAAK,aAAa,GAAG,aAAa,YAAY,CAAC,UAAU;AACvD,WAAK,mBAAmB,MAAM,MAAM;AAAA,IACtC,CAAC;AAAA,EACH;AAAA;AAAA,EAGQ,eAAqB;AAE3B,QAAI,KAAK,UAAU,WAAW;AAC5B,UAAI,KAAK,UAAU,MAAM;AACvB,6BAAqB,KAAK,KAAK;AAC/B,aAAK,QAAQ;AAAA,MACf;AACA;AAAA,IACF;AAEA,SAAK,QAAQ,sBAAsB,YAAY;AAE7C,UAAI,KAAK,UAAU,WAAW;AAC5B;AAAA,MACF;AAEA,WAAK,WAAA;AAEL,YAAM,KAAK,mBAAA;AAGX,UAAI,KAAK,UAAU,WAAW;AAC5B;AAAA,MACF;AAGA,YAAM,MAAM,YAAY,IAAA;AACxB,UAAI,KAAK,gBAAgB,GAAG;AAC1B,cAAM,YAAY,MAAM,KAAK;AAC7B,cAAM,aAAa,MAAO;AAC1B,aAAK,MAAM,KAAK,MAAM,IAAI,KAAK,MAAM,MAAM,aAAa,MAAM;AAAA,MAChE;AACA,WAAK,gBAAgB;AAErB,WAAK;AAEL,WAAK,aAAA;AAAA,IACP,CAAC;AAAA,EACH;AAAA,EAEQ,aAAmB;AACzB,UAAM,WAAW,YAAY,IAAA,IAAQ,KAAK,aAAa,KAAK;AAC5D,UAAM,YAAY,UAAU;AAC5B,UAAM,MAAM,KAAK,aAAa,kBAAkB;AAChD,SAAK,gBAAgB,yBAAyB,WAAW,GAAG,KAAK,SAAS;AAG1E,QAAI,KAAK,iBAAiB,KAAK,UAAU;AACvC,UAAI,KAAK,MAAM;AACb,aAAK,gBAAgB;AACrB,aAAK,YAAY,YAAY,IAAA;AAAA,MAC/B,OAAO;AACL,aAAK,gBAAgB,KAAK;AAC1B,aAAK,MAAA;AACL,aAAK,QAAQ;AACb,aAAK,SAAS,KAAK,aAAa,eAAe,EAAE,QAAQ,KAAK,eAAe;AAAA,MAC/E;AAAA,IACF;AAGA,SAAK,SAAS,KAAK,aAAa,oBAAoB,EAAE,QAAQ,KAAK,eAAe;AAAA,EACpF;AAAA,EAEA,MAAc,mBAAmB,QAAgC;AAC/D,QAAI;AACF,YAAM,aAAa,UAAU,KAAK;AAClC,YAAM,UAAU,MAAM,KAAK,aAAa,YAAY,UAAU;AAC9D,UAAI,CAAC,SAAS;AAEZ,YAAI,KAAK,UAAU,WAAW;AAC5B,gBAAM,KAAK,wBAAwB,UAAU;AAAA,QAC/C;AACA;AAAA,MACF;AAEA,YAAM,QAAQ,IAAI,CAAC,UAAU;AAE3B,aAAK,IAAI,wBAAwB;AACjC,aAAK,IAAI,wBAAwB;AACjC,aAAK,IAAI,UAAU,OAAO,GAAG,GAAG,KAAK,OAAO,OAAO,KAAK,OAAO,MAAM;AAAA,MACvE,CAAC;AAAA,IACH,SAAS,OAAO;AACd,cAAQ,MAAM,iBAAiB,KAAK;AACpC,WAAK,SAAS,KAAK,aAAa,eAAe,KAAc;AAAA,IAC/D;AAAA,EACF;AAAA,EAEA,MAAc,wBAAwB,QAA+B;AAEnE,QAAI,KAAK,aAAa;AACpB;AAAA,IACF;AAGA,UAAM,aAAa,KAAK,UAAU;AAClC,QAAI,CAAC,WAAY;AAEjB,SAAK,cAAc;AACnB,SAAK,QAAQ;AACb,SAAK,SAAS,KAAK,aAAa,iBAAiB;AAEjD,QAAI;AAEF,YAAM,KAAK,aAAa,gBAAgB,MAAM;AAG9C,YAAM,QAAQ,MAAM,KAAK,aAAa,iBAAiB,QAAQ;AAAA,QAC7D,eAAe;AAAA;AAAA,QACf,WAAW;AAAA,MAAA,CACZ;AAED,UAAI,CAAC,OAAO;AACV,gBAAQ,KAAK,wDAAwD;AAAA,MACvE;AAGA,WAAK,QAAQ;AACb,WAAK,YAAY,YAAY,IAAA,IAAQ,SAAS,MAAO,KAAK;AAC1D,WAAK,SAAS,KAAK,aAAa,YAAY;AAG5C,UAAI,CAAC,KAAK,OAAO;AACf,aAAK,aAAA;AAAA,MACP;AAAA,IACF,SAAS,OAAO;AACd,cAAQ,MAAM,yCAAyC,KAAK;AAC5D,WAAK,QAAQ;AACb,WAAK,SAAS,KAAK,aAAa,eAAe,KAAc;AAAA,IAC/D,UAAA;AACE,WAAK,cAAc;AAAA,IACrB;AAAA,EACF;AAAA,EAEQ,UAAU,QAAwB;AACxC,WAAO,KAAK,IAAI,GAAG,KAAK,IAAI,QAAQ,KAAK,QAAQ,CAAC;AAAA,EACpD;AAAA;AAAA,EAGA,UAAgB;AACd,SAAK,KAAA;AAAA,EACP;AAAA,EAEA,MAAc,qBAAoC;AAChD,QAAI,KAAK,cAAc;AACrB;AAAA,IACF;AAEA,SAAK,eAAe,IAAI,aAAA;AACxB,SAAK,gBAAgB,KAAK,aAAa,WAAA;AACvC,SAAK,cAAc,KAAK,QAAQ,KAAK;AACrC,SAAK,cAAc,QAAQ,KAAK,aAAa,WAAW;AAAA,EAC1D;AAAA,EAEQ,qBAA2B;AACjC,QAAI,CAAC,KAAK,gBAAgB,CAAC,KAAK,gBAAgB,CAAC,KAAK,eAAe;AACnE;AAAA,IACF;AAEA,SAAK,kBAAA;AAEL,SAAK,aACF,wBAAwB,KAAK,aAAa,EAC1C,KAAK,CAAC,cAAc;AACnB,UAAI,CAAC,aAAa,CAAC,KAAK,gBAAgB,CAAC,KAAK,eAAe;AAC3D;AAAA,MACF;AAEA,YAAM,SAAS,KAAK,aAAa,mBAAA;AACjC,aAAO,SAAS,UAAU;AAC1B,aAAO,aAAa,QAAQ,KAAK;AACjC,aAAO,UAAU,MAAM;AACrB,aAAK,cAAc;AACnB,YAAI,KAAK,UAAU,WAAW;AAC5B,eAAK,mBAAA;AAAA,QACP;AAAA,MACF;AAEA,aAAO,QAAQ,KAAK,aAAa;AACjC,aAAO,MAAM,GAAG,UAAU,eAAe,UAAU,eAAe;AAClE,WAAK,cAAc;AAAA,IACrB,CAAC,EACA,MAAM,CAAC,UAAU;AAChB,cAAQ,MAAM,8CAA8C,KAAK;AAAA,IACnE,CAAC;AAAA,EACL;AAAA,EAEQ,oBAA0B;AAChC,QAAI,KAAK,aAAa;AACpB,UAAI;AACF,aAAK,YAAY,KAAA;AAAA,MACnB,SAAS,OAAO;AACd,gBAAQ,KAAK,0CAA0C,KAAK;AAAA,MAC9D;AACA,WAAK,YAAY,WAAA;AACjB,WAAK,cAAc;AAAA,IACrB;AAAA,EACF;AACF;"}
|
|
@@ -44,10 +44,9 @@ export interface IPlaybackController {
|
|
|
44
44
|
setVolume(volume: number): void;
|
|
45
45
|
setLoop(loop: boolean): void;
|
|
46
46
|
setMute(muted: boolean): void;
|
|
47
|
-
|
|
47
|
+
currentTimeUs: TimeUs;
|
|
48
48
|
readonly duration: TimeUs;
|
|
49
|
-
readonly
|
|
50
|
-
readonly playing: boolean;
|
|
49
|
+
readonly isPlaying: boolean;
|
|
51
50
|
}
|
|
52
51
|
export type PlaybackState = 'idle' | 'buffering' | 'playing' | 'paused' | 'seeking' | 'ended';
|
|
53
52
|
export type PlaybackEvent = 'play' | 'pause' | 'ended' | 'seek' | 'timeupdate' | 'ratechange' | 'error' | 'frame' | 'stop';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/controllers/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAC;AAC7C,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAClD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAGvD,YAAY,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAC;AAI7C,MAAM,WAAW,iBAAiB;IAEhC,KAAK,IAAI,IAAI,CAAC;IACd,IAAI,IAAI,IAAI,CAAC;IACb,KAAK,IAAI,IAAI,CAAC;IACd,MAAM,IAAI,IAAI,CAAC;IAGf,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,WAAW,CAAC,QAAQ,EAAE,KAAK,GAAG,QAAQ,GAAG,MAAM,GAAG,IAAI,CAAC;IACvD,WAAW,CAAC,QAAQ,EAAE,cAAc,GAAG,IAAI,CAAC;IAG5C,UAAU,IAAI,IAAI,CAAC;IACnB,UAAU,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAGpE,QAAQ,CAAC,MAAM,EAAE,eAAe,CAAC;IACjC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;CAC5B;AAED,MAAM,WAAW,cAAc;IAC7B,SAAS,EAAE,SAAS,GAAG,UAAU,GAAG,eAAe,CAAC;IACpD,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB;AAED,MAAM,WAAW,eAAe;IAC9B,SAAS,EAAE,OAAO,CAAC;IACnB,cAAc,EAAE,MAAM,CAAC;IACvB,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,iBAAiB,EAAE,MAAM,GAAG,UAAU,GAAG,WAAW,GAAG,YAAY,CAAC;CACrE;AAID,MAAM,WAAW,mBAAmB;IAElC,IAAI,IAAI,IAAI,CAAC;IACb,KAAK,IAAI,IAAI,CAAC;IACd,IAAI,IAAI,IAAI,CAAC;IACb,IAAI,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IAG3B,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,OAAO,CAAC,IAAI,EAAE,OAAO,GAAG,IAAI,CAAC;IAC7B,OAAO,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI,CAAC;IAG9B,
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/controllers/types.ts"],"names":[],"mappings":"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"}
|
package/dist/event/events.d.ts
CHANGED
|
@@ -232,10 +232,7 @@ export interface EventPayloadMap {
|
|
|
232
232
|
};
|
|
233
233
|
[MeframeEvent.PatchApplied]: {
|
|
234
234
|
operations: number;
|
|
235
|
-
|
|
236
|
-
startUs: TimeUs;
|
|
237
|
-
endUs: TimeUs;
|
|
238
|
-
}>;
|
|
235
|
+
affectedClips: string[];
|
|
239
236
|
};
|
|
240
237
|
[MeframeEvent.Ready]: {
|
|
241
238
|
trackCount: number;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"events.d.ts","sourceRoot":"","sources":["../../src/event/events.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"events.d.ts","sourceRoot":"","sources":["../../src/event/events.ts"],"names":[],"mappings":"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"}
|
package/dist/event/events.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"events.js","sources":["../../src/event/events.ts"],"sourcesContent":["/**\n * Core event definitions for the Meframe engine\n * These are public events exposed to plugins and external components\n */\n\nimport { CompositionModel, Resource, type TimeUs } from '../model';\n\nexport interface ResourceEvent {\n type: MeframeEvent;\n resourceId: string;\n resource?: Resource;\n oldState?: Resource['state'];\n newState?: Resource['state'];\n workerType?: string;\n}\n\n/**\n * Core event types\n */\nexport enum MeframeEvent {\n // Composition model events\n ModelSet = 'model:set',\n\n // Resource events\n ResourceAdd = 'resource:add',\n ResourceUpdate = 'resource:update',\n ResourceRemove = 'resource:remove',\n ResourceStageChange = 'resource:state',\n\n // Load stage events\n LoadStart = 'load:start',\n LoadProgress = 'load:progress',\n LoadComplete = 'load:complete',\n LoadError = 'load:error',\n\n // Demux stage events\n DemuxStart = 'demux:start',\n DemuxProgress = 'demux:progress',\n DemuxComplete = 'demux:complete',\n DemuxError = 'demux:error',\n\n // Decode stage events\n DecodeStart = 'decode:start',\n DecodeProgress = 'decode:progress',\n DecodeComplete = 'decode:complete',\n DecodeError = 'decode:error',\n\n // Compose stage events\n ComposeStart = 'compose:start',\n ComposeProgress = 'compose:progress',\n ComposeComplete = 'compose:complete',\n\n // Composition frame events (L1 cache)\n ComposeFrameReady = 'compose:frameReady',\n ComposeFrameDropped = 'compose:frameDropped',\n\n // Encode events (L2 cache)\n EncodeChunkReady = 'encode:chunkReady',\n EncodeChunkError = 'encode:chunkError',\n\n // Cache events\n CacheHit = 'cache:hit',\n CacheMiss = 'cache:miss',\n CacheEvict = 'cache:evict',\n CacheWrite = 'cache:write',\n CacheCover = 'cache:cover',\n\n // Export events\n ExportStart = 'export:start',\n ExportProgress = 'export:progress',\n ExportComplete = 'export:complete',\n ExportError = 'export:error',\n\n // Composition model events\n CompositionUpdated = 'composition:updated',\n PatchApplied = 'patch:applied',\n Ready = 'ready',\n\n // Worker events\n WorkerStarted = 'worker:started',\n WorkerReady = 'worker:ready',\n WorkerError = 'worker:error',\n WorkerRestarted = 'worker:restarted',\n\n // Playback events\n PlaybackBuffering = 'playback:buffering',\n PlaybackPlay = 'playback:play',\n PlaybackPause = 'playback:pause',\n PlaybackStop = 'playback:stop',\n PlaybackSeek = 'playback:seek',\n PlaybackEnded = 'playback:ended',\n PlaybackTimeUpdate = 'playback:timeupdate',\n PlaybackRateChange = 'playback:ratechange',\n PlaybackVolumeChange = 'playback:volumechange',\n PlaybackError = 'playback:error',\n PlaybackStarted = 'playback:started',\n PlaybackPaused = 'playback:paused',\n PlaybackSeeked = 'playback:seeked',\n\n // General error event\n Error = 'error',\n\n // Plugin events\n PluginLoaded = 'plugin:loaded',\n PluginError = 'plugin:error',\n PluginUnloaded = 'plugin:unloaded',\n\n // Clip lifecycle events\n ClipActivated = 'clip:activated',\n ClipDeactivated = 'clip:deactivated',\n}\n\n/**\n * Event payload definitions\n */\nexport interface EventPayloadMap {\n // Composition model events\n [MeframeEvent.ModelSet]: CompositionModel;\n\n // Resource events\n [MeframeEvent.ResourceAdd]: ResourceEvent;\n [MeframeEvent.ResourceUpdate]: ResourceEvent;\n [MeframeEvent.ResourceRemove]: ResourceEvent;\n [MeframeEvent.ResourceStageChange]: ResourceEvent;\n\n // Load events\n [MeframeEvent.LoadStart]: {\n resourceId: string;\n url: string;\n size?: number;\n };\n\n [MeframeEvent.LoadProgress]: {\n resourceId: string;\n loaded: number;\n total: number;\n progress: number;\n };\n\n [MeframeEvent.LoadComplete]: {\n resourceId: string;\n bytes: number;\n durationMs: number;\n };\n\n [MeframeEvent.LoadError]: {\n resourceId: string;\n error: Error;\n retry?: boolean;\n };\n\n // Demux events\n [MeframeEvent.DemuxStart]: {\n clipId: string;\n trackId?: string;\n format?: string;\n };\n\n [MeframeEvent.DemuxProgress]: {\n clipId: string;\n progress: number;\n };\n\n [MeframeEvent.DemuxComplete]: {\n clipId: string;\n trackCount: number;\n durationUs: TimeUs;\n };\n\n [MeframeEvent.DemuxError]: {\n clipId: string;\n error: Error;\n };\n\n // Decode events\n [MeframeEvent.DecodeStart]: {\n clipId: string;\n frameCount?: number;\n trackType: 'video' | 'audio';\n };\n\n [MeframeEvent.DecodeProgress]: {\n clipId: string;\n decodedFrames: number;\n totalFrames: number;\n progress: number;\n };\n\n [MeframeEvent.DecodeComplete]: {\n clipId: string;\n frameCount: number;\n durationUs: TimeUs;\n };\n\n [MeframeEvent.DecodeError]: {\n clipId: string;\n error: Error;\n frame?: number;\n };\n\n // Compose events\n [MeframeEvent.ComposeStart]: {\n timeUs: TimeUs;\n clipIds: string[];\n };\n\n [MeframeEvent.ComposeProgress]: {\n timeUs: TimeUs;\n progress: number;\n };\n\n [MeframeEvent.ComposeComplete]: {\n timeUs: TimeUs;\n frameNumber: number;\n };\n\n // Composition frame events\n [MeframeEvent.ComposeFrameReady]: {\n timeUs: TimeUs;\n frameNumber: number;\n renderTimeMs: number;\n trackId: string;\n clipId: string;\n };\n\n [MeframeEvent.ComposeFrameDropped]: {\n timeUs: TimeUs;\n reason: 'decode_slow' | 'compose_slow' | 'backpressure';\n };\n\n // Encode events\n [MeframeEvent.EncodeChunkReady]: {\n timeUs: TimeUs;\n durationUs: TimeUs;\n track: 'video' | 'audio';\n size: number;\n };\n\n [MeframeEvent.EncodeChunkError]: {\n timeUs: TimeUs;\n track: 'video' | 'audio';\n error: Error;\n };\n\n // Cache events\n [MeframeEvent.CacheHit]: {\n timeUs: TimeUs;\n level: 'L1' | 'L2';\n key?: string;\n };\n\n [MeframeEvent.CacheMiss]: {\n timeUs: TimeUs;\n level: 'L1' | 'L2';\n key?: string;\n };\n\n [MeframeEvent.CacheEvict]: {\n clipId: string;\n count: number;\n level: 'L1' | 'L2';\n reason: 'size' | 'ttl' | 'manual';\n };\n\n [MeframeEvent.CacheWrite]: {\n clipId: string;\n timeUs: TimeUs;\n level: 'L1' | 'L2';\n size: number;\n };\n [MeframeEvent.CacheCover]: {\n clipId: string;\n timeUs: TimeUs;\n level: 'L1' | 'L2';\n size: number;\n };\n\n // Export events\n [MeframeEvent.ExportStart]: {\n format: string;\n width: number;\n height: number;\n fps: number;\n durationUs: TimeUs;\n };\n\n [MeframeEvent.ExportProgress]: {\n progress: number;\n currentFrame: number;\n totalFrames: number;\n timeUs: TimeUs;\n };\n\n [MeframeEvent.ExportComplete]: {\n size: number;\n durationMs: number;\n format: string;\n };\n\n [MeframeEvent.ExportError]: {\n error: Error;\n stage?: string;\n };\n\n // Composition events\n [MeframeEvent.CompositionUpdated]: {\n trackCount: number;\n clipCount: number;\n durationUs: TimeUs;\n };\n\n [MeframeEvent.PatchApplied]: {\n operations: number;\n dirtyRanges: Array<{ startUs: TimeUs; endUs: TimeUs }>;\n };\n\n [MeframeEvent.Ready]: {\n trackCount: number;\n clipCount: number;\n durationUs: TimeUs;\n };\n\n // Worker events\n [MeframeEvent.WorkerStarted]: {\n type: string;\n workerId: string;\n };\n\n [MeframeEvent.WorkerReady]: {\n type: string;\n workerId: string;\n };\n\n [MeframeEvent.WorkerError]: {\n type: string;\n workerId: string;\n error: Error;\n };\n\n [MeframeEvent.WorkerRestarted]: {\n type: string;\n workerId: string;\n reason: string;\n };\n\n // Playback events\n [MeframeEvent.PlaybackBuffering]: undefined;\n\n [MeframeEvent.PlaybackPlay]: undefined;\n\n [MeframeEvent.PlaybackPause]: undefined;\n\n [MeframeEvent.PlaybackStop]: undefined;\n\n [MeframeEvent.PlaybackSeek]: {\n timeUs: TimeUs;\n };\n\n [MeframeEvent.PlaybackStarted]: {\n timeUs: TimeUs;\n };\n\n [MeframeEvent.PlaybackPaused]: {\n timeUs: TimeUs;\n };\n\n [MeframeEvent.PlaybackSeeked]: {\n fromUs: TimeUs;\n toUs: TimeUs;\n };\n\n [MeframeEvent.PlaybackEnded]: {\n timeUs: TimeUs;\n };\n\n [MeframeEvent.PlaybackTimeUpdate]: {\n timeUs: TimeUs;\n };\n\n [MeframeEvent.PlaybackRateChange]: {\n rate: number;\n };\n\n [MeframeEvent.PlaybackVolumeChange]: {\n volume: number;\n };\n\n [MeframeEvent.PlaybackError]: Error;\n\n // Error event\n [MeframeEvent.Error]: {\n source: string;\n error: Error;\n context?: any;\n recoverable?: boolean;\n };\n\n // Plugin events\n [MeframeEvent.PluginLoaded]: {\n name: string;\n version?: string;\n };\n\n [MeframeEvent.PluginError]: {\n plugin: string;\n error: Error;\n };\n\n [MeframeEvent.PluginUnloaded]: {\n name: string;\n };\n\n // Clip events\n [MeframeEvent.ClipActivated]: {\n clipId: string;\n };\n\n [MeframeEvent.ClipDeactivated]: {\n clipId: string;\n };\n}\n"],"names":["MeframeEvent"],"mappings":"AAmBO,IAAK,iCAAAA,kBAAL;AAELA,gBAAA,UAAA,IAAW;AAGXA,gBAAA,aAAA,IAAc;AACdA,gBAAA,gBAAA,IAAiB;AACjBA,gBAAA,gBAAA,IAAiB;AACjBA,gBAAA,qBAAA,IAAsB;AAGtBA,gBAAA,WAAA,IAAY;AACZA,gBAAA,cAAA,IAAe;AACfA,gBAAA,cAAA,IAAe;AACfA,gBAAA,WAAA,IAAY;AAGZA,gBAAA,YAAA,IAAa;AACbA,gBAAA,eAAA,IAAgB;AAChBA,gBAAA,eAAA,IAAgB;AAChBA,gBAAA,YAAA,IAAa;AAGbA,gBAAA,aAAA,IAAc;AACdA,gBAAA,gBAAA,IAAiB;AACjBA,gBAAA,gBAAA,IAAiB;AACjBA,gBAAA,aAAA,IAAc;AAGdA,gBAAA,cAAA,IAAe;AACfA,gBAAA,iBAAA,IAAkB;AAClBA,gBAAA,iBAAA,IAAkB;AAGlBA,gBAAA,mBAAA,IAAoB;AACpBA,gBAAA,qBAAA,IAAsB;AAGtBA,gBAAA,kBAAA,IAAmB;AACnBA,gBAAA,kBAAA,IAAmB;AAGnBA,gBAAA,UAAA,IAAW;AACXA,gBAAA,WAAA,IAAY;AACZA,gBAAA,YAAA,IAAa;AACbA,gBAAA,YAAA,IAAa;AACbA,gBAAA,YAAA,IAAa;AAGbA,gBAAA,aAAA,IAAc;AACdA,gBAAA,gBAAA,IAAiB;AACjBA,gBAAA,gBAAA,IAAiB;AACjBA,gBAAA,aAAA,IAAc;AAGdA,gBAAA,oBAAA,IAAqB;AACrBA,gBAAA,cAAA,IAAe;AACfA,gBAAA,OAAA,IAAQ;AAGRA,gBAAA,eAAA,IAAgB;AAChBA,gBAAA,aAAA,IAAc;AACdA,gBAAA,aAAA,IAAc;AACdA,gBAAA,iBAAA,IAAkB;AAGlBA,gBAAA,mBAAA,IAAoB;AACpBA,gBAAA,cAAA,IAAe;AACfA,gBAAA,eAAA,IAAgB;AAChBA,gBAAA,cAAA,IAAe;AACfA,gBAAA,cAAA,IAAe;AACfA,gBAAA,eAAA,IAAgB;AAChBA,gBAAA,oBAAA,IAAqB;AACrBA,gBAAA,oBAAA,IAAqB;AACrBA,gBAAA,sBAAA,IAAuB;AACvBA,gBAAA,eAAA,IAAgB;AAChBA,gBAAA,iBAAA,IAAkB;AAClBA,gBAAA,gBAAA,IAAiB;AACjBA,gBAAA,gBAAA,IAAiB;AAGjBA,gBAAA,OAAA,IAAQ;AAGRA,gBAAA,cAAA,IAAe;AACfA,gBAAA,aAAA,IAAc;AACdA,gBAAA,gBAAA,IAAiB;AAGjBA,gBAAA,eAAA,IAAgB;AAChBA,gBAAA,iBAAA,IAAkB;AA1FR,SAAAA;AAAA,GAAA,gBAAA,CAAA,CAAA;"}
|
|
1
|
+
{"version":3,"file":"events.js","sources":["../../src/event/events.ts"],"sourcesContent":["/**\n * Core event definitions for the Meframe engine\n * These are public events exposed to plugins and external components\n */\n\nimport { CompositionModel, Resource, type TimeUs } from '../model';\n\nexport interface ResourceEvent {\n type: MeframeEvent;\n resourceId: string;\n resource?: Resource;\n oldState?: Resource['state'];\n newState?: Resource['state'];\n workerType?: string;\n}\n\n/**\n * Core event types\n */\nexport enum MeframeEvent {\n // Composition model events\n ModelSet = 'model:set',\n\n // Resource events\n ResourceAdd = 'resource:add',\n ResourceUpdate = 'resource:update',\n ResourceRemove = 'resource:remove',\n ResourceStageChange = 'resource:state',\n\n // Load stage events\n LoadStart = 'load:start',\n LoadProgress = 'load:progress',\n LoadComplete = 'load:complete',\n LoadError = 'load:error',\n\n // Demux stage events\n DemuxStart = 'demux:start',\n DemuxProgress = 'demux:progress',\n DemuxComplete = 'demux:complete',\n DemuxError = 'demux:error',\n\n // Decode stage events\n DecodeStart = 'decode:start',\n DecodeProgress = 'decode:progress',\n DecodeComplete = 'decode:complete',\n DecodeError = 'decode:error',\n\n // Compose stage events\n ComposeStart = 'compose:start',\n ComposeProgress = 'compose:progress',\n ComposeComplete = 'compose:complete',\n\n // Composition frame events (L1 cache)\n ComposeFrameReady = 'compose:frameReady',\n ComposeFrameDropped = 'compose:frameDropped',\n\n // Encode events (L2 cache)\n EncodeChunkReady = 'encode:chunkReady',\n EncodeChunkError = 'encode:chunkError',\n\n // Cache events\n CacheHit = 'cache:hit',\n CacheMiss = 'cache:miss',\n CacheEvict = 'cache:evict',\n CacheWrite = 'cache:write',\n CacheCover = 'cache:cover',\n\n // Export events\n ExportStart = 'export:start',\n ExportProgress = 'export:progress',\n ExportComplete = 'export:complete',\n ExportError = 'export:error',\n\n // Composition model events\n CompositionUpdated = 'composition:updated',\n PatchApplied = 'patch:applied',\n Ready = 'ready',\n\n // Worker events\n WorkerStarted = 'worker:started',\n WorkerReady = 'worker:ready',\n WorkerError = 'worker:error',\n WorkerRestarted = 'worker:restarted',\n\n // Playback events\n PlaybackBuffering = 'playback:buffering',\n PlaybackPlay = 'playback:play',\n PlaybackPause = 'playback:pause',\n PlaybackStop = 'playback:stop',\n PlaybackSeek = 'playback:seek',\n PlaybackEnded = 'playback:ended',\n PlaybackTimeUpdate = 'playback:timeupdate',\n PlaybackRateChange = 'playback:ratechange',\n PlaybackVolumeChange = 'playback:volumechange',\n PlaybackError = 'playback:error',\n PlaybackStarted = 'playback:started',\n PlaybackPaused = 'playback:paused',\n PlaybackSeeked = 'playback:seeked',\n\n // General error event\n Error = 'error',\n\n // Plugin events\n PluginLoaded = 'plugin:loaded',\n PluginError = 'plugin:error',\n PluginUnloaded = 'plugin:unloaded',\n\n // Clip lifecycle events\n ClipActivated = 'clip:activated',\n ClipDeactivated = 'clip:deactivated',\n}\n\n/**\n * Event payload definitions\n */\nexport interface EventPayloadMap {\n // Composition model events\n [MeframeEvent.ModelSet]: CompositionModel;\n\n // Resource events\n [MeframeEvent.ResourceAdd]: ResourceEvent;\n [MeframeEvent.ResourceUpdate]: ResourceEvent;\n [MeframeEvent.ResourceRemove]: ResourceEvent;\n [MeframeEvent.ResourceStageChange]: ResourceEvent;\n\n // Load events\n [MeframeEvent.LoadStart]: {\n resourceId: string;\n url: string;\n size?: number;\n };\n\n [MeframeEvent.LoadProgress]: {\n resourceId: string;\n loaded: number;\n total: number;\n progress: number;\n };\n\n [MeframeEvent.LoadComplete]: {\n resourceId: string;\n bytes: number;\n durationMs: number;\n };\n\n [MeframeEvent.LoadError]: {\n resourceId: string;\n error: Error;\n retry?: boolean;\n };\n\n // Demux events\n [MeframeEvent.DemuxStart]: {\n clipId: string;\n trackId?: string;\n format?: string;\n };\n\n [MeframeEvent.DemuxProgress]: {\n clipId: string;\n progress: number;\n };\n\n [MeframeEvent.DemuxComplete]: {\n clipId: string;\n trackCount: number;\n durationUs: TimeUs;\n };\n\n [MeframeEvent.DemuxError]: {\n clipId: string;\n error: Error;\n };\n\n // Decode events\n [MeframeEvent.DecodeStart]: {\n clipId: string;\n frameCount?: number;\n trackType: 'video' | 'audio';\n };\n\n [MeframeEvent.DecodeProgress]: {\n clipId: string;\n decodedFrames: number;\n totalFrames: number;\n progress: number;\n };\n\n [MeframeEvent.DecodeComplete]: {\n clipId: string;\n frameCount: number;\n durationUs: TimeUs;\n };\n\n [MeframeEvent.DecodeError]: {\n clipId: string;\n error: Error;\n frame?: number;\n };\n\n // Compose events\n [MeframeEvent.ComposeStart]: {\n timeUs: TimeUs;\n clipIds: string[];\n };\n\n [MeframeEvent.ComposeProgress]: {\n timeUs: TimeUs;\n progress: number;\n };\n\n [MeframeEvent.ComposeComplete]: {\n timeUs: TimeUs;\n frameNumber: number;\n };\n\n // Composition frame events\n [MeframeEvent.ComposeFrameReady]: {\n timeUs: TimeUs;\n frameNumber: number;\n renderTimeMs: number;\n trackId: string;\n clipId: string;\n };\n\n [MeframeEvent.ComposeFrameDropped]: {\n timeUs: TimeUs;\n reason: 'decode_slow' | 'compose_slow' | 'backpressure';\n };\n\n // Encode events\n [MeframeEvent.EncodeChunkReady]: {\n timeUs: TimeUs;\n durationUs: TimeUs;\n track: 'video' | 'audio';\n size: number;\n };\n\n [MeframeEvent.EncodeChunkError]: {\n timeUs: TimeUs;\n track: 'video' | 'audio';\n error: Error;\n };\n\n // Cache events\n [MeframeEvent.CacheHit]: {\n timeUs: TimeUs;\n level: 'L1' | 'L2';\n key?: string;\n };\n\n [MeframeEvent.CacheMiss]: {\n timeUs: TimeUs;\n level: 'L1' | 'L2';\n key?: string;\n };\n\n [MeframeEvent.CacheEvict]: {\n clipId: string;\n count: number;\n level: 'L1' | 'L2';\n reason: 'size' | 'ttl' | 'manual';\n };\n\n [MeframeEvent.CacheWrite]: {\n clipId: string;\n timeUs: TimeUs;\n level: 'L1' | 'L2';\n size: number;\n };\n [MeframeEvent.CacheCover]: {\n clipId: string;\n timeUs: TimeUs;\n level: 'L1' | 'L2';\n size: number;\n };\n\n // Export events\n [MeframeEvent.ExportStart]: {\n format: string;\n width: number;\n height: number;\n fps: number;\n durationUs: TimeUs;\n };\n\n [MeframeEvent.ExportProgress]: {\n progress: number;\n currentFrame: number;\n totalFrames: number;\n timeUs: TimeUs;\n };\n\n [MeframeEvent.ExportComplete]: {\n size: number;\n durationMs: number;\n format: string;\n };\n\n [MeframeEvent.ExportError]: {\n error: Error;\n stage?: string;\n };\n\n // Composition events\n [MeframeEvent.CompositionUpdated]: {\n trackCount: number;\n clipCount: number;\n durationUs: TimeUs;\n };\n\n [MeframeEvent.PatchApplied]: {\n operations: number;\n affectedClips: string[];\n };\n\n [MeframeEvent.Ready]: {\n trackCount: number;\n clipCount: number;\n durationUs: TimeUs;\n };\n\n // Worker events\n [MeframeEvent.WorkerStarted]: {\n type: string;\n workerId: string;\n };\n\n [MeframeEvent.WorkerReady]: {\n type: string;\n workerId: string;\n };\n\n [MeframeEvent.WorkerError]: {\n type: string;\n workerId: string;\n error: Error;\n };\n\n [MeframeEvent.WorkerRestarted]: {\n type: string;\n workerId: string;\n reason: string;\n };\n\n // Playback events\n [MeframeEvent.PlaybackBuffering]: undefined;\n\n [MeframeEvent.PlaybackPlay]: undefined;\n\n [MeframeEvent.PlaybackPause]: undefined;\n\n [MeframeEvent.PlaybackStop]: undefined;\n\n [MeframeEvent.PlaybackSeek]: {\n timeUs: TimeUs;\n };\n\n [MeframeEvent.PlaybackStarted]: {\n timeUs: TimeUs;\n };\n\n [MeframeEvent.PlaybackPaused]: {\n timeUs: TimeUs;\n };\n\n [MeframeEvent.PlaybackSeeked]: {\n fromUs: TimeUs;\n toUs: TimeUs;\n };\n\n [MeframeEvent.PlaybackEnded]: {\n timeUs: TimeUs;\n };\n\n [MeframeEvent.PlaybackTimeUpdate]: {\n timeUs: TimeUs;\n };\n\n [MeframeEvent.PlaybackRateChange]: {\n rate: number;\n };\n\n [MeframeEvent.PlaybackVolumeChange]: {\n volume: number;\n };\n\n [MeframeEvent.PlaybackError]: Error;\n\n // Error event\n [MeframeEvent.Error]: {\n source: string;\n error: Error;\n context?: any;\n recoverable?: boolean;\n };\n\n // Plugin events\n [MeframeEvent.PluginLoaded]: {\n name: string;\n version?: string;\n };\n\n [MeframeEvent.PluginError]: {\n plugin: string;\n error: Error;\n };\n\n [MeframeEvent.PluginUnloaded]: {\n name: string;\n };\n\n // Clip events\n [MeframeEvent.ClipActivated]: {\n clipId: string;\n };\n\n [MeframeEvent.ClipDeactivated]: {\n clipId: string;\n };\n}\n"],"names":["MeframeEvent"],"mappings":"AAmBO,IAAK,iCAAAA,kBAAL;AAELA,gBAAA,UAAA,IAAW;AAGXA,gBAAA,aAAA,IAAc;AACdA,gBAAA,gBAAA,IAAiB;AACjBA,gBAAA,gBAAA,IAAiB;AACjBA,gBAAA,qBAAA,IAAsB;AAGtBA,gBAAA,WAAA,IAAY;AACZA,gBAAA,cAAA,IAAe;AACfA,gBAAA,cAAA,IAAe;AACfA,gBAAA,WAAA,IAAY;AAGZA,gBAAA,YAAA,IAAa;AACbA,gBAAA,eAAA,IAAgB;AAChBA,gBAAA,eAAA,IAAgB;AAChBA,gBAAA,YAAA,IAAa;AAGbA,gBAAA,aAAA,IAAc;AACdA,gBAAA,gBAAA,IAAiB;AACjBA,gBAAA,gBAAA,IAAiB;AACjBA,gBAAA,aAAA,IAAc;AAGdA,gBAAA,cAAA,IAAe;AACfA,gBAAA,iBAAA,IAAkB;AAClBA,gBAAA,iBAAA,IAAkB;AAGlBA,gBAAA,mBAAA,IAAoB;AACpBA,gBAAA,qBAAA,IAAsB;AAGtBA,gBAAA,kBAAA,IAAmB;AACnBA,gBAAA,kBAAA,IAAmB;AAGnBA,gBAAA,UAAA,IAAW;AACXA,gBAAA,WAAA,IAAY;AACZA,gBAAA,YAAA,IAAa;AACbA,gBAAA,YAAA,IAAa;AACbA,gBAAA,YAAA,IAAa;AAGbA,gBAAA,aAAA,IAAc;AACdA,gBAAA,gBAAA,IAAiB;AACjBA,gBAAA,gBAAA,IAAiB;AACjBA,gBAAA,aAAA,IAAc;AAGdA,gBAAA,oBAAA,IAAqB;AACrBA,gBAAA,cAAA,IAAe;AACfA,gBAAA,OAAA,IAAQ;AAGRA,gBAAA,eAAA,IAAgB;AAChBA,gBAAA,aAAA,IAAc;AACdA,gBAAA,aAAA,IAAc;AACdA,gBAAA,iBAAA,IAAkB;AAGlBA,gBAAA,mBAAA,IAAoB;AACpBA,gBAAA,cAAA,IAAe;AACfA,gBAAA,eAAA,IAAgB;AAChBA,gBAAA,cAAA,IAAe;AACfA,gBAAA,cAAA,IAAe;AACfA,gBAAA,eAAA,IAAgB;AAChBA,gBAAA,oBAAA,IAAqB;AACrBA,gBAAA,oBAAA,IAAqB;AACrBA,gBAAA,sBAAA,IAAuB;AACvBA,gBAAA,eAAA,IAAgB;AAChBA,gBAAA,iBAAA,IAAkB;AAClBA,gBAAA,gBAAA,IAAiB;AACjBA,gBAAA,gBAAA,IAAiB;AAGjBA,gBAAA,OAAA,IAAQ;AAGRA,gBAAA,cAAA,IAAe;AACfA,gBAAA,aAAA,IAAc;AACdA,gBAAA,gBAAA,IAAiB;AAGjBA,gBAAA,eAAA,IAAgB;AAChBA,gBAAA,iBAAA,IAAkB;AA1FR,SAAAA;AAAA,GAAA,gBAAA,CAAA,CAAA;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CompositionModel.d.ts","sourceRoot":"","sources":["../../src/model/CompositionModel.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AAI9E,qBAAa,gBAAgB;IAC3B,SAAgB,OAAO,EAAG,KAAK,CAAU;IACzC,SAAgB,GAAG,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC;IAChC,UAAU,EAAE,MAAM,CAAC;IAC1B,SAAgB,MAAM,EAAE,KAAK,EAAE,CAAC;IAChC,SAAgB,SAAS,EAAE,GAAG,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;IAEjD,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAqB;IAC9C,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAoB;IAC5C,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAsB;IAEvD,SAAgB,YAAY,CAAC,EAAE;QAC7B,KAAK,EAAE,MAAM,CAAC;QACd,MAAM,EAAE,MAAM,CAAC;QACf,eAAe,CAAC,EAAE,MAAM,CAAC;KAC1B,CAAC;IAEF,SAAgB,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;gBAElC,IAAI,EAAE,oBAAoB;
|
|
1
|
+
{"version":3,"file":"CompositionModel.d.ts","sourceRoot":"","sources":["../../src/model/CompositionModel.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AAI9E,qBAAa,gBAAgB;IAC3B,SAAgB,OAAO,EAAG,KAAK,CAAU;IACzC,SAAgB,GAAG,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC;IAChC,UAAU,EAAE,MAAM,CAAC;IAC1B,SAAgB,WAAW,EAAE,MAAM,CAAC;IACpC,SAAgB,MAAM,EAAE,KAAK,EAAE,CAAC;IAChC,SAAgB,SAAS,EAAE,GAAG,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;IAEjD,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAqB;IAC9C,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAoB;IAC5C,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAsB;IAEvD,SAAgB,YAAY,CAAC,EAAE;QAC7B,KAAK,EAAE,MAAM,CAAC;QACd,MAAM,EAAE,MAAM,CAAC;QACf,eAAe,CAAC,EAAE,MAAM,CAAC;KAC1B,CAAC;IAEF,SAAgB,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;gBAElC,IAAI,EAAE,oBAAoB;IAyBtC,SAAS,CAAC,EAAE,EAAE,MAAM,GAAG,KAAK,GAAG,IAAI;IAInC,eAAe,CAAC,IAAI,EAAE,OAAO,GAAG,OAAO,GAAG,SAAS,GAAG,IAAI,GAAG,KAAK,EAAE;IAKpE,QAAQ,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI;IAIjC,cAAc,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,EAAE;IAoBxD,cAAc,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,EAAE;IAgBtD,sBAAsB,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,EAAE;IAKpD,eAAe,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS;IAcpE;;;OAGG;IACH,mBAAmB,CAAC,MAAM,EAAE,MAAM,GAAG;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE;IAsCvF;;;OAGG;IACH,qBAAqB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE;IAY/C,WAAW,CAAC,EAAE,EAAE,MAAM,GAAG,QAAQ,GAAG,IAAI;IAIxC,mBAAmB,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,GAAG,SAAS,GAAG,OAAO,GAAG,OAAO,GAAG,IAAI;IAOvF,kBAAkB,IAAI,QAAQ,EAAE;IAahC,WAAW,IAAI,MAAM;IAIrB,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM;IAUzC,OAAO,CAAC,YAAY;IAgCpB,OAAO,CAAC,iBAAiB;CAY1B"}
|
|
@@ -4,6 +4,7 @@ class CompositionModel {
|
|
|
4
4
|
version = "1.0";
|
|
5
5
|
fps;
|
|
6
6
|
durationUs;
|
|
7
|
+
mainTrackId;
|
|
7
8
|
tracks;
|
|
8
9
|
resources;
|
|
9
10
|
trackMap;
|
|
@@ -20,6 +21,7 @@ ${errors.map((e) => `${e.path}: ${e.message}`).join("\n")}`
|
|
|
20
21
|
);
|
|
21
22
|
}
|
|
22
23
|
this.fps = data.fps;
|
|
24
|
+
this.mainTrackId = data.mainTrackId ?? "main";
|
|
23
25
|
this.tracks = data.tracks;
|
|
24
26
|
this.resources = new Map(Object.entries(data.resources));
|
|
25
27
|
this.renderConfig = data.renderConfig;
|