@meframe/core 0.1.7 → 0.1.9
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/cache/CacheManager.d.ts +1 -1
- 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/AudioL1Cache.d.ts +3 -8
- package/dist/cache/l1/AudioL1Cache.d.ts.map +1 -1
- package/dist/cache/l1/AudioL1Cache.js +41 -56
- package/dist/cache/l1/AudioL1Cache.js.map +1 -1
- package/dist/controllers/PlaybackController.d.ts +2 -0
- package/dist/controllers/PlaybackController.d.ts.map +1 -1
- package/dist/controllers/PlaybackController.js +75 -14
- package/dist/controllers/PlaybackController.js.map +1 -1
- package/dist/controllers/PlaybackStateMachine.d.ts.map +1 -1
- package/dist/controllers/PlaybackStateMachine.js +33 -10
- package/dist/controllers/PlaybackStateMachine.js.map +1 -1
- package/dist/controllers/types.d.ts +13 -3
- package/dist/controllers/types.d.ts.map +1 -1
- package/dist/controllers/types.js +2 -0
- package/dist/controllers/types.js.map +1 -1
- package/dist/model/types.d.ts +0 -1
- package/dist/model/types.d.ts.map +1 -1
- package/dist/model/types.js.map +1 -1
- package/dist/orchestrator/ExportScheduler.d.ts.map +1 -1
- package/dist/orchestrator/ExportScheduler.js +22 -19
- package/dist/orchestrator/ExportScheduler.js.map +1 -1
- package/dist/orchestrator/GlobalAudioSession.d.ts +15 -2
- package/dist/orchestrator/GlobalAudioSession.d.ts.map +1 -1
- package/dist/orchestrator/GlobalAudioSession.js +48 -20
- package/dist/orchestrator/GlobalAudioSession.js.map +1 -1
- package/dist/orchestrator/OnDemandVideoSession.d.ts.map +1 -1
- package/dist/orchestrator/OnDemandVideoSession.js +13 -0
- package/dist/orchestrator/OnDemandVideoSession.js.map +1 -1
- package/dist/orchestrator/Orchestrator.d.ts +1 -1
- package/dist/orchestrator/Orchestrator.d.ts.map +1 -1
- package/dist/orchestrator/Orchestrator.js +52 -20
- package/dist/orchestrator/Orchestrator.js.map +1 -1
- package/dist/orchestrator/VideoClipSession.d.ts.map +1 -1
- package/dist/orchestrator/VideoClipSession.js +4 -2
- package/dist/orchestrator/VideoClipSession.js.map +1 -1
- package/dist/orchestrator/types.d.ts +7 -1
- package/dist/orchestrator/types.d.ts.map +1 -1
- package/dist/stages/load/ResourceLoader.d.ts +6 -5
- package/dist/stages/load/ResourceLoader.d.ts.map +1 -1
- package/dist/stages/load/ResourceLoader.js +62 -41
- package/dist/stages/load/ResourceLoader.js.map +1 -1
- package/dist/stages/load/TaskManager.d.ts +5 -12
- package/dist/stages/load/TaskManager.d.ts.map +1 -1
- package/dist/stages/load/TaskManager.js +60 -46
- package/dist/stages/load/TaskManager.js.map +1 -1
- package/dist/stages/mux/MP4Muxer.d.ts.map +1 -1
- package/dist/stages/mux/MP4Muxer.js +3 -0
- package/dist/stages/mux/MP4Muxer.js.map +1 -1
- package/dist/utils/platform-utils.d.ts +1 -0
- package/dist/utils/platform-utils.d.ts.map +1 -1
- package/dist/utils/platform-utils.js +19 -6
- package/dist/utils/platform-utils.js.map +1 -1
- package/dist/worker/BaseWorker.d.ts +2 -0
- package/dist/worker/BaseWorker.d.ts.map +1 -1
- package/dist/worker/BaseWorker.js.map +1 -1
- package/dist/worker/WorkerChannel.d.ts +2 -0
- package/dist/worker/WorkerChannel.d.ts.map +1 -1
- package/dist/worker/WorkerChannel.js +17 -1
- package/dist/worker/WorkerChannel.js.map +1 -1
- package/dist/workers/{WorkerChannel.DjBEVvEA.js → WorkerChannel.DQK8rAab.js} +18 -2
- package/dist/workers/{WorkerChannel.DjBEVvEA.js.map → WorkerChannel.DQK8rAab.js.map} +1 -1
- package/dist/workers/stages/compose/{audio-compose.worker.CiM_KP27.js → audio-compose.worker.B4Io5w9i.js} +2 -2
- package/dist/workers/stages/compose/{audio-compose.worker.CiM_KP27.js.map → audio-compose.worker.B4Io5w9i.js.map} +1 -1
- package/dist/workers/stages/compose/{video-compose.worker.CQwmNfXT.js → video-compose.worker.CA2_Kpg-.js} +2 -2
- package/dist/workers/stages/compose/{video-compose.worker.CQwmNfXT.js.map → video-compose.worker.CA2_Kpg-.js.map} +1 -1
- package/dist/workers/stages/decode/{audio-decode.worker.CpjkrZtT.js → audio-decode.worker.-DGlQrJD.js} +2 -2
- package/dist/workers/stages/decode/{audio-decode.worker.CpjkrZtT.js.map → audio-decode.worker.-DGlQrJD.js.map} +1 -1
- package/dist/workers/stages/decode/{video-decode.worker.BQtw6eWn.js → video-decode.worker.BnWVUkng.js} +2 -2
- package/dist/workers/stages/decode/video-decode.worker.BnWVUkng.js.map +1 -0
- package/dist/workers/stages/demux/{audio-demux.worker.C4V11GQi.js → audio-demux.worker.D-_LoVqW.js} +2 -2
- package/dist/workers/stages/demux/{audio-demux.worker.C4V11GQi.js.map → audio-demux.worker.D-_LoVqW.js.map} +1 -1
- package/dist/workers/stages/demux/{video-demux.worker.5pJr0Ij-.js → video-demux.worker.BWDrLGni.js} +2 -2
- package/dist/workers/stages/demux/{video-demux.worker.5pJr0Ij-.js.map → video-demux.worker.BWDrLGni.js.map} +1 -1
- package/dist/workers/stages/encode/{video-encode.worker.CX2_3YhQ.js → video-encode.worker.D6aB_rF9.js} +2 -2
- package/dist/workers/stages/encode/{video-encode.worker.CX2_3YhQ.js.map → video-encode.worker.D6aB_rF9.js.map} +1 -1
- package/dist/workers/worker-manifest.json +7 -7
- package/package.json +1 -1
- package/dist/workers/stages/decode/video-decode.worker.BQtw6eWn.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PlaybackController.js","sources":["../../src/controllers/PlaybackController.ts"],"sourcesContent":["import type {\n IPlaybackController,\n PlaybackOptions,\n IEventBus,\n PreviewHandle,\n TimeUs,\n} from './types';\nimport {\n PlaybackActionType,\n PlaybackCommandType,\n PlaybackState,\n type OpToken,\n type PlaybackAction,\n type PlaybackCommand,\n} from './types';\nimport { MeframeEvent } from '../event/events';\nimport type { GlobalAudioSession } from '../orchestrator/GlobalAudioSession';\nimport type { Orchestrator } from '../orchestrator';\nimport { WaiterReplacedError } from '../utils/errors';\nimport { VideoComposer } from '../stages/compose/VideoComposer';\nimport { isVideoClip } from '../model/types';\n\nimport { PlaybackStateMachine } from './PlaybackStateMachine';\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 videoComposer: VideoComposer | null = null;\n\n // Playback time (external)\n currentTimeUs: TimeUs = 0;\n private playbackRate = 1.0;\n private volume = 1.0;\n private loop = false;\n\n // Time base\n private rafId: number | null = null;\n private startTimeUs: TimeUs = 0; // AudioContext timeline origin (microseconds)\n\n // Frame stats\n private frameCount = 0;\n private lastFrameTime = 0;\n private fps = 0;\n\n // Audio\n private audioContext: AudioContext;\n private audioSession: GlobalAudioSession;\n private lastAudioScheduleTime = 0;\n private readonly AUDIO_SCHEDULE_INTERVAL = 100_000; // 100ms\n\n // State machine\n private fsm = new PlaybackStateMachine();\n\n // Unified window management for both video and audio\n private windowEnd: TimeUs = 0;\n private readonly WINDOW_DURATION = 3_000_000; // 3s decode window\n private readonly PREHEAT_DISTANCE = 1_000_000; // 1s preheat trigger distance\n private preheatInProgress = false;\n\n constructor(orchestrator: Orchestrator, eventBus: IEventBus, options: PlaybackOptions) {\n this.orchestrator = orchestrator;\n this.audioSession = orchestrator.audioSession;\n this.eventBus = eventBus;\n this.canvas = options.canvas;\n this.audioContext = new AudioContext();\n\n const model = orchestrator.compositionModel;\n const width = model?.renderConfig?.width || this.canvas.width || 720;\n const height = model?.renderConfig?.height || this.canvas.height || 1280;\n\n this.videoComposer = new VideoComposer({\n width,\n height,\n fps: model?.fps || 30,\n backgroundColor: model?.renderConfig?.backgroundColor || '#000',\n externalCanvas: this.canvas,\n });\n\n if (options.startUs !== undefined) {\n this.currentTimeUs = options.startUs;\n }\n if (options.rate !== undefined) {\n this.playbackRate = options.rate;\n }\n if (options.loop !== undefined) {\n this.loop = options.loop;\n }\n\n this.setupEventListeners();\n\n if (options.autoStart) {\n this.play();\n }\n }\n\n async renderCover(): Promise<void> {\n await this.renderCurrentFrame(0, { immediate: false });\n }\n\n // ========= Public API =========\n\n play(): void {\n this.dispatch({ type: PlaybackActionType.Play });\n }\n\n pause(): void {\n this.dispatch({ type: PlaybackActionType.Pause });\n }\n\n stop(): void {\n this.dispatch({ type: PlaybackActionType.Stop });\n }\n\n async seek(timeUs: TimeUs): Promise<void> {\n const { done } = this.dispatch({\n type: PlaybackActionType.Seek,\n timeUs,\n durationUs: this.duration,\n });\n await done;\n }\n\n setRate(rate: number): void {\n const currentTimeUs = this.currentTimeUs;\n this.playbackRate = rate;\n\n // Keep currentTimeUs stable; update the time base for AudioContext clock mapping.\n this.startTimeUs = this.audioContext.currentTime * 1_000_000 - currentTimeUs / rate;\n this.audioSession.setPlaybackRate(this.playbackRate);\n\n this.eventBus.emit(MeframeEvent.PlaybackRateChange, { rate });\n }\n\n setVolume(volume: number): void {\n this.volume = Math.max(0, Math.min(1, volume));\n this.audioSession.setVolume(this.volume);\n this.eventBus.emit(MeframeEvent.PlaybackVolumeChange, { volume: this.volume });\n }\n\n setMute(muted: boolean): void {\n if (muted) {\n this.audioSession.stopPlayback();\n return;\n }\n if (this.fsm.snapshot.state === PlaybackState.Playing) {\n void this.audioSession.startPlayback(this.currentTimeUs, this.audioContext);\n }\n }\n\n setLoop(loop: boolean): void {\n this.loop = loop;\n }\n\n get duration(): TimeUs {\n return this.orchestrator.compositionModel?.durationUs ?? 0;\n }\n\n get isPlaying(): boolean {\n return this.fsm.snapshot.state === PlaybackState.Playing;\n }\n\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 // ========= State machine wiring =========\n\n private dispatch(action: PlaybackAction): { token: OpToken; done: Promise<void> } {\n const { token, commands } = this.fsm.dispatch(action, { currentTimeUs: this.currentTimeUs });\n const done = this.executeCommands(commands, token);\n return { token, done };\n }\n\n private executeCommands(commands: PlaybackCommand[], token: OpToken): Promise<void> {\n const maybe = this.executeSeq(commands, token, 0);\n return maybe ?? Promise.resolve();\n }\n\n private executeSeq(\n commands: PlaybackCommand[],\n token: OpToken,\n startIndex: number\n ): Promise<void> | void {\n for (let i = startIndex; i < commands.length; i++) {\n if (!this.isCurrentToken(token)) return;\n const maybe = this.executeCommand(commands[i]!, token);\n if (maybe) {\n return maybe.then(() => {\n if (!this.isCurrentToken(token)) return;\n const cont = this.executeSeq(commands, token, i + 1);\n return cont ?? Promise.resolve();\n });\n }\n }\n }\n\n private executePar(commands: PlaybackCommand[], token: OpToken): Promise<void> | void {\n const promises: Promise<void>[] = [];\n for (const c of commands) {\n if (!this.isCurrentToken(token)) return;\n const maybe = this.executeCommand(c, token);\n if (maybe) promises.push(maybe);\n }\n if (promises.length === 0) return;\n return Promise.all(promises).then(() => undefined);\n }\n\n private executeCommand(command: PlaybackCommand, token: OpToken): Promise<void> | void {\n if (!this.isCurrentToken(token)) return;\n\n switch (command.type) {\n case PlaybackCommandType.Seq:\n return this.executeSeq(command.commands, token, 0);\n case PlaybackCommandType.Par:\n return this.executePar(command.commands, token);\n case PlaybackCommandType.Try: {\n const handleError = (error: unknown): Promise<void> | void => {\n if (!this.isCurrentToken(token)) return;\n if (command.ignoreWaiterReplacedError && error instanceof WaiterReplacedError) return;\n if (command.logPrefix) console.error(command.logPrefix, error);\n const onErrorDone = command.onError ? this.dispatch(command.onError).done : undefined;\n const emit = () => {\n if (command.emitPlaybackError) {\n this.eventBus.emit(MeframeEvent.PlaybackError, error as Error);\n }\n };\n if (onErrorDone) {\n return onErrorDone.then(() => {\n emit();\n });\n }\n emit();\n };\n\n try {\n const maybe = this.executeCommand(command.command, token);\n if (maybe) {\n return maybe.catch(handleError);\n }\n return;\n } catch (error) {\n return handleError(error) ?? Promise.resolve();\n }\n }\n case PlaybackCommandType.Dispatch:\n return this.dispatch(command.action).done;\n case PlaybackCommandType.SetTime: {\n this.currentTimeUs = command.timeUs;\n return;\n }\n case PlaybackCommandType.SetFrozenTime:\n case PlaybackCommandType.SetWantsPlay:\n case PlaybackCommandType.SetState: {\n // managed inside fsm\n return;\n }\n case PlaybackCommandType.CancelRaf: {\n this.cancelRaf();\n return;\n }\n case PlaybackCommandType.StopAudio: {\n this.audioSession.stopPlayback();\n return;\n }\n case PlaybackCommandType.ResetAudioPlaybackStates: {\n this.audioSession.resetPlaybackStates();\n return;\n }\n case PlaybackCommandType.ResetAudioSession: {\n this.audioSession.reset();\n return;\n }\n case PlaybackCommandType.ClearCanvas: {\n this.clearCanvas();\n return;\n }\n case PlaybackCommandType.SetLastAudioScheduleTime: {\n this.lastAudioScheduleTime = command.timeUs;\n return;\n }\n case PlaybackCommandType.SetStartTimeBase: {\n this.startTimeUs = command.startTimeUs;\n return;\n }\n case PlaybackCommandType.SyncTimeBaseToAudioClock: {\n this.startTimeUs =\n this.audioContext.currentTime * 1_000_000 - command.timeUs / this.playbackRate;\n return;\n }\n case PlaybackCommandType.InitWindow: {\n this.initWindow(command.timeUs);\n return;\n }\n case PlaybackCommandType.SetCacheWindow: {\n this.orchestrator.cacheManager.setWindow(command.timeUs);\n return;\n }\n case PlaybackCommandType.Emit: {\n if (command.payload === undefined) {\n this.eventBus.emit(command.event as any);\n } else {\n this.eventBus.emit(command.event as any, command.payload);\n }\n return;\n }\n case PlaybackCommandType.RenderFrame: {\n return this.renderCurrentFrame(command.timeUs, {\n immediate: command.immediate,\n relativeTimeUs: command.relativeTimeUs,\n });\n }\n case PlaybackCommandType.MaybeRenderKeyframePreview: {\n return this.orchestrator.tryRenderKeyframe(command.timeUs).then((keyframeTimeUs) => {\n if (!this.isCurrentToken(token)) return;\n if (keyframeTimeUs === null) return;\n return this.orchestrator\n .getRenderState(command.timeUs, {\n immediate: true,\n relativeTimeUs: keyframeTimeUs,\n })\n .then((keyframeRenderState) => {\n if (!this.isCurrentToken(token)) return;\n if (!keyframeRenderState) return;\n return this.compose(command.timeUs, keyframeRenderState);\n });\n });\n }\n case PlaybackCommandType.EnsureAudio: {\n return this.audioSession.ensureAudioForTime(command.timeUs, {\n immediate: command.immediate,\n });\n }\n case PlaybackCommandType.GetFrame: {\n return this.orchestrator\n .getFrame(command.timeUs, {\n immediate: command.immediate,\n preheat: command.preheat,\n })\n .then(() => undefined);\n }\n case PlaybackCommandType.StartAudioPlayback: {\n return this.audioSession.startPlayback(command.timeUs, this.audioContext);\n }\n case PlaybackCommandType.StartRafLoop: {\n this.startPlaybackLoop(token);\n return;\n }\n }\n }\n\n private cancelRaf(): void {\n if (this.rafId !== null) {\n cancelAnimationFrame(this.rafId);\n this.rafId = null;\n }\n }\n\n private isCurrentToken(token: OpToken): boolean {\n return token === this.fsm.snapshot.token;\n }\n\n private startPlaybackLoop(token: OpToken): void {\n this.rafId = requestAnimationFrame(() => {\n void this.onRafTick(token);\n });\n }\n\n private async onRafTick(token: OpToken): Promise<void> {\n if (!this.isCurrentToken(token) || this.fsm.snapshot.state !== PlaybackState.Playing) {\n return;\n }\n\n const candidateTimeUs =\n (this.audioContext.currentTime * 1_000_000 - this.startTimeUs) * this.playbackRate;\n this.dispatch({\n type: PlaybackActionType.ClockTick,\n candidateTimeUs,\n durationUs: this.duration,\n loop: this.loop,\n audioNowUs: this.audioContext.currentTime * 1_000_000,\n });\n\n if (!this.isCurrentToken(token) || this.fsm.snapshot.state !== PlaybackState.Playing) {\n return;\n }\n\n // Throttle audio scheduling.\n if (this.currentTimeUs - this.lastAudioScheduleTime >= this.AUDIO_SCHEDULE_INTERVAL) {\n await this.audioSession.scheduleAudio(this.currentTimeUs, this.audioContext);\n if (!this.isCurrentToken(token) || this.fsm.snapshot.state !== PlaybackState.Playing) return;\n this.lastAudioScheduleTime = this.currentTimeUs;\n }\n\n const renderState = await this.orchestrator.getRenderState(this.currentTimeUs, {\n immediate: true,\n });\n if (!this.isCurrentToken(token) || this.fsm.snapshot.state !== PlaybackState.Playing) {\n return;\n }\n\n if (!renderState) {\n this.dispatch({ type: PlaybackActionType.EnterBuffering, timeUs: this.currentTimeUs });\n return;\n }\n\n await this.compose(this.currentTimeUs, renderState);\n if (!this.isCurrentToken(token) || this.fsm.snapshot.state !== PlaybackState.Playing) return;\n\n this.updateFps();\n this.frameCount++;\n\n // Unified cache window update.\n this.orchestrator.cacheManager.setWindow(this.currentTimeUs);\n\n this.checkAndPreheatWindow();\n if (!this.isCurrentToken(token) || this.fsm.snapshot.state !== PlaybackState.Playing) return;\n\n this.startPlaybackLoop(token);\n }\n\n private updateFps(): void {\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\n private initWindow(timeUs: TimeUs): void {\n this.windowEnd = timeUs + this.WINDOW_DURATION;\n this.preheatInProgress = false;\n this.orchestrator.cacheManager.setWindow(timeUs);\n }\n\n private checkAndPreheatWindow(): void {\n if (this.preheatInProgress || this.fsm.snapshot.state !== PlaybackState.Playing) {\n return;\n }\n\n const distanceToWindowEnd = this.windowEnd - this.currentTimeUs;\n if (distanceToWindowEnd < 0) {\n this.initWindow(this.currentTimeUs);\n return;\n }\n\n if (distanceToWindowEnd > 0 && distanceToWindowEnd <= this.PREHEAT_DISTANCE) {\n void this.preheatNextWindow();\n }\n }\n\n async preheatNextWindow(): Promise<void> {\n if (this.preheatInProgress) return;\n\n this.preheatInProgress = true;\n try {\n const windowStart = this.currentTimeUs;\n const windowEnd = windowStart + this.WINDOW_DURATION;\n\n const clipsInWindow =\n this.orchestrator.compositionModel?.getClipsInRange(windowStart, windowEnd) ?? [];\n const preheatPromises: Promise<any>[] = [];\n\n for (const clip of clipsInWindow) {\n if (!isVideoClip(clip)) continue;\n\n const clipWindowStart = Math.max(0, windowStart - clip.startUs);\n const clipWindowEnd = Math.min(clip.durationUs, windowEnd - clip.startUs);\n if (clipWindowStart >= clipWindowEnd) continue;\n\n preheatPromises.push(\n this.orchestrator.preheatClipWindow(clip.id, clipWindowStart, clipWindowEnd, windowStart)\n );\n }\n\n // Non-blocking audio preheat.\n preheatPromises.push(this.audioSession.ensureAudioForTime(windowStart, { immediate: false }));\n\n await Promise.all(preheatPromises);\n this.windowEnd = windowEnd;\n } catch (error) {\n console.warn('[PlaybackController] Preheat failed:', error);\n } finally {\n this.preheatInProgress = false;\n }\n }\n\n private async renderCurrentFrame(\n timeUs: TimeUs,\n options: { immediate: boolean; relativeTimeUs?: TimeUs }\n ): Promise<void> {\n if (!this.videoComposer) {\n console.error('[PlaybackController] VideoComposer not initialized');\n return;\n }\n\n const renderState = await this.orchestrator.getRenderState(timeUs, {\n immediate: options.immediate,\n relativeTimeUs: options.relativeTimeUs,\n });\n\n if (!renderState) {\n return;\n }\n\n await this.compose(timeUs, renderState);\n }\n\n private async compose(\n timeUs: TimeUs,\n renderState: { layers: any[]; transition?: any }\n ): Promise<void> {\n if (!this.videoComposer) return;\n await this.videoComposer.composeFrame({\n timeUs,\n layers: renderState.layers,\n transition: renderState.transition,\n });\n }\n\n private clearCanvas(): void {\n const ctx = this.canvas.getContext('2d') as\n | CanvasRenderingContext2D\n | OffscreenCanvasRenderingContext2D\n | null;\n if (ctx && 'clearRect' in ctx) {\n ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);\n }\n }\n\n // ========= Cleanup / event handlers =========\n\n dispose(): void {\n this.stop();\n this.eventBus.off(MeframeEvent.CacheCover, this.onCacheCover);\n this.eventBus.off(MeframeEvent.ModelSet, this.onModelSet);\n if (this.videoComposer) {\n this.videoComposer.dispose();\n this.videoComposer = null;\n }\n }\n\n private onCacheCover = (): void => {\n if (this.fsm.snapshot.state === PlaybackState.Idle && this.currentTimeUs === 0) {\n void this.renderCurrentFrame(0, { immediate: false });\n }\n };\n\n private onModelSet = (): void => {\n if (!this.videoComposer || !this.orchestrator.compositionModel) return;\n\n const model = this.orchestrator.compositionModel;\n this.videoComposer.updateConfig({\n width: model.renderConfig?.width || 720,\n height: model.renderConfig?.height || 1280,\n fps: model.fps || 30,\n backgroundColor: model.renderConfig?.backgroundColor || '#000',\n });\n\n // Best-effort background preheat.\n void this.audioSession.ensureAudioForTime(this.currentTimeUs, { immediate: false });\n void this.renderCurrentFrame(this.currentTimeUs, { immediate: false });\n };\n\n private setupEventListeners(): void {\n this.eventBus.on(MeframeEvent.CacheCover, this.onCacheCover);\n this.eventBus.on(MeframeEvent.ModelSet, this.onModelSet);\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 PlaybackOptions,\n IEventBus,\n PreviewHandle,\n TimeUs,\n} from './types';\nimport {\n PlaybackActionType,\n PlaybackCommandType,\n PlaybackState,\n type OpToken,\n type PlaybackAction,\n type PlaybackCommand,\n} from './types';\nimport { MeframeEvent } from '../event/events';\nimport type { GlobalAudioSession } from '../orchestrator/GlobalAudioSession';\nimport type { Orchestrator } from '../orchestrator';\nimport type { RequestMode } from '../orchestrator/types';\nimport { WaiterReplacedError } from '../utils/errors';\nimport { VideoComposer } from '../stages/compose/VideoComposer';\nimport { isVideoClip } from '../model/types';\n\nimport { PlaybackStateMachine } from './PlaybackStateMachine';\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 videoComposer: VideoComposer | null = null;\n\n // Playback time (external)\n currentTimeUs: TimeUs = 0;\n private playbackRate = 1.0;\n private volume = 1.0;\n private loop = false;\n\n // Time base\n private rafId: number | null = null;\n private startTimeUs: TimeUs = 0; // AudioContext timeline origin (microseconds)\n\n // Frame stats\n private frameCount = 0;\n private lastFrameTime = 0;\n private fps = 0;\n\n // Audio\n private audioContext: AudioContext;\n private audioSession: GlobalAudioSession;\n private lastAudioScheduleTime = 0;\n private readonly AUDIO_SCHEDULE_INTERVAL = 100_000; // 100ms\n\n // State machine\n private fsm = new PlaybackStateMachine();\n\n // Unified window management for both video and audio\n private windowEnd: TimeUs = 0;\n private readonly WINDOW_DURATION = 3_000_000; // 3s decode window\n private readonly AUDIO_READY_PROBE_WINDOW = 500_000; // 500ms: gate buffering only for near-future audio\n private readonly PREHEAT_DISTANCE = 1_000_000; // 1s preheat trigger distance\n private preheatInProgress = false;\n\n constructor(orchestrator: Orchestrator, eventBus: IEventBus, options: PlaybackOptions) {\n this.orchestrator = orchestrator;\n this.audioSession = orchestrator.audioSession;\n this.eventBus = eventBus;\n this.canvas = options.canvas;\n this.audioContext = new AudioContext();\n\n const model = orchestrator.compositionModel;\n const width = model?.renderConfig?.width || this.canvas.width || 720;\n const height = model?.renderConfig?.height || this.canvas.height || 1280;\n\n this.videoComposer = new VideoComposer({\n width,\n height,\n fps: model?.fps || 30,\n backgroundColor: model?.renderConfig?.backgroundColor || '#000',\n externalCanvas: this.canvas,\n });\n\n if (options.startUs !== undefined) {\n this.currentTimeUs = options.startUs;\n }\n if (options.rate !== undefined) {\n this.playbackRate = options.rate;\n }\n if (options.loop !== undefined) {\n this.loop = options.loop;\n }\n\n this.setupEventListeners();\n\n if (options.autoStart) {\n this.play();\n }\n }\n\n async renderCover(): Promise<void> {\n await this.renderCurrentFrame(0, { mode: 'blocking' });\n }\n\n // ========= Public API =========\n\n play(): void {\n this.dispatch({ type: PlaybackActionType.Play });\n }\n\n pause(): void {\n this.dispatch({ type: PlaybackActionType.Pause });\n }\n\n stop(): void {\n this.dispatch({ type: PlaybackActionType.Stop });\n }\n\n async seek(timeUs: TimeUs): Promise<void> {\n const { done } = this.dispatch({\n type: PlaybackActionType.Seek,\n timeUs,\n durationUs: this.duration,\n });\n await done;\n }\n\n setRate(rate: number): void {\n const currentTimeUs = this.currentTimeUs;\n this.playbackRate = rate;\n\n // Keep currentTimeUs stable; update the time base for AudioContext clock mapping.\n this.startTimeUs = this.audioContext.currentTime * 1_000_000 - currentTimeUs / rate;\n this.audioSession.setPlaybackRate(this.playbackRate);\n\n this.eventBus.emit(MeframeEvent.PlaybackRateChange, { rate });\n }\n\n setVolume(volume: number): void {\n this.volume = Math.max(0, Math.min(1, volume));\n this.audioSession.setVolume(this.volume);\n this.eventBus.emit(MeframeEvent.PlaybackVolumeChange, { volume: this.volume });\n }\n\n setMute(muted: boolean): void {\n if (muted) {\n this.audioSession.stopPlayback();\n return;\n }\n if (this.fsm.snapshot.state === PlaybackState.Playing) {\n void this.audioSession.startPlayback(this.currentTimeUs, this.audioContext);\n }\n }\n\n setLoop(loop: boolean): void {\n this.loop = loop;\n }\n\n get duration(): TimeUs {\n return this.orchestrator.compositionModel?.durationUs ?? 0;\n }\n\n get isPlaying(): boolean {\n return this.fsm.snapshot.state === PlaybackState.Playing;\n }\n\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 // ========= State machine wiring =========\n\n private dispatch(action: PlaybackAction): { token: OpToken; done: Promise<void> } {\n const { token, commands } = this.fsm.dispatch(action, { currentTimeUs: this.currentTimeUs });\n const done = this.executeCommands(commands, token);\n return { token, done };\n }\n\n private executeCommands(commands: PlaybackCommand[], token: OpToken): Promise<void> {\n const maybe = this.executeSeq(commands, token, 0);\n return maybe ?? Promise.resolve();\n }\n\n private executeSeq(\n commands: PlaybackCommand[],\n token: OpToken,\n startIndex: number\n ): Promise<void> | void {\n for (let i = startIndex; i < commands.length; i++) {\n if (!this.isCurrentToken(token)) return;\n const maybe = this.executeCommand(commands[i]!, token);\n if (maybe) {\n return maybe.then(() => {\n if (!this.isCurrentToken(token)) return;\n const cont = this.executeSeq(commands, token, i + 1);\n return cont ?? Promise.resolve();\n });\n }\n }\n }\n\n private executePar(commands: PlaybackCommand[], token: OpToken): Promise<any> | void {\n const promises: Promise<void>[] = [];\n for (const c of commands) {\n if (!this.isCurrentToken(token)) return;\n const maybe = this.executeCommand(c, token);\n if (maybe) promises.push(maybe);\n }\n if (promises.length === 0) return;\n return Promise.all(promises);\n }\n\n private executeCommand(command: PlaybackCommand, token: OpToken): Promise<any> | void {\n if (!this.isCurrentToken(token)) return;\n\n switch (command.type) {\n case PlaybackCommandType.Seq:\n return this.executeSeq(command.commands, token, 0);\n case PlaybackCommandType.Par:\n return this.executePar(command.commands, token);\n case PlaybackCommandType.Try: {\n const handleError = (error: unknown): Promise<void> | void => {\n if (!this.isCurrentToken(token)) return;\n if (command.ignoreWaiterReplacedError && error instanceof WaiterReplacedError) return;\n if (command.logPrefix) console.error(command.logPrefix, error);\n const onErrorDone = command.onError ? this.dispatch(command.onError).done : undefined;\n const normalizeError = (e: unknown): Error => {\n if (e instanceof Error) return e;\n return new Error(typeof e === 'string' ? e : JSON.stringify(e));\n };\n const emit = () => {\n if (command.emitPlaybackError) {\n const err = normalizeError(error);\n // PlaybackError: direct playback channel error for advanced consumers.\n this.eventBus.emit(MeframeEvent.PlaybackError, err);\n // Error: generic error channel expected by higher-level wrappers (e.g. @meframe/axii).\n this.eventBus.emit(MeframeEvent.Error, {\n source: 'playback',\n error: err,\n context: {\n command: command.logPrefix,\n onError: command.onError?.type,\n },\n recoverable: false,\n });\n }\n };\n if (onErrorDone) {\n return onErrorDone.then(() => {\n emit();\n });\n }\n emit();\n };\n\n try {\n const maybe = this.executeCommand(command.command, token);\n if (maybe) {\n return maybe.catch(handleError);\n }\n return;\n } catch (error) {\n return handleError(error) ?? Promise.resolve();\n }\n }\n case PlaybackCommandType.Dispatch:\n return this.dispatch(command.action).done;\n case PlaybackCommandType.SetTime: {\n this.currentTimeUs = command.timeUs;\n return;\n }\n case PlaybackCommandType.SetFrozenTime:\n case PlaybackCommandType.SetWantsPlay:\n case PlaybackCommandType.SetState: {\n // managed inside fsm\n return;\n }\n case PlaybackCommandType.CancelRaf: {\n this.cancelRaf();\n return;\n }\n case PlaybackCommandType.StopAudio: {\n this.audioSession.stopPlayback();\n return;\n }\n case PlaybackCommandType.ResetAudioPlaybackStates: {\n this.audioSession.resetPlaybackStates();\n return;\n }\n case PlaybackCommandType.ResetAudioSession: {\n this.audioSession.reset();\n return;\n }\n case PlaybackCommandType.ClearCanvas: {\n this.clearCanvas();\n return;\n }\n case PlaybackCommandType.SetLastAudioScheduleTime: {\n this.lastAudioScheduleTime = command.timeUs;\n return;\n }\n case PlaybackCommandType.SetStartTimeBase: {\n this.startTimeUs = command.startTimeUs;\n return;\n }\n case PlaybackCommandType.SyncTimeBaseToAudioClock: {\n this.startTimeUs =\n this.audioContext.currentTime * 1_000_000 - command.timeUs / this.playbackRate;\n return;\n }\n case PlaybackCommandType.InitWindow: {\n this.initWindow(command.timeUs);\n return;\n }\n case PlaybackCommandType.SetCacheWindow: {\n this.orchestrator.cacheManager.setWindow(command.timeUs);\n return;\n }\n case PlaybackCommandType.Emit: {\n if (command.payload === undefined) {\n this.eventBus.emit(command.event as any);\n } else {\n this.eventBus.emit(command.event as any, command.payload);\n }\n return;\n }\n case PlaybackCommandType.RenderFrame: {\n return this.renderCurrentFrame(command.timeUs, {\n mode: command.mode,\n relativeTimeUs: command.relativeTimeUs,\n });\n }\n case PlaybackCommandType.MaybeRenderKeyframePreview: {\n return this.orchestrator.tryRenderKeyframe(command.timeUs).then((keyframeTimeUs) => {\n if (!this.isCurrentToken(token)) return;\n if (keyframeTimeUs === null) return;\n return this.orchestrator\n .getRenderState(command.timeUs, {\n mode: 'probe',\n relativeTimeUs: keyframeTimeUs,\n })\n .then((keyframeRenderState) => {\n if (!this.isCurrentToken(token)) return;\n if (!keyframeRenderState) return;\n return this.compose(command.timeUs, keyframeRenderState);\n });\n });\n }\n case PlaybackCommandType.EnsureAudio: {\n return this.audioSession.ensureAudioForTime(command.timeUs, {\n mode: command.mode,\n });\n }\n case PlaybackCommandType.GetFrame: {\n return this.orchestrator.getFrame(command.timeUs, {\n mode: command.mode,\n preheat: command.preheat,\n });\n }\n case PlaybackCommandType.StartAudioPlayback: {\n return this.audioSession.startPlayback(command.timeUs, this.audioContext);\n }\n case PlaybackCommandType.ProbeStartReady: {\n const audioWindowEnd = Math.min(\n this.duration,\n command.timeUs + this.AUDIO_READY_PROBE_WINDOW\n );\n\n const audioReady = this.audioSession.isAudioResourceWindowReady(\n command.timeUs,\n audioWindowEnd\n );\n const videoReady = this.isVideoResourceReadyAtTime(command.timeUs);\n\n if (audioReady && videoReady) return;\n\n // Kick background preparation (best-effort).\n if (!audioReady) {\n void this.audioSession.ensureAudioForTime(command.timeUs, { mode: 'probe' });\n }\n if (!videoReady) {\n void this.orchestrator.getFrame(command.timeUs, { mode: 'probe' });\n }\n\n // Enter buffering and bump token to cancel the remaining start sequence.\n this.dispatch({\n type: PlaybackActionType.EnterBuffering,\n timeUs: command.timeUs,\n bumpToken: true,\n reason: 'startup',\n });\n return;\n }\n case PlaybackCommandType.StartRafLoop: {\n this.startPlaybackLoop(token);\n return;\n }\n }\n }\n\n private cancelRaf(): void {\n if (this.rafId !== null) {\n cancelAnimationFrame(this.rafId);\n this.rafId = null;\n }\n }\n\n private isCurrentToken(token: OpToken): boolean {\n return token === this.fsm.snapshot.token;\n }\n\n private startPlaybackLoop(token: OpToken): void {\n this.rafId = requestAnimationFrame(() => {\n void this.onRafTick(token);\n });\n }\n\n private async onRafTick(token: OpToken): Promise<void> {\n if (!this.isCurrentToken(token) || this.fsm.snapshot.state !== PlaybackState.Playing) {\n return;\n }\n\n const candidateTimeUs =\n (this.audioContext.currentTime * 1_000_000 - this.startTimeUs) * this.playbackRate;\n this.dispatch({\n type: PlaybackActionType.ClockTick,\n candidateTimeUs,\n durationUs: this.duration,\n loop: this.loop,\n audioNowUs: this.audioContext.currentTime * 1_000_000,\n });\n\n if (!this.isCurrentToken(token) || this.fsm.snapshot.state !== PlaybackState.Playing) {\n return;\n }\n\n // Audio probe: if the audio window isn't ready, enter buffering (freeze timeline)\n // and kick background audio preparation.\n const audioWindowEnd = Math.min(\n this.duration,\n this.currentTimeUs + this.AUDIO_READY_PROBE_WINDOW\n );\n if (!this.audioSession.isAudioResourceWindowReady(this.currentTimeUs, audioWindowEnd)) {\n void this.audioSession.ensureAudioForTime(this.currentTimeUs, { mode: 'probe' });\n this.dispatch({ type: PlaybackActionType.EnterBuffering, timeUs: this.currentTimeUs });\n return;\n }\n\n // Throttle audio scheduling.\n if (this.currentTimeUs - this.lastAudioScheduleTime >= this.AUDIO_SCHEDULE_INTERVAL) {\n await this.audioSession.scheduleAudio(this.currentTimeUs, this.audioContext);\n if (!this.isCurrentToken(token) || this.fsm.snapshot.state !== PlaybackState.Playing) return;\n this.lastAudioScheduleTime = this.currentTimeUs;\n }\n\n const renderState = await this.orchestrator.getRenderState(this.currentTimeUs, {\n mode: 'probe',\n });\n if (!this.isCurrentToken(token) || this.fsm.snapshot.state !== PlaybackState.Playing) {\n return;\n }\n\n if (!renderState) {\n this.dispatch({ type: PlaybackActionType.EnterBuffering, timeUs: this.currentTimeUs });\n return;\n }\n\n await this.compose(this.currentTimeUs, renderState);\n if (!this.isCurrentToken(token) || this.fsm.snapshot.state !== PlaybackState.Playing) return;\n\n this.updateFps();\n this.frameCount++;\n\n // Unified cache window update.\n this.orchestrator.cacheManager.setWindow(this.currentTimeUs);\n\n this.checkAndPreheatWindow();\n if (!this.isCurrentToken(token) || this.fsm.snapshot.state !== PlaybackState.Playing) return;\n\n this.startPlaybackLoop(token);\n }\n\n private updateFps(): void {\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\n private initWindow(timeUs: TimeUs): void {\n this.windowEnd = timeUs + this.WINDOW_DURATION;\n this.preheatInProgress = false;\n this.orchestrator.cacheManager.setWindow(timeUs);\n }\n\n private checkAndPreheatWindow(): void {\n if (this.preheatInProgress || this.fsm.snapshot.state !== PlaybackState.Playing) {\n return;\n }\n\n const distanceToWindowEnd = this.windowEnd - this.currentTimeUs;\n if (distanceToWindowEnd < 0) {\n this.initWindow(this.currentTimeUs);\n return;\n }\n\n if (distanceToWindowEnd > 0 && distanceToWindowEnd <= this.PREHEAT_DISTANCE) {\n void this.preheatNextWindow();\n }\n }\n\n async preheatNextWindow(): Promise<void> {\n if (this.preheatInProgress) return;\n\n this.preheatInProgress = true;\n try {\n const windowStart = this.currentTimeUs;\n const windowEnd = windowStart + this.WINDOW_DURATION;\n\n const clipsInWindow =\n this.orchestrator.compositionModel?.getClipsInRange(windowStart, windowEnd) ?? [];\n const preheatPromises: Promise<any>[] = [];\n\n for (const clip of clipsInWindow) {\n if (!isVideoClip(clip)) continue;\n\n const clipWindowStart = Math.max(0, windowStart - clip.startUs);\n const clipWindowEnd = Math.min(clip.durationUs, windowEnd - clip.startUs);\n if (clipWindowStart >= clipWindowEnd) continue;\n\n preheatPromises.push(\n this.orchestrator.preheatClipWindow(clip.id, clipWindowStart, clipWindowEnd, windowStart)\n );\n }\n\n // Non-blocking audio preheat.\n preheatPromises.push(this.audioSession.ensureAudioForTime(windowStart, { mode: 'blocking' }));\n\n await Promise.all(preheatPromises);\n this.windowEnd = windowEnd;\n } catch (error) {\n console.warn('[PlaybackController] Preheat failed:', error);\n } finally {\n this.preheatInProgress = false;\n }\n }\n\n private async renderCurrentFrame(\n timeUs: TimeUs,\n options: { mode: RequestMode; relativeTimeUs?: TimeUs }\n ): Promise<void> {\n if (!this.videoComposer) {\n console.error('[PlaybackController] VideoComposer not initialized');\n return;\n }\n\n const renderState = await this.orchestrator.getRenderState(timeUs, {\n mode: options.mode,\n relativeTimeUs: options.relativeTimeUs,\n });\n\n if (!renderState) {\n return;\n }\n\n await this.compose(timeUs, renderState);\n }\n\n private async compose(\n timeUs: TimeUs,\n renderState: { layers: any[]; transition?: any }\n ): Promise<void> {\n if (!this.videoComposer) return;\n await this.videoComposer.composeFrame({\n timeUs,\n layers: renderState.layers,\n transition: renderState.transition,\n });\n }\n\n private clearCanvas(): void {\n const ctx = this.canvas.getContext('2d') as\n | CanvasRenderingContext2D\n | OffscreenCanvasRenderingContext2D\n | null;\n if (ctx && 'clearRect' in ctx) {\n ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);\n }\n }\n\n // ========= Cleanup / event handlers =========\n\n dispose(): void {\n this.stop();\n this.eventBus.off(MeframeEvent.CacheCover, this.onCacheCover);\n this.eventBus.off(MeframeEvent.ModelSet, this.onModelSet);\n if (this.videoComposer) {\n this.videoComposer.dispose();\n this.videoComposer = null;\n }\n }\n\n private onCacheCover = (): void => {\n if (this.fsm.snapshot.state === PlaybackState.Idle && this.currentTimeUs === 0) {\n void this.renderCurrentFrame(0, { mode: 'blocking' });\n }\n };\n\n private onModelSet = (): void => {\n if (!this.videoComposer || !this.orchestrator.compositionModel) return;\n\n // Model switching cancels in-flight async chains, but must NOT enter buffering or reset time/state.\n // Buffering runs a long async sequence; if cancelled mid-way it can leave the FSM stuck.\n this.dispatch({ type: PlaybackActionType.ModelSet });\n\n const model = this.orchestrator.compositionModel;\n this.videoComposer.updateConfig({\n width: model.renderConfig?.width || 720,\n height: model.renderConfig?.height || 1280,\n fps: model.fps || 30,\n backgroundColor: model.renderConfig?.backgroundColor || '#000',\n });\n\n // Best-effort background preheat.\n void this.audioSession.ensureAudioForTime(this.currentTimeUs, { mode: 'blocking' });\n void this.renderCurrentFrame(this.currentTimeUs, { mode: 'blocking' });\n };\n\n private setupEventListeners(): void {\n this.eventBus.on(MeframeEvent.CacheCover, this.onCacheCover);\n this.eventBus.on(MeframeEvent.ModelSet, this.onModelSet);\n }\n\n private isVideoResourceReadyAtTime(timeUs: TimeUs): boolean {\n const model = this.orchestrator.compositionModel;\n if (!model) return true;\n const clip = model.getClipsAtTime(timeUs, model.mainTrackId)[0];\n if (!clip || !('resourceId' in clip) || typeof (clip as any).resourceId !== 'string')\n return true;\n const resourceId = (clip as any).resourceId as string;\n const resource = model.getResource(resourceId);\n return resource?.state === 'ready';\n }\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PlaybackStateMachine.d.ts","sourceRoot":"","sources":["../../src/controllers/PlaybackStateMachine.ts"],"names":[],"mappings":"AACA,OAAO,EAIL,KAAK,OAAO,EACZ,KAAK,cAAc,EACnB,KAAK,eAAe,EACpB,KAAK,uBAAuB,EAC5B,KAAK,MAAM,EACZ,MAAM,SAAS,CAAC;AAEjB,qBAAa,oBAAoB;IAC/B,OAAO,CAAC,KAAK,CAAqC;IAClD,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,YAAY,CAAuB;IAC3C,OAAO,CAAC,KAAK,CAAc;IAE3B,IAAI,QAAQ,IAAI,uBAAuB,CAOtC;IAED,QAAQ,CACN,MAAM,EAAE,cAAc,EACtB,GAAG,EAAE;QAAE,aAAa,EAAE,MAAM,CAAA;KAAE,GAC7B;QAAE,KAAK,EAAE,OAAO,CAAC;QAAC,QAAQ,EAAE,eAAe,EAAE,CAAA;KAAE;
|
|
1
|
+
{"version":3,"file":"PlaybackStateMachine.d.ts","sourceRoot":"","sources":["../../src/controllers/PlaybackStateMachine.ts"],"names":[],"mappings":"AACA,OAAO,EAIL,KAAK,OAAO,EACZ,KAAK,cAAc,EACnB,KAAK,eAAe,EACpB,KAAK,uBAAuB,EAC5B,KAAK,MAAM,EACZ,MAAM,SAAS,CAAC;AAEjB,qBAAa,oBAAoB;IAC/B,OAAO,CAAC,KAAK,CAAqC;IAClD,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,YAAY,CAAuB;IAC3C,OAAO,CAAC,KAAK,CAAc;IAE3B,IAAI,QAAQ,IAAI,uBAAuB,CAOtC;IAED,QAAQ,CACN,MAAM,EAAE,cAAc,EACtB,GAAG,EAAE;QAAE,aAAa,EAAE,MAAM,CAAA;KAAE,GAC7B;QAAE,KAAK,EAAE,OAAO,CAAC;QAAC,QAAQ,EAAE,eAAe,EAAE,CAAA;KAAE;CA0WnD"}
|
|
@@ -35,11 +35,24 @@ class PlaybackStateMachine {
|
|
|
35
35
|
commands.push({ type: PlaybackCommandType.SetTime, timeUs });
|
|
36
36
|
};
|
|
37
37
|
const clampTime = (timeUs, durationUs) => {
|
|
38
|
-
|
|
38
|
+
const maxTimeUs = durationUs > 0 ? durationUs - 1 : 0;
|
|
39
|
+
return Math.max(0, Math.min(timeUs, maxTimeUs));
|
|
39
40
|
};
|
|
40
41
|
switch (action.type) {
|
|
42
|
+
case PlaybackActionType.ModelSet: {
|
|
43
|
+
bumpToken();
|
|
44
|
+
commands.push({ type: PlaybackCommandType.CancelRaf });
|
|
45
|
+
commands.push({ type: PlaybackCommandType.StopAudio });
|
|
46
|
+
commands.push({ type: PlaybackCommandType.SetLastAudioScheduleTime, timeUs: 0 });
|
|
47
|
+
setFrozenTime(null);
|
|
48
|
+
if (this.state === PlaybackState.Playing || this.state === PlaybackState.Buffering || this.state === PlaybackState.Seeking) {
|
|
49
|
+
setState(PlaybackState.Paused);
|
|
50
|
+
}
|
|
51
|
+
return { token: this.token, commands };
|
|
52
|
+
}
|
|
41
53
|
case PlaybackActionType.Play: {
|
|
42
54
|
const token = bumpToken();
|
|
55
|
+
const prevState = this.state;
|
|
43
56
|
setWantsPlay(true);
|
|
44
57
|
if (this.state === PlaybackState.Ended) {
|
|
45
58
|
setTime(0);
|
|
@@ -51,7 +64,7 @@ class PlaybackStateMachine {
|
|
|
51
64
|
setFrozenTime(null);
|
|
52
65
|
commands.push({ type: PlaybackCommandType.SetLastAudioScheduleTime, timeUs: 0 });
|
|
53
66
|
commands.push({ type: PlaybackCommandType.CancelRaf });
|
|
54
|
-
const fallbackState =
|
|
67
|
+
const fallbackState = prevState === PlaybackState.Idle || prevState === PlaybackState.Ended ? PlaybackState.Idle : PlaybackState.Paused;
|
|
55
68
|
commands.push({
|
|
56
69
|
type: PlaybackCommandType.Try,
|
|
57
70
|
logPrefix: "[PlaybackController] Failed to start playback:",
|
|
@@ -60,10 +73,11 @@ class PlaybackStateMachine {
|
|
|
60
73
|
command: {
|
|
61
74
|
type: PlaybackCommandType.Seq,
|
|
62
75
|
commands: [
|
|
76
|
+
{ type: PlaybackCommandType.ProbeStartReady, timeUs: ctx.currentTimeUs },
|
|
63
77
|
{
|
|
64
78
|
type: PlaybackCommandType.RenderFrame,
|
|
65
79
|
timeUs: ctx.currentTimeUs,
|
|
66
|
-
|
|
80
|
+
mode: "blocking"
|
|
67
81
|
},
|
|
68
82
|
{ type: PlaybackCommandType.InitWindow, timeUs: ctx.currentTimeUs },
|
|
69
83
|
{ type: PlaybackCommandType.StartAudioPlayback, timeUs: ctx.currentTimeUs },
|
|
@@ -127,17 +141,17 @@ class PlaybackStateMachine {
|
|
|
127
141
|
{
|
|
128
142
|
type: PlaybackCommandType.Par,
|
|
129
143
|
commands: [
|
|
130
|
-
{ type: PlaybackCommandType.EnsureAudio, timeUs: toUs,
|
|
144
|
+
{ type: PlaybackCommandType.EnsureAudio, timeUs: toUs, mode: "blocking" },
|
|
131
145
|
{
|
|
132
146
|
type: PlaybackCommandType.GetFrame,
|
|
133
147
|
timeUs: toUs,
|
|
134
|
-
|
|
148
|
+
mode: "blocking",
|
|
135
149
|
preheat: true
|
|
136
150
|
}
|
|
137
151
|
]
|
|
138
152
|
},
|
|
139
153
|
{ type: PlaybackCommandType.InitWindow, timeUs: toUs },
|
|
140
|
-
{ type: PlaybackCommandType.RenderFrame, timeUs: toUs,
|
|
154
|
+
{ type: PlaybackCommandType.RenderFrame, timeUs: toUs, mode: "blocking" },
|
|
141
155
|
{
|
|
142
156
|
type: PlaybackCommandType.Dispatch,
|
|
143
157
|
action: { type: PlaybackActionType.SeekResolved, previousState }
|
|
@@ -148,6 +162,10 @@ class PlaybackStateMachine {
|
|
|
148
162
|
return { token, commands };
|
|
149
163
|
}
|
|
150
164
|
case PlaybackActionType.EnterBuffering: {
|
|
165
|
+
const shouldBump = action.bumpToken ?? false;
|
|
166
|
+
if (shouldBump) {
|
|
167
|
+
bumpToken();
|
|
168
|
+
}
|
|
151
169
|
if (this.state !== PlaybackState.Playing) {
|
|
152
170
|
return { token: this.token, commands };
|
|
153
171
|
}
|
|
@@ -169,11 +187,11 @@ class PlaybackStateMachine {
|
|
|
169
187
|
{
|
|
170
188
|
type: PlaybackCommandType.Par,
|
|
171
189
|
commands: [
|
|
172
|
-
{ type: PlaybackCommandType.GetFrame, timeUs: action.timeUs,
|
|
190
|
+
{ type: PlaybackCommandType.GetFrame, timeUs: action.timeUs, mode: "blocking" },
|
|
173
191
|
{
|
|
174
192
|
type: PlaybackCommandType.EnsureAudio,
|
|
175
193
|
timeUs: action.timeUs,
|
|
176
|
-
|
|
194
|
+
mode: "blocking"
|
|
177
195
|
}
|
|
178
196
|
]
|
|
179
197
|
},
|
|
@@ -201,7 +219,7 @@ class PlaybackStateMachine {
|
|
|
201
219
|
command: {
|
|
202
220
|
type: PlaybackCommandType.Seq,
|
|
203
221
|
commands: [
|
|
204
|
-
{ type: PlaybackCommandType.RenderFrame, timeUs: action.timeUs,
|
|
222
|
+
{ type: PlaybackCommandType.RenderFrame, timeUs: action.timeUs, mode: "blocking" },
|
|
205
223
|
{ type: PlaybackCommandType.InitWindow, timeUs: action.timeUs },
|
|
206
224
|
{ type: PlaybackCommandType.StartAudioPlayback, timeUs: action.timeUs },
|
|
207
225
|
{ type: PlaybackCommandType.SyncTimeBaseToAudioClock, timeUs: action.timeUs },
|
|
@@ -238,7 +256,7 @@ class PlaybackStateMachine {
|
|
|
238
256
|
{
|
|
239
257
|
type: PlaybackCommandType.RenderFrame,
|
|
240
258
|
timeUs: ctx.currentTimeUs,
|
|
241
|
-
|
|
259
|
+
mode: "blocking"
|
|
242
260
|
},
|
|
243
261
|
{ type: PlaybackCommandType.InitWindow, timeUs: ctx.currentTimeUs },
|
|
244
262
|
{ type: PlaybackCommandType.StartAudioPlayback, timeUs: ctx.currentTimeUs },
|
|
@@ -256,7 +274,12 @@ class PlaybackStateMachine {
|
|
|
256
274
|
return { token: this.token, commands };
|
|
257
275
|
}
|
|
258
276
|
case PlaybackActionType.StartFailed: {
|
|
277
|
+
setWantsPlay(false);
|
|
278
|
+
setFrozenTime(null);
|
|
259
279
|
setState(action.fallbackState);
|
|
280
|
+
commands.push({ type: PlaybackCommandType.CancelRaf });
|
|
281
|
+
commands.push({ type: PlaybackCommandType.StopAudio });
|
|
282
|
+
commands.push({ type: PlaybackCommandType.SetLastAudioScheduleTime, timeUs: 0 });
|
|
260
283
|
return { token: this.token, commands };
|
|
261
284
|
}
|
|
262
285
|
case PlaybackActionType.ClockTick: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PlaybackStateMachine.js","sources":["../../src/controllers/PlaybackStateMachine.ts"],"sourcesContent":["import { MeframeEvent } from '../event/events';\nimport {\n PlaybackActionType,\n PlaybackCommandType,\n PlaybackState,\n type OpToken,\n type PlaybackAction,\n type PlaybackCommand,\n type PlaybackMachineSnapshot,\n type TimeUs,\n} from './types';\n\nexport class PlaybackStateMachine {\n private state: PlaybackState = PlaybackState.Idle;\n private wantsPlay = false;\n private frozenTimeUs: TimeUs | null = null;\n private token: OpToken = 0;\n\n get snapshot(): PlaybackMachineSnapshot {\n return {\n state: this.state,\n wantsPlay: this.wantsPlay,\n frozenTimeUs: this.frozenTimeUs,\n token: this.token,\n };\n }\n\n dispatch(\n action: PlaybackAction,\n ctx: { currentTimeUs: TimeUs }\n ): { token: OpToken; commands: PlaybackCommand[] } {\n const commands: PlaybackCommand[] = [];\n\n const bumpToken = () => {\n this.token++;\n return this.token;\n };\n\n const setState = (state: PlaybackState) => {\n this.state = state;\n commands.push({ type: PlaybackCommandType.SetState, state });\n };\n\n const setWantsPlay = (wantsPlay: boolean) => {\n this.wantsPlay = wantsPlay;\n commands.push({ type: PlaybackCommandType.SetWantsPlay, wantsPlay });\n };\n\n const setFrozenTime = (timeUs: TimeUs | null) => {\n this.frozenTimeUs = timeUs;\n commands.push({ type: PlaybackCommandType.SetFrozenTime, timeUs });\n };\n\n const setTime = (timeUs: TimeUs) => {\n commands.push({ type: PlaybackCommandType.SetTime, timeUs });\n };\n\n const clampTime = (timeUs: TimeUs, durationUs: TimeUs) => {\n return Math.max(0, Math.min(timeUs, durationUs));\n };\n\n switch (action.type) {\n case PlaybackActionType.Play: {\n const token = bumpToken();\n setWantsPlay(true);\n\n if (this.state === PlaybackState.Ended) {\n setTime(0);\n }\n\n if (this.state === PlaybackState.Playing) {\n return { token, commands };\n }\n\n // Set playing immediately; failures will rollback via START_FAILED.\n setState(PlaybackState.Playing);\n setFrozenTime(null);\n commands.push({ type: PlaybackCommandType.SetLastAudioScheduleTime, timeUs: 0 });\n commands.push({ type: PlaybackCommandType.CancelRaf });\n\n const fallbackState =\n this.state === PlaybackState.Idle || this.state === PlaybackState.Ended\n ? PlaybackState.Idle\n : PlaybackState.Paused;\n\n commands.push({\n type: PlaybackCommandType.Try,\n logPrefix: '[PlaybackController] Failed to start playback:',\n emitPlaybackError: true,\n onError: { type: PlaybackActionType.StartFailed, fallbackState },\n command: {\n type: PlaybackCommandType.Seq,\n commands: [\n {\n type: PlaybackCommandType.RenderFrame,\n timeUs: ctx.currentTimeUs,\n immediate: false,\n },\n { type: PlaybackCommandType.InitWindow, timeUs: ctx.currentTimeUs },\n { type: PlaybackCommandType.StartAudioPlayback, timeUs: ctx.currentTimeUs },\n { type: PlaybackCommandType.SyncTimeBaseToAudioClock, timeUs: ctx.currentTimeUs },\n { type: PlaybackCommandType.StartRafLoop },\n { type: PlaybackCommandType.Emit, event: MeframeEvent.PlaybackPlay },\n ],\n },\n });\n return { token, commands };\n }\n\n case PlaybackActionType.Pause: {\n bumpToken();\n const prev = this.state;\n setWantsPlay(false);\n setFrozenTime(null);\n commands.push({ type: PlaybackCommandType.CancelRaf });\n commands.push({ type: PlaybackCommandType.StopAudio });\n\n if (prev !== PlaybackState.Idle && prev !== PlaybackState.Ended) {\n setState(PlaybackState.Paused);\n }\n\n if (\n prev === PlaybackState.Playing ||\n prev === PlaybackState.Buffering ||\n prev === PlaybackState.Seeking\n ) {\n commands.push({ type: PlaybackCommandType.Emit, event: MeframeEvent.PlaybackPause });\n }\n\n return { token: this.token, commands };\n }\n\n case PlaybackActionType.Stop: {\n bumpToken();\n setWantsPlay(false);\n setFrozenTime(null);\n setState(PlaybackState.Idle);\n setTime(0);\n\n commands.push({ type: PlaybackCommandType.CancelRaf });\n commands.push({ type: PlaybackCommandType.StopAudio });\n commands.push({ type: PlaybackCommandType.ClearCanvas });\n commands.push({ type: PlaybackCommandType.ResetAudioSession });\n commands.push({ type: PlaybackCommandType.ResetAudioPlaybackStates });\n commands.push({ type: PlaybackCommandType.SetLastAudioScheduleTime, timeUs: 0 });\n commands.push({ type: PlaybackCommandType.Emit, event: MeframeEvent.PlaybackStop });\n\n return { token: this.token, commands };\n }\n\n case PlaybackActionType.Seek: {\n const token = bumpToken();\n const previousState = this.state;\n const toUs = clampTime(action.timeUs, action.durationUs);\n\n setTime(toUs);\n setFrozenTime(toUs);\n setState(PlaybackState.Seeking);\n commands.push({ type: PlaybackCommandType.CancelRaf });\n commands.push({ type: PlaybackCommandType.StopAudio });\n commands.push({ type: PlaybackCommandType.SetLastAudioScheduleTime, timeUs: 0 });\n commands.push({\n type: PlaybackCommandType.Try,\n logPrefix: '[PlaybackController] Seek error:',\n emitPlaybackError: true,\n onError: { type: PlaybackActionType.Pause },\n command: {\n type: PlaybackCommandType.Seq,\n commands: [\n { type: PlaybackCommandType.MaybeRenderKeyframePreview, timeUs: toUs },\n {\n type: PlaybackCommandType.Par,\n commands: [\n { type: PlaybackCommandType.EnsureAudio, timeUs: toUs, immediate: false },\n {\n type: PlaybackCommandType.GetFrame,\n timeUs: toUs,\n immediate: false,\n preheat: true,\n },\n ],\n },\n { type: PlaybackCommandType.InitWindow, timeUs: toUs },\n { type: PlaybackCommandType.RenderFrame, timeUs: toUs, immediate: false },\n {\n type: PlaybackCommandType.Dispatch,\n action: { type: PlaybackActionType.SeekResolved, previousState },\n },\n ],\n },\n });\n\n return { token, commands };\n }\n\n case PlaybackActionType.EnterBuffering: {\n if (this.state !== PlaybackState.Playing) {\n return { token: this.token, commands };\n }\n // Do NOT bump token; buffering is part of the current playback operation.\n setFrozenTime(action.timeUs);\n setState(PlaybackState.Buffering);\n commands.push({ type: PlaybackCommandType.Emit, event: MeframeEvent.PlaybackBuffering });\n commands.push({ type: PlaybackCommandType.CancelRaf });\n commands.push({ type: PlaybackCommandType.StopAudio });\n commands.push({\n type: PlaybackCommandType.Try,\n logPrefix: '[PlaybackController] Buffering error:',\n emitPlaybackError: true,\n ignoreWaiterReplacedError: true,\n onError: { type: PlaybackActionType.Pause },\n command: {\n type: PlaybackCommandType.Seq,\n commands: [\n { type: PlaybackCommandType.SetCacheWindow, timeUs: action.timeUs },\n {\n type: PlaybackCommandType.Par,\n commands: [\n { type: PlaybackCommandType.GetFrame, timeUs: action.timeUs, immediate: false },\n {\n type: PlaybackCommandType.EnsureAudio,\n timeUs: action.timeUs,\n immediate: false,\n },\n ],\n },\n {\n type: PlaybackCommandType.Dispatch,\n action: { type: PlaybackActionType.BufferingResolved, timeUs: action.timeUs },\n },\n ],\n },\n });\n return { token: this.token, commands };\n }\n\n case PlaybackActionType.BufferingResolved: {\n if (this.state !== PlaybackState.Buffering) {\n return { token: this.token, commands };\n }\n setFrozenTime(null);\n if (this.wantsPlay) {\n setState(PlaybackState.Playing);\n commands.push({\n type: PlaybackCommandType.Try,\n logPrefix: '[PlaybackController] Failed to start playback:',\n emitPlaybackError: true,\n onError: { type: PlaybackActionType.StartFailed, fallbackState: PlaybackState.Paused },\n command: {\n type: PlaybackCommandType.Seq,\n commands: [\n { type: PlaybackCommandType.RenderFrame, timeUs: action.timeUs, immediate: false },\n { type: PlaybackCommandType.InitWindow, timeUs: action.timeUs },\n { type: PlaybackCommandType.StartAudioPlayback, timeUs: action.timeUs },\n { type: PlaybackCommandType.SyncTimeBaseToAudioClock, timeUs: action.timeUs },\n { type: PlaybackCommandType.StartRafLoop },\n { type: PlaybackCommandType.Emit, event: MeframeEvent.PlaybackPlay },\n ],\n },\n });\n } else {\n setState(PlaybackState.Paused);\n }\n return { token: this.token, commands };\n }\n\n case PlaybackActionType.SeekResolved: {\n if (this.state !== PlaybackState.Seeking) {\n return { token: this.token, commands };\n }\n setFrozenTime(null);\n commands.push({\n type: PlaybackCommandType.Emit,\n event: MeframeEvent.PlaybackSeek,\n payload: { timeUs: ctx.currentTimeUs },\n });\n if (this.wantsPlay) {\n setState(PlaybackState.Playing);\n commands.push({\n type: PlaybackCommandType.Try,\n logPrefix: '[PlaybackController] Failed to start playback:',\n emitPlaybackError: true,\n onError: { type: PlaybackActionType.StartFailed, fallbackState: PlaybackState.Paused },\n command: {\n type: PlaybackCommandType.Seq,\n commands: [\n {\n type: PlaybackCommandType.RenderFrame,\n timeUs: ctx.currentTimeUs,\n immediate: false,\n },\n { type: PlaybackCommandType.InitWindow, timeUs: ctx.currentTimeUs },\n { type: PlaybackCommandType.StartAudioPlayback, timeUs: ctx.currentTimeUs },\n { type: PlaybackCommandType.SyncTimeBaseToAudioClock, timeUs: ctx.currentTimeUs },\n { type: PlaybackCommandType.StartRafLoop },\n { type: PlaybackCommandType.Emit, event: MeframeEvent.PlaybackPlay },\n ],\n },\n });\n } else {\n setState(\n action.previousState === PlaybackState.Idle ? PlaybackState.Idle : PlaybackState.Paused\n );\n }\n return { token: this.token, commands };\n }\n\n case PlaybackActionType.StartFailed: {\n // Only meaningful if we were trying to play.\n setState(action.fallbackState);\n return { token: this.token, commands };\n }\n\n case PlaybackActionType.ClockTick: {\n if (this.state !== PlaybackState.Playing) {\n return { token: this.token, commands };\n }\n if (this.frozenTimeUs !== null) {\n return { token: this.token, commands };\n }\n\n const t = action.candidateTimeUs;\n\n if (t >= action.durationUs) {\n if (action.loop) {\n setTime(0);\n commands.push({\n type: PlaybackCommandType.SetStartTimeBase,\n startTimeUs: action.audioNowUs,\n });\n commands.push({ type: PlaybackCommandType.ResetAudioPlaybackStates });\n commands.push({ type: PlaybackCommandType.SetLastAudioScheduleTime, timeUs: 0 });\n commands.push({ type: PlaybackCommandType.InitWindow, timeUs: 0 });\n } else {\n setWantsPlay(false);\n setState(PlaybackState.Ended);\n commands.push({ type: PlaybackCommandType.CancelRaf });\n commands.push({ type: PlaybackCommandType.StopAudio });\n setTime(0);\n commands.push({\n type: PlaybackCommandType.Emit,\n event: MeframeEvent.PlaybackEnded,\n payload: { timeUs: action.durationUs },\n });\n }\n return { token: this.token, commands };\n }\n\n setTime(t);\n commands.push({\n type: PlaybackCommandType.Emit,\n event: MeframeEvent.PlaybackTimeUpdate,\n payload: { timeUs: t },\n });\n return { token: this.token, commands };\n }\n }\n }\n}\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"PlaybackStateMachine.js","sources":["../../src/controllers/PlaybackStateMachine.ts"],"sourcesContent":["import { MeframeEvent } from '../event/events';\nimport {\n PlaybackActionType,\n PlaybackCommandType,\n PlaybackState,\n type OpToken,\n type PlaybackAction,\n type PlaybackCommand,\n type PlaybackMachineSnapshot,\n type TimeUs,\n} from './types';\n\nexport class PlaybackStateMachine {\n private state: PlaybackState = PlaybackState.Idle;\n private wantsPlay = false;\n private frozenTimeUs: TimeUs | null = null;\n private token: OpToken = 0;\n\n get snapshot(): PlaybackMachineSnapshot {\n return {\n state: this.state,\n wantsPlay: this.wantsPlay,\n frozenTimeUs: this.frozenTimeUs,\n token: this.token,\n };\n }\n\n dispatch(\n action: PlaybackAction,\n ctx: { currentTimeUs: TimeUs }\n ): { token: OpToken; commands: PlaybackCommand[] } {\n const commands: PlaybackCommand[] = [];\n\n const bumpToken = () => {\n this.token++;\n return this.token;\n };\n\n const setState = (state: PlaybackState) => {\n this.state = state;\n commands.push({ type: PlaybackCommandType.SetState, state });\n };\n\n const setWantsPlay = (wantsPlay: boolean) => {\n this.wantsPlay = wantsPlay;\n commands.push({ type: PlaybackCommandType.SetWantsPlay, wantsPlay });\n };\n\n const setFrozenTime = (timeUs: TimeUs | null) => {\n this.frozenTimeUs = timeUs;\n commands.push({ type: PlaybackCommandType.SetFrozenTime, timeUs });\n };\n\n const setTime = (timeUs: TimeUs) => {\n commands.push({ type: PlaybackCommandType.SetTime, timeUs });\n };\n\n const clampTime = (timeUs: TimeUs, durationUs: TimeUs) => {\n // Timeline point queries are defined on [0, durationUs).\n // Seeking to durationUs would have no active clip and can cause persistent buffering.\n const maxTimeUs = durationUs > 0 ? durationUs - 1 : 0;\n return Math.max(0, Math.min(timeUs, maxTimeUs));\n };\n\n switch (action.type) {\n case PlaybackActionType.ModelSet: {\n bumpToken();\n // Cancel any in-flight async chains and leave the machine in a stable state.\n // Important: do NOT enter buffering here; buffering runs a long async sequence and can be\n // cancelled mid-way, leaving the state stuck in Buffering/Seeking.\n commands.push({ type: PlaybackCommandType.CancelRaf });\n commands.push({ type: PlaybackCommandType.StopAudio });\n commands.push({ type: PlaybackCommandType.SetLastAudioScheduleTime, timeUs: 0 });\n setFrozenTime(null);\n\n if (\n this.state === PlaybackState.Playing ||\n this.state === PlaybackState.Buffering ||\n this.state === PlaybackState.Seeking\n ) {\n setState(PlaybackState.Paused);\n }\n return { token: this.token, commands };\n }\n\n case PlaybackActionType.Play: {\n const token = bumpToken();\n const prevState = this.state;\n setWantsPlay(true);\n\n if (this.state === PlaybackState.Ended) {\n setTime(0);\n }\n\n if (this.state === PlaybackState.Playing) {\n return { token, commands };\n }\n\n // Set playing immediately; failures will rollback via START_FAILED.\n setState(PlaybackState.Playing);\n setFrozenTime(null);\n commands.push({ type: PlaybackCommandType.SetLastAudioScheduleTime, timeUs: 0 });\n commands.push({ type: PlaybackCommandType.CancelRaf });\n\n const fallbackState =\n prevState === PlaybackState.Idle || prevState === PlaybackState.Ended\n ? PlaybackState.Idle\n : PlaybackState.Paused;\n\n commands.push({\n type: PlaybackCommandType.Try,\n logPrefix: '[PlaybackController] Failed to start playback:',\n emitPlaybackError: true,\n onError: { type: PlaybackActionType.StartFailed, fallbackState },\n command: {\n type: PlaybackCommandType.Seq,\n commands: [\n { type: PlaybackCommandType.ProbeStartReady, timeUs: ctx.currentTimeUs },\n {\n type: PlaybackCommandType.RenderFrame,\n timeUs: ctx.currentTimeUs,\n mode: 'blocking',\n },\n { type: PlaybackCommandType.InitWindow, timeUs: ctx.currentTimeUs },\n { type: PlaybackCommandType.StartAudioPlayback, timeUs: ctx.currentTimeUs },\n { type: PlaybackCommandType.SyncTimeBaseToAudioClock, timeUs: ctx.currentTimeUs },\n { type: PlaybackCommandType.StartRafLoop },\n { type: PlaybackCommandType.Emit, event: MeframeEvent.PlaybackPlay },\n ],\n },\n });\n return { token, commands };\n }\n\n case PlaybackActionType.Pause: {\n bumpToken();\n const prev = this.state;\n setWantsPlay(false);\n setFrozenTime(null);\n commands.push({ type: PlaybackCommandType.CancelRaf });\n commands.push({ type: PlaybackCommandType.StopAudio });\n\n if (prev !== PlaybackState.Idle && prev !== PlaybackState.Ended) {\n setState(PlaybackState.Paused);\n }\n\n if (\n prev === PlaybackState.Playing ||\n prev === PlaybackState.Buffering ||\n prev === PlaybackState.Seeking\n ) {\n commands.push({ type: PlaybackCommandType.Emit, event: MeframeEvent.PlaybackPause });\n }\n\n return { token: this.token, commands };\n }\n\n case PlaybackActionType.Stop: {\n bumpToken();\n setWantsPlay(false);\n setFrozenTime(null);\n setState(PlaybackState.Idle);\n setTime(0);\n\n commands.push({ type: PlaybackCommandType.CancelRaf });\n commands.push({ type: PlaybackCommandType.StopAudio });\n commands.push({ type: PlaybackCommandType.ClearCanvas });\n commands.push({ type: PlaybackCommandType.ResetAudioSession });\n commands.push({ type: PlaybackCommandType.ResetAudioPlaybackStates });\n commands.push({ type: PlaybackCommandType.SetLastAudioScheduleTime, timeUs: 0 });\n commands.push({ type: PlaybackCommandType.Emit, event: MeframeEvent.PlaybackStop });\n\n return { token: this.token, commands };\n }\n\n case PlaybackActionType.Seek: {\n const token = bumpToken();\n const previousState = this.state;\n const toUs = clampTime(action.timeUs, action.durationUs);\n\n setTime(toUs);\n setFrozenTime(toUs);\n setState(PlaybackState.Seeking);\n commands.push({ type: PlaybackCommandType.CancelRaf });\n commands.push({ type: PlaybackCommandType.StopAudio });\n commands.push({ type: PlaybackCommandType.SetLastAudioScheduleTime, timeUs: 0 });\n commands.push({\n type: PlaybackCommandType.Try,\n logPrefix: '[PlaybackController] Seek error:',\n emitPlaybackError: true,\n onError: { type: PlaybackActionType.Pause },\n command: {\n type: PlaybackCommandType.Seq,\n commands: [\n { type: PlaybackCommandType.MaybeRenderKeyframePreview, timeUs: toUs },\n {\n type: PlaybackCommandType.Par,\n commands: [\n { type: PlaybackCommandType.EnsureAudio, timeUs: toUs, mode: 'blocking' },\n {\n type: PlaybackCommandType.GetFrame,\n timeUs: toUs,\n mode: 'blocking',\n preheat: true,\n },\n ],\n },\n { type: PlaybackCommandType.InitWindow, timeUs: toUs },\n { type: PlaybackCommandType.RenderFrame, timeUs: toUs, mode: 'blocking' },\n {\n type: PlaybackCommandType.Dispatch,\n action: { type: PlaybackActionType.SeekResolved, previousState },\n },\n ],\n },\n });\n\n return { token, commands };\n }\n\n case PlaybackActionType.EnterBuffering: {\n const shouldBump = action.bumpToken ?? false;\n if (shouldBump) {\n bumpToken();\n }\n if (this.state !== PlaybackState.Playing) {\n return { token: this.token, commands };\n }\n // Do NOT bump token; buffering is part of the current playback operation.\n setFrozenTime(action.timeUs);\n setState(PlaybackState.Buffering);\n commands.push({ type: PlaybackCommandType.Emit, event: MeframeEvent.PlaybackBuffering });\n commands.push({ type: PlaybackCommandType.CancelRaf });\n commands.push({ type: PlaybackCommandType.StopAudio });\n commands.push({\n type: PlaybackCommandType.Try,\n logPrefix: '[PlaybackController] Buffering error:',\n emitPlaybackError: true,\n ignoreWaiterReplacedError: true,\n onError: { type: PlaybackActionType.Pause },\n command: {\n type: PlaybackCommandType.Seq,\n commands: [\n { type: PlaybackCommandType.SetCacheWindow, timeUs: action.timeUs },\n {\n type: PlaybackCommandType.Par,\n commands: [\n { type: PlaybackCommandType.GetFrame, timeUs: action.timeUs, mode: 'blocking' },\n {\n type: PlaybackCommandType.EnsureAudio,\n timeUs: action.timeUs,\n mode: 'blocking',\n },\n ],\n },\n {\n type: PlaybackCommandType.Dispatch,\n action: { type: PlaybackActionType.BufferingResolved, timeUs: action.timeUs },\n },\n ],\n },\n });\n return { token: this.token, commands };\n }\n\n case PlaybackActionType.BufferingResolved: {\n if (this.state !== PlaybackState.Buffering) {\n return { token: this.token, commands };\n }\n setFrozenTime(null);\n if (this.wantsPlay) {\n setState(PlaybackState.Playing);\n commands.push({\n type: PlaybackCommandType.Try,\n logPrefix: '[PlaybackController] Failed to start playback:',\n emitPlaybackError: true,\n onError: { type: PlaybackActionType.StartFailed, fallbackState: PlaybackState.Paused },\n command: {\n type: PlaybackCommandType.Seq,\n commands: [\n { type: PlaybackCommandType.RenderFrame, timeUs: action.timeUs, mode: 'blocking' },\n { type: PlaybackCommandType.InitWindow, timeUs: action.timeUs },\n { type: PlaybackCommandType.StartAudioPlayback, timeUs: action.timeUs },\n { type: PlaybackCommandType.SyncTimeBaseToAudioClock, timeUs: action.timeUs },\n { type: PlaybackCommandType.StartRafLoop },\n { type: PlaybackCommandType.Emit, event: MeframeEvent.PlaybackPlay },\n ],\n },\n });\n } else {\n setState(PlaybackState.Paused);\n }\n return { token: this.token, commands };\n }\n\n case PlaybackActionType.SeekResolved: {\n if (this.state !== PlaybackState.Seeking) {\n return { token: this.token, commands };\n }\n setFrozenTime(null);\n commands.push({\n type: PlaybackCommandType.Emit,\n event: MeframeEvent.PlaybackSeek,\n payload: { timeUs: ctx.currentTimeUs },\n });\n if (this.wantsPlay) {\n setState(PlaybackState.Playing);\n commands.push({\n type: PlaybackCommandType.Try,\n logPrefix: '[PlaybackController] Failed to start playback:',\n emitPlaybackError: true,\n onError: { type: PlaybackActionType.StartFailed, fallbackState: PlaybackState.Paused },\n command: {\n type: PlaybackCommandType.Seq,\n commands: [\n {\n type: PlaybackCommandType.RenderFrame,\n timeUs: ctx.currentTimeUs,\n mode: 'blocking',\n },\n { type: PlaybackCommandType.InitWindow, timeUs: ctx.currentTimeUs },\n { type: PlaybackCommandType.StartAudioPlayback, timeUs: ctx.currentTimeUs },\n { type: PlaybackCommandType.SyncTimeBaseToAudioClock, timeUs: ctx.currentTimeUs },\n { type: PlaybackCommandType.StartRafLoop },\n { type: PlaybackCommandType.Emit, event: MeframeEvent.PlaybackPlay },\n ],\n },\n });\n } else {\n setState(\n action.previousState === PlaybackState.Idle ? PlaybackState.Idle : PlaybackState.Paused\n );\n }\n return { token: this.token, commands };\n }\n\n case PlaybackActionType.StartFailed: {\n // Startup failed: leave a stable non-playing state and clear intent.\n setWantsPlay(false);\n setFrozenTime(null);\n setState(action.fallbackState);\n commands.push({ type: PlaybackCommandType.CancelRaf });\n commands.push({ type: PlaybackCommandType.StopAudio });\n commands.push({ type: PlaybackCommandType.SetLastAudioScheduleTime, timeUs: 0 });\n return { token: this.token, commands };\n }\n\n case PlaybackActionType.ClockTick: {\n if (this.state !== PlaybackState.Playing) {\n return { token: this.token, commands };\n }\n if (this.frozenTimeUs !== null) {\n return { token: this.token, commands };\n }\n\n const t = action.candidateTimeUs;\n\n if (t >= action.durationUs) {\n if (action.loop) {\n setTime(0);\n commands.push({\n type: PlaybackCommandType.SetStartTimeBase,\n startTimeUs: action.audioNowUs,\n });\n commands.push({ type: PlaybackCommandType.ResetAudioPlaybackStates });\n commands.push({ type: PlaybackCommandType.SetLastAudioScheduleTime, timeUs: 0 });\n commands.push({ type: PlaybackCommandType.InitWindow, timeUs: 0 });\n } else {\n setWantsPlay(false);\n setState(PlaybackState.Ended);\n commands.push({ type: PlaybackCommandType.CancelRaf });\n commands.push({ type: PlaybackCommandType.StopAudio });\n setTime(0);\n commands.push({\n type: PlaybackCommandType.Emit,\n event: MeframeEvent.PlaybackEnded,\n payload: { timeUs: action.durationUs },\n });\n }\n return { token: this.token, commands };\n }\n\n setTime(t);\n commands.push({\n type: PlaybackCommandType.Emit,\n event: MeframeEvent.PlaybackTimeUpdate,\n payload: { timeUs: t },\n });\n return { token: this.token, commands };\n }\n }\n }\n}\n"],"names":[],"mappings":";;AAYO,MAAM,qBAAqB;AAAA,EACxB,QAAuB,cAAc;AAAA,EACrC,YAAY;AAAA,EACZ,eAA8B;AAAA,EAC9B,QAAiB;AAAA,EAEzB,IAAI,WAAoC;AACtC,WAAO;AAAA,MACL,OAAO,KAAK;AAAA,MACZ,WAAW,KAAK;AAAA,MAChB,cAAc,KAAK;AAAA,MACnB,OAAO,KAAK;AAAA,IAAA;AAAA,EAEhB;AAAA,EAEA,SACE,QACA,KACiD;AACjD,UAAM,WAA8B,CAAA;AAEpC,UAAM,YAAY,MAAM;AACtB,WAAK;AACL,aAAO,KAAK;AAAA,IACd;AAEA,UAAM,WAAW,CAAC,UAAyB;AACzC,WAAK,QAAQ;AACb,eAAS,KAAK,EAAE,MAAM,oBAAoB,UAAU,OAAO;AAAA,IAC7D;AAEA,UAAM,eAAe,CAAC,cAAuB;AAC3C,WAAK,YAAY;AACjB,eAAS,KAAK,EAAE,MAAM,oBAAoB,cAAc,WAAW;AAAA,IACrE;AAEA,UAAM,gBAAgB,CAAC,WAA0B;AAC/C,WAAK,eAAe;AACpB,eAAS,KAAK,EAAE,MAAM,oBAAoB,eAAe,QAAQ;AAAA,IACnE;AAEA,UAAM,UAAU,CAAC,WAAmB;AAClC,eAAS,KAAK,EAAE,MAAM,oBAAoB,SAAS,QAAQ;AAAA,IAC7D;AAEA,UAAM,YAAY,CAAC,QAAgB,eAAuB;AAGxD,YAAM,YAAY,aAAa,IAAI,aAAa,IAAI;AACpD,aAAO,KAAK,IAAI,GAAG,KAAK,IAAI,QAAQ,SAAS,CAAC;AAAA,IAChD;AAEA,YAAQ,OAAO,MAAA;AAAA,MACb,KAAK,mBAAmB,UAAU;AAChC,kBAAA;AAIA,iBAAS,KAAK,EAAE,MAAM,oBAAoB,WAAW;AACrD,iBAAS,KAAK,EAAE,MAAM,oBAAoB,WAAW;AACrD,iBAAS,KAAK,EAAE,MAAM,oBAAoB,0BAA0B,QAAQ,GAAG;AAC/E,sBAAc,IAAI;AAElB,YACE,KAAK,UAAU,cAAc,WAC7B,KAAK,UAAU,cAAc,aAC7B,KAAK,UAAU,cAAc,SAC7B;AACA,mBAAS,cAAc,MAAM;AAAA,QAC/B;AACA,eAAO,EAAE,OAAO,KAAK,OAAO,SAAA;AAAA,MAC9B;AAAA,MAEA,KAAK,mBAAmB,MAAM;AAC5B,cAAM,QAAQ,UAAA;AACd,cAAM,YAAY,KAAK;AACvB,qBAAa,IAAI;AAEjB,YAAI,KAAK,UAAU,cAAc,OAAO;AACtC,kBAAQ,CAAC;AAAA,QACX;AAEA,YAAI,KAAK,UAAU,cAAc,SAAS;AACxC,iBAAO,EAAE,OAAO,SAAA;AAAA,QAClB;AAGA,iBAAS,cAAc,OAAO;AAC9B,sBAAc,IAAI;AAClB,iBAAS,KAAK,EAAE,MAAM,oBAAoB,0BAA0B,QAAQ,GAAG;AAC/E,iBAAS,KAAK,EAAE,MAAM,oBAAoB,WAAW;AAErD,cAAM,gBACJ,cAAc,cAAc,QAAQ,cAAc,cAAc,QAC5D,cAAc,OACd,cAAc;AAEpB,iBAAS,KAAK;AAAA,UACZ,MAAM,oBAAoB;AAAA,UAC1B,WAAW;AAAA,UACX,mBAAmB;AAAA,UACnB,SAAS,EAAE,MAAM,mBAAmB,aAAa,cAAA;AAAA,UACjD,SAAS;AAAA,YACP,MAAM,oBAAoB;AAAA,YAC1B,UAAU;AAAA,cACR,EAAE,MAAM,oBAAoB,iBAAiB,QAAQ,IAAI,cAAA;AAAA,cACzD;AAAA,gBACE,MAAM,oBAAoB;AAAA,gBAC1B,QAAQ,IAAI;AAAA,gBACZ,MAAM;AAAA,cAAA;AAAA,cAER,EAAE,MAAM,oBAAoB,YAAY,QAAQ,IAAI,cAAA;AAAA,cACpD,EAAE,MAAM,oBAAoB,oBAAoB,QAAQ,IAAI,cAAA;AAAA,cAC5D,EAAE,MAAM,oBAAoB,0BAA0B,QAAQ,IAAI,cAAA;AAAA,cAClE,EAAE,MAAM,oBAAoB,aAAA;AAAA,cAC5B,EAAE,MAAM,oBAAoB,MAAM,OAAO,aAAa,aAAA;AAAA,YAAa;AAAA,UACrE;AAAA,QACF,CACD;AACD,eAAO,EAAE,OAAO,SAAA;AAAA,MAClB;AAAA,MAEA,KAAK,mBAAmB,OAAO;AAC7B,kBAAA;AACA,cAAM,OAAO,KAAK;AAClB,qBAAa,KAAK;AAClB,sBAAc,IAAI;AAClB,iBAAS,KAAK,EAAE,MAAM,oBAAoB,WAAW;AACrD,iBAAS,KAAK,EAAE,MAAM,oBAAoB,WAAW;AAErD,YAAI,SAAS,cAAc,QAAQ,SAAS,cAAc,OAAO;AAC/D,mBAAS,cAAc,MAAM;AAAA,QAC/B;AAEA,YACE,SAAS,cAAc,WACvB,SAAS,cAAc,aACvB,SAAS,cAAc,SACvB;AACA,mBAAS,KAAK,EAAE,MAAM,oBAAoB,MAAM,OAAO,aAAa,eAAe;AAAA,QACrF;AAEA,eAAO,EAAE,OAAO,KAAK,OAAO,SAAA;AAAA,MAC9B;AAAA,MAEA,KAAK,mBAAmB,MAAM;AAC5B,kBAAA;AACA,qBAAa,KAAK;AAClB,sBAAc,IAAI;AAClB,iBAAS,cAAc,IAAI;AAC3B,gBAAQ,CAAC;AAET,iBAAS,KAAK,EAAE,MAAM,oBAAoB,WAAW;AACrD,iBAAS,KAAK,EAAE,MAAM,oBAAoB,WAAW;AACrD,iBAAS,KAAK,EAAE,MAAM,oBAAoB,aAAa;AACvD,iBAAS,KAAK,EAAE,MAAM,oBAAoB,mBAAmB;AAC7D,iBAAS,KAAK,EAAE,MAAM,oBAAoB,0BAA0B;AACpE,iBAAS,KAAK,EAAE,MAAM,oBAAoB,0BAA0B,QAAQ,GAAG;AAC/E,iBAAS,KAAK,EAAE,MAAM,oBAAoB,MAAM,OAAO,aAAa,cAAc;AAElF,eAAO,EAAE,OAAO,KAAK,OAAO,SAAA;AAAA,MAC9B;AAAA,MAEA,KAAK,mBAAmB,MAAM;AAC5B,cAAM,QAAQ,UAAA;AACd,cAAM,gBAAgB,KAAK;AAC3B,cAAM,OAAO,UAAU,OAAO,QAAQ,OAAO,UAAU;AAEvD,gBAAQ,IAAI;AACZ,sBAAc,IAAI;AAClB,iBAAS,cAAc,OAAO;AAC9B,iBAAS,KAAK,EAAE,MAAM,oBAAoB,WAAW;AACrD,iBAAS,KAAK,EAAE,MAAM,oBAAoB,WAAW;AACrD,iBAAS,KAAK,EAAE,MAAM,oBAAoB,0BAA0B,QAAQ,GAAG;AAC/E,iBAAS,KAAK;AAAA,UACZ,MAAM,oBAAoB;AAAA,UAC1B,WAAW;AAAA,UACX,mBAAmB;AAAA,UACnB,SAAS,EAAE,MAAM,mBAAmB,MAAA;AAAA,UACpC,SAAS;AAAA,YACP,MAAM,oBAAoB;AAAA,YAC1B,UAAU;AAAA,cACR,EAAE,MAAM,oBAAoB,4BAA4B,QAAQ,KAAA;AAAA,cAChE;AAAA,gBACE,MAAM,oBAAoB;AAAA,gBAC1B,UAAU;AAAA,kBACR,EAAE,MAAM,oBAAoB,aAAa,QAAQ,MAAM,MAAM,WAAA;AAAA,kBAC7D;AAAA,oBACE,MAAM,oBAAoB;AAAA,oBAC1B,QAAQ;AAAA,oBACR,MAAM;AAAA,oBACN,SAAS;AAAA,kBAAA;AAAA,gBACX;AAAA,cACF;AAAA,cAEF,EAAE,MAAM,oBAAoB,YAAY,QAAQ,KAAA;AAAA,cAChD,EAAE,MAAM,oBAAoB,aAAa,QAAQ,MAAM,MAAM,WAAA;AAAA,cAC7D;AAAA,gBACE,MAAM,oBAAoB;AAAA,gBAC1B,QAAQ,EAAE,MAAM,mBAAmB,cAAc,cAAA;AAAA,cAAc;AAAA,YACjE;AAAA,UACF;AAAA,QACF,CACD;AAED,eAAO,EAAE,OAAO,SAAA;AAAA,MAClB;AAAA,MAEA,KAAK,mBAAmB,gBAAgB;AACtC,cAAM,aAAa,OAAO,aAAa;AACvC,YAAI,YAAY;AACd,oBAAA;AAAA,QACF;AACA,YAAI,KAAK,UAAU,cAAc,SAAS;AACxC,iBAAO,EAAE,OAAO,KAAK,OAAO,SAAA;AAAA,QAC9B;AAEA,sBAAc,OAAO,MAAM;AAC3B,iBAAS,cAAc,SAAS;AAChC,iBAAS,KAAK,EAAE,MAAM,oBAAoB,MAAM,OAAO,aAAa,mBAAmB;AACvF,iBAAS,KAAK,EAAE,MAAM,oBAAoB,WAAW;AACrD,iBAAS,KAAK,EAAE,MAAM,oBAAoB,WAAW;AACrD,iBAAS,KAAK;AAAA,UACZ,MAAM,oBAAoB;AAAA,UAC1B,WAAW;AAAA,UACX,mBAAmB;AAAA,UACnB,2BAA2B;AAAA,UAC3B,SAAS,EAAE,MAAM,mBAAmB,MAAA;AAAA,UACpC,SAAS;AAAA,YACP,MAAM,oBAAoB;AAAA,YAC1B,UAAU;AAAA,cACR,EAAE,MAAM,oBAAoB,gBAAgB,QAAQ,OAAO,OAAA;AAAA,cAC3D;AAAA,gBACE,MAAM,oBAAoB;AAAA,gBAC1B,UAAU;AAAA,kBACR,EAAE,MAAM,oBAAoB,UAAU,QAAQ,OAAO,QAAQ,MAAM,WAAA;AAAA,kBACnE;AAAA,oBACE,MAAM,oBAAoB;AAAA,oBAC1B,QAAQ,OAAO;AAAA,oBACf,MAAM;AAAA,kBAAA;AAAA,gBACR;AAAA,cACF;AAAA,cAEF;AAAA,gBACE,MAAM,oBAAoB;AAAA,gBAC1B,QAAQ,EAAE,MAAM,mBAAmB,mBAAmB,QAAQ,OAAO,OAAA;AAAA,cAAO;AAAA,YAC9E;AAAA,UACF;AAAA,QACF,CACD;AACD,eAAO,EAAE,OAAO,KAAK,OAAO,SAAA;AAAA,MAC9B;AAAA,MAEA,KAAK,mBAAmB,mBAAmB;AACzC,YAAI,KAAK,UAAU,cAAc,WAAW;AAC1C,iBAAO,EAAE,OAAO,KAAK,OAAO,SAAA;AAAA,QAC9B;AACA,sBAAc,IAAI;AAClB,YAAI,KAAK,WAAW;AAClB,mBAAS,cAAc,OAAO;AAC9B,mBAAS,KAAK;AAAA,YACZ,MAAM,oBAAoB;AAAA,YAC1B,WAAW;AAAA,YACX,mBAAmB;AAAA,YACnB,SAAS,EAAE,MAAM,mBAAmB,aAAa,eAAe,cAAc,OAAA;AAAA,YAC9E,SAAS;AAAA,cACP,MAAM,oBAAoB;AAAA,cAC1B,UAAU;AAAA,gBACR,EAAE,MAAM,oBAAoB,aAAa,QAAQ,OAAO,QAAQ,MAAM,WAAA;AAAA,gBACtE,EAAE,MAAM,oBAAoB,YAAY,QAAQ,OAAO,OAAA;AAAA,gBACvD,EAAE,MAAM,oBAAoB,oBAAoB,QAAQ,OAAO,OAAA;AAAA,gBAC/D,EAAE,MAAM,oBAAoB,0BAA0B,QAAQ,OAAO,OAAA;AAAA,gBACrE,EAAE,MAAM,oBAAoB,aAAA;AAAA,gBAC5B,EAAE,MAAM,oBAAoB,MAAM,OAAO,aAAa,aAAA;AAAA,cAAa;AAAA,YACrE;AAAA,UACF,CACD;AAAA,QACH,OAAO;AACL,mBAAS,cAAc,MAAM;AAAA,QAC/B;AACA,eAAO,EAAE,OAAO,KAAK,OAAO,SAAA;AAAA,MAC9B;AAAA,MAEA,KAAK,mBAAmB,cAAc;AACpC,YAAI,KAAK,UAAU,cAAc,SAAS;AACxC,iBAAO,EAAE,OAAO,KAAK,OAAO,SAAA;AAAA,QAC9B;AACA,sBAAc,IAAI;AAClB,iBAAS,KAAK;AAAA,UACZ,MAAM,oBAAoB;AAAA,UAC1B,OAAO,aAAa;AAAA,UACpB,SAAS,EAAE,QAAQ,IAAI,cAAA;AAAA,QAAc,CACtC;AACD,YAAI,KAAK,WAAW;AAClB,mBAAS,cAAc,OAAO;AAC9B,mBAAS,KAAK;AAAA,YACZ,MAAM,oBAAoB;AAAA,YAC1B,WAAW;AAAA,YACX,mBAAmB;AAAA,YACnB,SAAS,EAAE,MAAM,mBAAmB,aAAa,eAAe,cAAc,OAAA;AAAA,YAC9E,SAAS;AAAA,cACP,MAAM,oBAAoB;AAAA,cAC1B,UAAU;AAAA,gBACR;AAAA,kBACE,MAAM,oBAAoB;AAAA,kBAC1B,QAAQ,IAAI;AAAA,kBACZ,MAAM;AAAA,gBAAA;AAAA,gBAER,EAAE,MAAM,oBAAoB,YAAY,QAAQ,IAAI,cAAA;AAAA,gBACpD,EAAE,MAAM,oBAAoB,oBAAoB,QAAQ,IAAI,cAAA;AAAA,gBAC5D,EAAE,MAAM,oBAAoB,0BAA0B,QAAQ,IAAI,cAAA;AAAA,gBAClE,EAAE,MAAM,oBAAoB,aAAA;AAAA,gBAC5B,EAAE,MAAM,oBAAoB,MAAM,OAAO,aAAa,aAAA;AAAA,cAAa;AAAA,YACrE;AAAA,UACF,CACD;AAAA,QACH,OAAO;AACL;AAAA,YACE,OAAO,kBAAkB,cAAc,OAAO,cAAc,OAAO,cAAc;AAAA,UAAA;AAAA,QAErF;AACA,eAAO,EAAE,OAAO,KAAK,OAAO,SAAA;AAAA,MAC9B;AAAA,MAEA,KAAK,mBAAmB,aAAa;AAEnC,qBAAa,KAAK;AAClB,sBAAc,IAAI;AAClB,iBAAS,OAAO,aAAa;AAC7B,iBAAS,KAAK,EAAE,MAAM,oBAAoB,WAAW;AACrD,iBAAS,KAAK,EAAE,MAAM,oBAAoB,WAAW;AACrD,iBAAS,KAAK,EAAE,MAAM,oBAAoB,0BAA0B,QAAQ,GAAG;AAC/E,eAAO,EAAE,OAAO,KAAK,OAAO,SAAA;AAAA,MAC9B;AAAA,MAEA,KAAK,mBAAmB,WAAW;AACjC,YAAI,KAAK,UAAU,cAAc,SAAS;AACxC,iBAAO,EAAE,OAAO,KAAK,OAAO,SAAA;AAAA,QAC9B;AACA,YAAI,KAAK,iBAAiB,MAAM;AAC9B,iBAAO,EAAE,OAAO,KAAK,OAAO,SAAA;AAAA,QAC9B;AAEA,cAAM,IAAI,OAAO;AAEjB,YAAI,KAAK,OAAO,YAAY;AAC1B,cAAI,OAAO,MAAM;AACf,oBAAQ,CAAC;AACT,qBAAS,KAAK;AAAA,cACZ,MAAM,oBAAoB;AAAA,cAC1B,aAAa,OAAO;AAAA,YAAA,CACrB;AACD,qBAAS,KAAK,EAAE,MAAM,oBAAoB,0BAA0B;AACpE,qBAAS,KAAK,EAAE,MAAM,oBAAoB,0BAA0B,QAAQ,GAAG;AAC/E,qBAAS,KAAK,EAAE,MAAM,oBAAoB,YAAY,QAAQ,GAAG;AAAA,UACnE,OAAO;AACL,yBAAa,KAAK;AAClB,qBAAS,cAAc,KAAK;AAC5B,qBAAS,KAAK,EAAE,MAAM,oBAAoB,WAAW;AACrD,qBAAS,KAAK,EAAE,MAAM,oBAAoB,WAAW;AACrD,oBAAQ,CAAC;AACT,qBAAS,KAAK;AAAA,cACZ,MAAM,oBAAoB;AAAA,cAC1B,OAAO,aAAa;AAAA,cACpB,SAAS,EAAE,QAAQ,OAAO,WAAA;AAAA,YAAW,CACtC;AAAA,UACH;AACA,iBAAO,EAAE,OAAO,KAAK,OAAO,SAAA;AAAA,QAC9B;AAEA,gBAAQ,CAAC;AACT,iBAAS,KAAK;AAAA,UACZ,MAAM,oBAAoB;AAAA,UAC1B,OAAO,aAAa;AAAA,UACpB,SAAS,EAAE,QAAQ,EAAA;AAAA,QAAE,CACtB;AACD,eAAO,EAAE,OAAO,KAAK,OAAO,SAAA;AAAA,MAC9B;AAAA,IAAA;AAAA,EAEJ;AACF;"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { TimeUs } from '../model/types';
|
|
2
2
|
import { EventBus } from '../event/EventBus';
|
|
3
3
|
import { EventPayloadMap, MeframeEvent } from '../event/events';
|
|
4
|
+
import { RequestMode } from '../orchestrator/types';
|
|
4
5
|
|
|
5
6
|
export type { TimeUs } from '../model/types';
|
|
6
7
|
export interface IPlaybackController {
|
|
@@ -30,6 +31,7 @@ export declare const PlaybackActionType: {
|
|
|
30
31
|
readonly Pause: "pause";
|
|
31
32
|
readonly Stop: "stop";
|
|
32
33
|
readonly Seek: "seek";
|
|
34
|
+
readonly ModelSet: "modelSet";
|
|
33
35
|
readonly ClockTick: "clockTick";
|
|
34
36
|
readonly EnterBuffering: "enterBuffering";
|
|
35
37
|
readonly BufferingResolved: "bufferingResolved";
|
|
@@ -47,6 +49,8 @@ export type PlaybackAction = {
|
|
|
47
49
|
type: typeof PlaybackActionType.Seek;
|
|
48
50
|
timeUs: TimeUs;
|
|
49
51
|
durationUs: TimeUs;
|
|
52
|
+
} | {
|
|
53
|
+
type: typeof PlaybackActionType.ModelSet;
|
|
50
54
|
} | {
|
|
51
55
|
type: typeof PlaybackActionType.ClockTick;
|
|
52
56
|
candidateTimeUs: TimeUs;
|
|
@@ -56,6 +60,8 @@ export type PlaybackAction = {
|
|
|
56
60
|
} | {
|
|
57
61
|
type: typeof PlaybackActionType.EnterBuffering;
|
|
58
62
|
timeUs: TimeUs;
|
|
63
|
+
bumpToken?: boolean;
|
|
64
|
+
reason?: 'startup' | 'video' | 'audio';
|
|
59
65
|
} | {
|
|
60
66
|
type: typeof PlaybackActionType.BufferingResolved;
|
|
61
67
|
timeUs: TimeUs;
|
|
@@ -86,6 +92,7 @@ export declare const PlaybackCommandType: {
|
|
|
86
92
|
readonly InitWindow: "initWindow";
|
|
87
93
|
readonly SetCacheWindow: "setCacheWindow";
|
|
88
94
|
readonly Emit: "emit";
|
|
95
|
+
readonly ProbeStartReady: "probeStartReady";
|
|
89
96
|
readonly RenderFrame: "renderFrame";
|
|
90
97
|
readonly MaybeRenderKeyframePreview: "maybeRenderKeyframePreview";
|
|
91
98
|
readonly EnsureAudio: "ensureAudio";
|
|
@@ -151,10 +158,13 @@ export type PlaybackCommand = {
|
|
|
151
158
|
type: typeof PlaybackCommandType.Emit;
|
|
152
159
|
event: MeframeEvent;
|
|
153
160
|
payload?: any;
|
|
161
|
+
} | {
|
|
162
|
+
type: typeof PlaybackCommandType.ProbeStartReady;
|
|
163
|
+
timeUs: TimeUs;
|
|
154
164
|
} | {
|
|
155
165
|
type: typeof PlaybackCommandType.RenderFrame;
|
|
156
166
|
timeUs: TimeUs;
|
|
157
|
-
|
|
167
|
+
mode: RequestMode;
|
|
158
168
|
relativeTimeUs?: TimeUs;
|
|
159
169
|
} | {
|
|
160
170
|
type: typeof PlaybackCommandType.MaybeRenderKeyframePreview;
|
|
@@ -162,11 +172,11 @@ export type PlaybackCommand = {
|
|
|
162
172
|
} | {
|
|
163
173
|
type: typeof PlaybackCommandType.EnsureAudio;
|
|
164
174
|
timeUs: TimeUs;
|
|
165
|
-
|
|
175
|
+
mode: RequestMode;
|
|
166
176
|
} | {
|
|
167
177
|
type: typeof PlaybackCommandType.GetFrame;
|
|
168
178
|
timeUs: TimeUs;
|
|
169
|
-
|
|
179
|
+
mode: RequestMode;
|
|
170
180
|
preheat?: boolean;
|
|
171
181
|
} | {
|
|
172
182
|
type: typeof PlaybackCommandType.StartAudioPlayback;
|
|
@@ -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;AACvD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;
|
|
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;AACvD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAGzD,YAAY,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAC;AAI7C,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,aAAa,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;CAC7B;AAED,oBAAY,aAAa;IACvB,IAAI,SAAS;IACb,SAAS,cAAc;IACvB,OAAO,YAAY;IACnB,MAAM,WAAW;IACjB,OAAO,YAAY;IACnB,KAAK,UAAU;CAChB;AAID,MAAM,MAAM,OAAO,GAAG,MAAM,CAAC;AAE7B,eAAO,MAAM,kBAAkB;;;;;;;;;;;CAWrB,CAAC;AAEX,MAAM,MAAM,uBAAuB,GAAG,CAAC,OAAO,kBAAkB,CAAC,CAAC,MAAM,OAAO,kBAAkB,CAAC,CAAC;AAEnG,MAAM,MAAM,cAAc,GACtB;IAAE,IAAI,EAAE,OAAO,kBAAkB,CAAC,IAAI,CAAA;CAAE,GACxC;IAAE,IAAI,EAAE,OAAO,kBAAkB,CAAC,KAAK,CAAA;CAAE,GACzC;IAAE,IAAI,EAAE,OAAO,kBAAkB,CAAC,IAAI,CAAA;CAAE,GACxC;IAAE,IAAI,EAAE,OAAO,kBAAkB,CAAC,IAAI,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,GAC5E;IAAE,IAAI,EAAE,OAAO,kBAAkB,CAAC,QAAQ,CAAA;CAAE,GAC5C;IACE,IAAI,EAAE,OAAO,kBAAkB,CAAC,SAAS,CAAC;IAC1C,eAAe,EAAE,MAAM,CAAC;IACxB,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,OAAO,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;CACpB,GACD;IACE,IAAI,EAAE,OAAO,kBAAkB,CAAC,cAAc,CAAC;IAC/C,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,MAAM,CAAC,EAAE,SAAS,GAAG,OAAO,GAAG,OAAO,CAAC;CACxC,GACD;IAAE,IAAI,EAAE,OAAO,kBAAkB,CAAC,iBAAiB,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GACrE;IAAE,IAAI,EAAE,OAAO,kBAAkB,CAAC,YAAY,CAAC;IAAC,aAAa,EAAE,aAAa,CAAA;CAAE,GAC9E;IAAE,IAAI,EAAE,OAAO,kBAAkB,CAAC,WAAW,CAAC;IAAC,aAAa,EAAE,aAAa,CAAA;CAAE,CAAC;AAElF,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;;;;;;;;;;;;;;;CA6BtB,CAAC;AAEX,MAAM,MAAM,wBAAwB,GAClC,CAAC,OAAO,mBAAmB,CAAC,CAAC,MAAM,OAAO,mBAAmB,CAAC,CAAC;AAEjE,MAAM,MAAM,eAAe,GACvB;IAAE,IAAI,EAAE,OAAO,mBAAmB,CAAC,GAAG,CAAC;IAAC,QAAQ,EAAE,eAAe,EAAE,CAAA;CAAE,GACrE;IAAE,IAAI,EAAE,OAAO,mBAAmB,CAAC,GAAG,CAAC;IAAC,QAAQ,EAAE,eAAe,EAAE,CAAA;CAAE,GACrE;IACE,IAAI,EAAE,OAAO,mBAAmB,CAAC,GAAG,CAAC;IACrC,OAAO,EAAE,eAAe,CAAC;IACzB,yBAAyB,CAAC,EAAE,OAAO,CAAC;IACpC,OAAO,CAAC,EAAE,cAAc,CAAC;IACzB,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,GACD;IAAE,IAAI,EAAE,OAAO,mBAAmB,CAAC,QAAQ,CAAC;IAAC,MAAM,EAAE,cAAc,CAAA;CAAE,GACrE;IAAE,IAAI,EAAE,OAAO,mBAAmB,CAAC,OAAO,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GAC5D;IAAE,IAAI,EAAE,OAAO,mBAAmB,CAAC,aAAa,CAAC;IAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,GACzE;IAAE,IAAI,EAAE,OAAO,mBAAmB,CAAC,YAAY,CAAC;IAAC,SAAS,EAAE,OAAO,CAAA;CAAE,GACrE;IAAE,IAAI,EAAE,OAAO,mBAAmB,CAAC,QAAQ,CAAC;IAAC,KAAK,EAAE,aAAa,CAAA;CAAE,GACnE;IAAE,IAAI,EAAE,OAAO,mBAAmB,CAAC,SAAS,CAAA;CAAE,GAC9C;IAAE,IAAI,EAAE,OAAO,mBAAmB,CAAC,SAAS,CAAA;CAAE,GAC9C;IAAE,IAAI,EAAE,OAAO,mBAAmB,CAAC,wBAAwB,CAAA;CAAE,GAC7D;IAAE,IAAI,EAAE,OAAO,mBAAmB,CAAC,iBAAiB,CAAA;CAAE,GACtD;IAAE,IAAI,EAAE,OAAO,mBAAmB,CAAC,WAAW,CAAA;CAAE,GAChD;IAAE,IAAI,EAAE,OAAO,mBAAmB,CAAC,wBAAwB,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GAC7E;IAAE,IAAI,EAAE,OAAO,mBAAmB,CAAC,gBAAgB,CAAC;IAAC,WAAW,EAAE,MAAM,CAAA;CAAE,GAC1E;IAAE,IAAI,EAAE,OAAO,mBAAmB,CAAC,wBAAwB,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GAC7E;IAAE,IAAI,EAAE,OAAO,mBAAmB,CAAC,UAAU,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GAC/D;IAAE,IAAI,EAAE,OAAO,mBAAmB,CAAC,cAAc,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GACnE;IAAE,IAAI,EAAE,OAAO,mBAAmB,CAAC,IAAI,CAAC;IAAC,KAAK,EAAE,YAAY,CAAC;IAAC,OAAO,CAAC,EAAE,GAAG,CAAA;CAAE,GAC7E;IAAE,IAAI,EAAE,OAAO,mBAAmB,CAAC,eAAe,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GACpE;IACE,IAAI,EAAE,OAAO,mBAAmB,CAAC,WAAW,CAAC;IAC7C,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,WAAW,CAAC;IAClB,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB,GACD;IAAE,IAAI,EAAE,OAAO,mBAAmB,CAAC,0BAA0B,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GAC/E;IAAE,IAAI,EAAE,OAAO,mBAAmB,CAAC,WAAW,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,WAAW,CAAA;CAAE,GACnF;IACE,IAAI,EAAE,OAAO,mBAAmB,CAAC,QAAQ,CAAC;IAC1C,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,WAAW,CAAC;IAClB,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB,GACD;IAAE,IAAI,EAAE,OAAO,mBAAmB,CAAC,kBAAkB,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GACvE;IAAE,IAAI,EAAE,OAAO,mBAAmB,CAAC,YAAY,CAAA;CAAE,CAAC;AAEtD,MAAM,WAAW,uBAAuB;IACtC,KAAK,EAAE,aAAa,CAAC;IACrB,SAAS,EAAE,OAAO,CAAC;IACnB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,KAAK,EAAE,OAAO,CAAC;CAChB;AAED,MAAM,MAAM,aAAa,GACrB,MAAM,GACN,OAAO,GACP,OAAO,GACP,MAAM,GACN,YAAY,GACZ,YAAY,GACZ,OAAO,GACP,OAAO,GACP,MAAM,CAAC;AAEX,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,iBAAiB,GAAG,eAAe,CAAC;IAC5C,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,IAAI,IAAI,CAAC;IACb,IAAI,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,KAAK,IAAI,IAAI,CAAC;IACd,MAAM,IAAI,IAAI,CAAC;IACf,IAAI,IAAI,IAAI,CAAC;IACb,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;IAC5B,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,QAAQ,GAAG,IAAI,CAAC;IAC3C,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,QAAQ,GAAG,IAAI,CAAC;CAC7C;AAID,MAAM,WAAW,SAAS;IACxB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,eAAe;IAC9B,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;CAClB;AAID,MAAM,MAAM,SAAS,GAAG,QAAQ,CAAC,eAAe,CAAC,CAAC;AAIlD,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,GAAG,EAAE,MAAM,CAAC;IACZ,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,OAAO,CAAC;CAClB"}
|
|
@@ -12,6 +12,7 @@ const PlaybackActionType = {
|
|
|
12
12
|
Pause: "pause",
|
|
13
13
|
Stop: "stop",
|
|
14
14
|
Seek: "seek",
|
|
15
|
+
ModelSet: "modelSet",
|
|
15
16
|
ClockTick: "clockTick",
|
|
16
17
|
EnterBuffering: "enterBuffering",
|
|
17
18
|
BufferingResolved: "bufferingResolved",
|
|
@@ -38,6 +39,7 @@ const PlaybackCommandType = {
|
|
|
38
39
|
InitWindow: "initWindow",
|
|
39
40
|
SetCacheWindow: "setCacheWindow",
|
|
40
41
|
Emit: "emit",
|
|
42
|
+
ProbeStartReady: "probeStartReady",
|
|
41
43
|
RenderFrame: "renderFrame",
|
|
42
44
|
MaybeRenderKeyframePreview: "maybeRenderKeyframePreview",
|
|
43
45
|
EnsureAudio: "ensureAudio",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sources":["../../src/controllers/types.ts"],"sourcesContent":["import type { TimeUs } from '../model/types';\nimport type { EventBus } from '../event/EventBus';\nimport type { EventPayloadMap } from '../event/events';\nimport type { MeframeEvent } from '../event/events';\n\n// Re-export TimeUs for convenience\nexport type { TimeUs } from '../model/types';\n\n// ========= PlaybackController Types =========\n\nexport interface IPlaybackController {\n // Playback control\n play(): void;\n pause(): void;\n stop(): void;\n seek(timeUs: TimeUs): void;\n\n // Playback properties\n setRate(rate: number): void;\n setVolume(volume: number): void;\n setLoop(loop: boolean): void;\n setMute(muted: boolean): void;\n\n // State queries\n currentTimeUs: TimeUs;\n readonly duration: TimeUs;\n readonly isPlaying: boolean;\n}\n\nexport enum PlaybackState {\n Idle = 'idle',\n Buffering = 'buffering',\n Playing = 'playing',\n Paused = 'paused',\n Seeking = 'seeking',\n Ended = 'ended',\n}\n\n// ========= Playback State Machine Types (internal protocol) =========\n\nexport type OpToken = number;\n\nexport const PlaybackActionType = {\n Play: 'play',\n Pause: 'pause',\n Stop: 'stop',\n Seek: 'seek',\n ClockTick: 'clockTick',\n EnterBuffering: 'enterBuffering',\n BufferingResolved: 'bufferingResolved',\n SeekResolved: 'seekResolved',\n StartFailed: 'startFailed',\n} as const;\n\nexport type PlaybackActionTypeValue = (typeof PlaybackActionType)[keyof typeof PlaybackActionType];\n\nexport type PlaybackAction =\n | { type: typeof PlaybackActionType.Play }\n | { type: typeof PlaybackActionType.Pause }\n | { type: typeof PlaybackActionType.Stop }\n | { type: typeof PlaybackActionType.Seek; timeUs: TimeUs; durationUs: TimeUs }\n | {\n type: typeof PlaybackActionType.ClockTick;\n candidateTimeUs: TimeUs;\n durationUs: TimeUs;\n loop: boolean;\n audioNowUs: TimeUs;\n }\n | {
|
|
1
|
+
{"version":3,"file":"types.js","sources":["../../src/controllers/types.ts"],"sourcesContent":["import type { TimeUs } from '../model/types';\nimport type { EventBus } from '../event/EventBus';\nimport type { EventPayloadMap } from '../event/events';\nimport type { MeframeEvent } from '../event/events';\nimport type { RequestMode } from '../orchestrator/types';\n\n// Re-export TimeUs for convenience\nexport type { TimeUs } from '../model/types';\n\n// ========= PlaybackController Types =========\n\nexport interface IPlaybackController {\n // Playback control\n play(): void;\n pause(): void;\n stop(): void;\n seek(timeUs: TimeUs): void;\n\n // Playback properties\n setRate(rate: number): void;\n setVolume(volume: number): void;\n setLoop(loop: boolean): void;\n setMute(muted: boolean): void;\n\n // State queries\n currentTimeUs: TimeUs;\n readonly duration: TimeUs;\n readonly isPlaying: boolean;\n}\n\nexport enum PlaybackState {\n Idle = 'idle',\n Buffering = 'buffering',\n Playing = 'playing',\n Paused = 'paused',\n Seeking = 'seeking',\n Ended = 'ended',\n}\n\n// ========= Playback State Machine Types (internal protocol) =========\n\nexport type OpToken = number;\n\nexport const PlaybackActionType = {\n Play: 'play',\n Pause: 'pause',\n Stop: 'stop',\n Seek: 'seek',\n ModelSet: 'modelSet',\n ClockTick: 'clockTick',\n EnterBuffering: 'enterBuffering',\n BufferingResolved: 'bufferingResolved',\n SeekResolved: 'seekResolved',\n StartFailed: 'startFailed',\n} as const;\n\nexport type PlaybackActionTypeValue = (typeof PlaybackActionType)[keyof typeof PlaybackActionType];\n\nexport type PlaybackAction =\n | { type: typeof PlaybackActionType.Play }\n | { type: typeof PlaybackActionType.Pause }\n | { type: typeof PlaybackActionType.Stop }\n | { type: typeof PlaybackActionType.Seek; timeUs: TimeUs; durationUs: TimeUs }\n | { type: typeof PlaybackActionType.ModelSet }\n | {\n type: typeof PlaybackActionType.ClockTick;\n candidateTimeUs: TimeUs;\n durationUs: TimeUs;\n loop: boolean;\n audioNowUs: TimeUs;\n }\n | {\n type: typeof PlaybackActionType.EnterBuffering;\n timeUs: TimeUs;\n bumpToken?: boolean;\n reason?: 'startup' | 'video' | 'audio';\n }\n | { type: typeof PlaybackActionType.BufferingResolved; timeUs: TimeUs }\n | { type: typeof PlaybackActionType.SeekResolved; previousState: PlaybackState }\n | { type: typeof PlaybackActionType.StartFailed; fallbackState: PlaybackState };\n\nexport const PlaybackCommandType = {\n Seq: 'seq',\n Par: 'par',\n Try: 'try',\n Dispatch: 'dispatch',\n\n SetTime: 'setTime',\n SetFrozenTime: 'setFrozenTime',\n SetWantsPlay: 'setWantsPlay',\n SetState: 'setState',\n CancelRaf: 'cancelRaf',\n StopAudio: 'stopAudio',\n ResetAudioPlaybackStates: 'resetAudioPlaybackStates',\n ResetAudioSession: 'resetAudioSession',\n ClearCanvas: 'clearCanvas',\n SetLastAudioScheduleTime: 'setLastAudioScheduleTime',\n SetStartTimeBase: 'setStartTimeBase',\n SyncTimeBaseToAudioClock: 'syncTimeBaseToAudioClock',\n InitWindow: 'initWindow',\n SetCacheWindow: 'setCacheWindow',\n Emit: 'emit',\n\n ProbeStartReady: 'probeStartReady',\n RenderFrame: 'renderFrame',\n MaybeRenderKeyframePreview: 'maybeRenderKeyframePreview',\n EnsureAudio: 'ensureAudio',\n GetFrame: 'getFrame',\n StartAudioPlayback: 'startAudioPlayback',\n StartRafLoop: 'startRafLoop',\n} as const;\n\nexport type PlaybackCommandTypeValue =\n (typeof PlaybackCommandType)[keyof typeof PlaybackCommandType];\n\nexport type PlaybackCommand =\n | { type: typeof PlaybackCommandType.Seq; commands: PlaybackCommand[] }\n | { type: typeof PlaybackCommandType.Par; commands: PlaybackCommand[] }\n | {\n type: typeof PlaybackCommandType.Try;\n command: PlaybackCommand;\n ignoreWaiterReplacedError?: boolean;\n onError?: PlaybackAction;\n emitPlaybackError?: boolean;\n logPrefix?: string;\n }\n | { type: typeof PlaybackCommandType.Dispatch; action: PlaybackAction }\n | { type: typeof PlaybackCommandType.SetTime; timeUs: TimeUs }\n | { type: typeof PlaybackCommandType.SetFrozenTime; timeUs: TimeUs | null }\n | { type: typeof PlaybackCommandType.SetWantsPlay; wantsPlay: boolean }\n | { type: typeof PlaybackCommandType.SetState; state: PlaybackState }\n | { type: typeof PlaybackCommandType.CancelRaf }\n | { type: typeof PlaybackCommandType.StopAudio }\n | { type: typeof PlaybackCommandType.ResetAudioPlaybackStates }\n | { type: typeof PlaybackCommandType.ResetAudioSession }\n | { type: typeof PlaybackCommandType.ClearCanvas }\n | { type: typeof PlaybackCommandType.SetLastAudioScheduleTime; timeUs: TimeUs }\n | { type: typeof PlaybackCommandType.SetStartTimeBase; startTimeUs: TimeUs }\n | { type: typeof PlaybackCommandType.SyncTimeBaseToAudioClock; timeUs: TimeUs }\n | { type: typeof PlaybackCommandType.InitWindow; timeUs: TimeUs }\n | { type: typeof PlaybackCommandType.SetCacheWindow; timeUs: TimeUs }\n | { type: typeof PlaybackCommandType.Emit; event: MeframeEvent; payload?: any }\n | { type: typeof PlaybackCommandType.ProbeStartReady; timeUs: TimeUs }\n | {\n type: typeof PlaybackCommandType.RenderFrame;\n timeUs: TimeUs;\n mode: RequestMode;\n relativeTimeUs?: TimeUs;\n }\n | { type: typeof PlaybackCommandType.MaybeRenderKeyframePreview; timeUs: TimeUs }\n | { type: typeof PlaybackCommandType.EnsureAudio; timeUs: TimeUs; mode: RequestMode }\n | {\n type: typeof PlaybackCommandType.GetFrame;\n timeUs: TimeUs;\n mode: RequestMode;\n preheat?: boolean;\n }\n | { type: typeof PlaybackCommandType.StartAudioPlayback; timeUs: TimeUs }\n | { type: typeof PlaybackCommandType.StartRafLoop };\n\nexport interface PlaybackMachineSnapshot {\n state: PlaybackState;\n wantsPlay: boolean;\n frozenTimeUs: TimeUs | null;\n token: OpToken;\n}\n\nexport type PlaybackEvent =\n | 'play'\n | 'pause'\n | 'ended'\n | 'seek'\n | 'timeupdate'\n | 'ratechange'\n | 'error'\n | 'frame'\n | 'stop';\n\nexport interface PlaybackOptions {\n canvas: HTMLCanvasElement | OffscreenCanvas;\n startUs?: TimeUs;\n endUs?: TimeUs;\n loop?: boolean;\n rate?: number;\n autoStart?: boolean;\n}\n\nexport interface PreviewHandle {\n play(): void;\n seek(timeUs: TimeUs): void;\n setRate(rate: number): void;\n setVolume(volume: number): void;\n pause(): void;\n resume(): void;\n stop(): void;\n readonly currentTimeUs: TimeUs;\n readonly isPlaying: boolean;\n on(event: string, handler: Function): void;\n off(event: string, handler: Function): void;\n}\n\n// ========= PlaybackWindowPlanner Types =========\n\nexport interface TimeRange {\n startUs: TimeUs;\n endUs: TimeUs;\n}\n\nexport interface PrioritizedClip {\n id: string;\n startUs: TimeUs;\n endUs: TimeUs;\n priority: number;\n}\n\n// ========= Event Bus Type =========\n// Using EventBus from orchestrator module\nexport type IEventBus = EventBus<EventPayloadMap>;\n\n// ========= Performance Types =========\n\nexport interface FrameStats {\n timeUs: TimeUs;\n fps: number;\n frameTime: number;\n dropped: boolean;\n}\n"],"names":["PlaybackState"],"mappings":"AA8BO,IAAK,kCAAAA,mBAAL;AACLA,iBAAA,MAAA,IAAO;AACPA,iBAAA,WAAA,IAAY;AACZA,iBAAA,SAAA,IAAU;AACVA,iBAAA,QAAA,IAAS;AACTA,iBAAA,SAAA,IAAU;AACVA,iBAAA,OAAA,IAAQ;AANE,SAAAA;AAAA,GAAA,iBAAA,CAAA,CAAA;AAaL,MAAM,qBAAqB;AAAA,EAChC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,MAAM;AAAA,EACN,MAAM;AAAA,EACN,UAAU;AAAA,EACV,WAAW;AAAA,EACX,gBAAgB;AAAA,EAChB,mBAAmB;AAAA,EACnB,cAAc;AAAA,EACd,aAAa;AACf;AA2BO,MAAM,sBAAsB;AAAA,EACjC,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,UAAU;AAAA,EAEV,SAAS;AAAA,EACT,eAAe;AAAA,EACf,cAAc;AAAA,EACd,UAAU;AAAA,EACV,WAAW;AAAA,EACX,WAAW;AAAA,EACX,0BAA0B;AAAA,EAC1B,mBAAmB;AAAA,EACnB,aAAa;AAAA,EACb,0BAA0B;AAAA,EAC1B,kBAAkB;AAAA,EAClB,0BAA0B;AAAA,EAC1B,YAAY;AAAA,EACZ,gBAAgB;AAAA,EAChB,MAAM;AAAA,EAEN,iBAAiB;AAAA,EACjB,aAAa;AAAA,EACb,4BAA4B;AAAA,EAC5B,aAAa;AAAA,EACb,UAAU;AAAA,EACV,oBAAoB;AAAA,EACpB,cAAc;AAChB;"}
|
package/dist/model/types.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/model/types.ts"],"names":[],"mappings":"AACA,MAAM,MAAM,MAAM,GAAG,MAAM,CAAC;AAG5B,eAAO,MAAM,uBAAuB,UAAY,CAAC;AACjD,eAAO,MAAM,4BAA4B,OAAQ,CAAC;AAGlD,MAAM,WAAW,oBAAoB;IACnC,OAAO,EAAE,KAAK,CAAC;IACf,GAAG,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC;IACvB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,KAAK,EAAE,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;IAEpC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,YAAY,CAAC;IAE5B,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAC/B;AAED,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAGD,MAAM,WAAW,KAAK;IACpB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,OAAO,GAAG,OAAO,GAAG,SAAS,GAAG,SAAS,GAAG,IAAI,CAAC;IACvD,KAAK,EAAE,IAAI,EAAE,CAAC;IAEd,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,YAAY,CAAC,EAAE,WAAW,EAAE,CAAC;CAC9B;AAKD,MAAM,WAAW,gBAAgB;IAC/B,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACxB,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;CAC1B;AAED,UAAU,QAAQ;IAChB,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB,WAAW,CAAC,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/model/types.ts"],"names":[],"mappings":"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"}
|