@meframe/core 0.0.31 → 0.0.32

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.
Files changed (61) hide show
  1. package/dist/Meframe.d.ts +2 -2
  2. package/dist/Meframe.d.ts.map +1 -1
  3. package/dist/Meframe.js +3 -2
  4. package/dist/Meframe.js.map +1 -1
  5. package/dist/cache/CacheManager.d.ts +12 -17
  6. package/dist/cache/CacheManager.d.ts.map +1 -1
  7. package/dist/cache/CacheManager.js +18 -280
  8. package/dist/cache/CacheManager.js.map +1 -1
  9. package/dist/cache/l1/AudioL1Cache.d.ts +36 -19
  10. package/dist/cache/l1/AudioL1Cache.d.ts.map +1 -1
  11. package/dist/cache/l1/AudioL1Cache.js +182 -282
  12. package/dist/cache/l1/AudioL1Cache.js.map +1 -1
  13. package/dist/controllers/PlaybackController.d.ts +4 -2
  14. package/dist/controllers/PlaybackController.d.ts.map +1 -1
  15. package/dist/controllers/PlaybackController.js +43 -13
  16. package/dist/controllers/PlaybackController.js.map +1 -1
  17. package/dist/model/types.d.ts +0 -4
  18. package/dist/model/types.d.ts.map +1 -1
  19. package/dist/model/types.js.map +1 -1
  20. package/dist/orchestrator/ExportScheduler.d.ts +6 -0
  21. package/dist/orchestrator/ExportScheduler.d.ts.map +1 -1
  22. package/dist/orchestrator/ExportScheduler.js +45 -66
  23. package/dist/orchestrator/ExportScheduler.js.map +1 -1
  24. package/dist/orchestrator/GlobalAudioSession.d.ts +35 -28
  25. package/dist/orchestrator/GlobalAudioSession.d.ts.map +1 -1
  26. package/dist/orchestrator/GlobalAudioSession.js +212 -421
  27. package/dist/orchestrator/GlobalAudioSession.js.map +1 -1
  28. package/dist/orchestrator/OnDemandVideoSession.d.ts +3 -3
  29. package/dist/orchestrator/OnDemandVideoSession.d.ts.map +1 -1
  30. package/dist/orchestrator/OnDemandVideoSession.js +4 -4
  31. package/dist/orchestrator/OnDemandVideoSession.js.map +1 -1
  32. package/dist/orchestrator/Orchestrator.d.ts +1 -2
  33. package/dist/orchestrator/Orchestrator.d.ts.map +1 -1
  34. package/dist/orchestrator/Orchestrator.js +34 -48
  35. package/dist/orchestrator/Orchestrator.js.map +1 -1
  36. package/dist/orchestrator/VideoClipSession.d.ts +0 -2
  37. package/dist/orchestrator/VideoClipSession.d.ts.map +1 -1
  38. package/dist/orchestrator/VideoClipSession.js +0 -49
  39. package/dist/orchestrator/VideoClipSession.js.map +1 -1
  40. package/dist/stages/compose/OfflineAudioMixer.d.ts.map +1 -1
  41. package/dist/stages/compose/OfflineAudioMixer.js +13 -18
  42. package/dist/stages/compose/OfflineAudioMixer.js.map +1 -1
  43. package/dist/stages/decode/AudioChunkDecoder.js +169 -0
  44. package/dist/stages/decode/AudioChunkDecoder.js.map +1 -0
  45. package/dist/stages/demux/MP3FrameParser.js +186 -0
  46. package/dist/stages/demux/MP3FrameParser.js.map +1 -0
  47. package/dist/stages/load/ResourceLoader.d.ts +20 -9
  48. package/dist/stages/load/ResourceLoader.d.ts.map +1 -1
  49. package/dist/stages/load/ResourceLoader.js +92 -135
  50. package/dist/stages/load/ResourceLoader.js.map +1 -1
  51. package/dist/stages/load/types.d.ts +1 -0
  52. package/dist/stages/load/types.d.ts.map +1 -1
  53. package/dist/utils/audio-data.d.ts +16 -0
  54. package/dist/utils/audio-data.d.ts.map +1 -0
  55. package/dist/utils/audio-data.js +111 -0
  56. package/dist/utils/audio-data.js.map +1 -0
  57. package/package.json +1 -1
  58. package/dist/cache/resource/ImageBitmapCache.d.ts +0 -65
  59. package/dist/cache/resource/ImageBitmapCache.d.ts.map +0 -1
  60. package/dist/cache/resource/ImageBitmapCache.js +0 -101
  61. package/dist/cache/resource/ImageBitmapCache.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"ExportScheduler.js","sources":["../../src/orchestrator/ExportScheduler.ts"],"sourcesContent":["import { CompositionModel } from '../model';\nimport { ExportOptions } from '../types';\nimport { WorkerPool } from '../worker/WorkerPool';\nimport { CompositionPlanner } from './CompositionPlanner';\nimport { CacheManager } from '../cache/CacheManager';\nimport { ResourceLoader } from '../stages/load/ResourceLoader';\nimport { MuxManager } from '../stages/mux/MuxManager';\nimport { GlobalAudioSession } from './GlobalAudioSession';\nimport { VideoClipSession } from './VideoClipSession';\nimport { WorkerType } from '../worker/types';\nimport { hasResourceId } from '../model/types';\nimport type { ExportController } from '../controllers/ExportController';\nimport { EventBus } from '../event/EventBus';\nimport { MeframeEvent, EventPayloadMap } from '../event/events';\n\ninterface ExportSchedulerDeps {\n workerPool: WorkerPool;\n planner: CompositionPlanner;\n cacheManager: CacheManager;\n resourceLoader: ResourceLoader;\n muxManager: MuxManager;\n audioSession: GlobalAudioSession;\n workerConfigsProvider: () => Record<WorkerType, any>;\n eventBus: EventBus<EventPayloadMap>;\n}\n\ninterface ExtendedExportOptions extends ExportOptions {\n signal?: AbortSignal;\n controller?: ExportController;\n}\n\nexport class ExportScheduler {\n private deps: ExportSchedulerDeps;\n\n constructor(deps: ExportSchedulerDeps) {\n this.deps = deps;\n }\n\n async execute(model: CompositionModel, options: ExtendedExportOptions): Promise<Blob> {\n const { muxManager, audioSession, resourceLoader, eventBus } = this.deps;\n const signal = options.signal;\n const controller = options.controller;\n\n const checkStatus = async () => {\n if (signal?.aborted) {\n throw new DOMException('Export aborted', 'AbortError');\n }\n if (controller?.isPaused()) {\n // Wait until resumed\n while (controller.isPaused()) {\n if (signal?.aborted) throw new DOMException('Export aborted', 'AbortError');\n await new Promise((resolve) => setTimeout(resolve, 100));\n }\n }\n };\n\n const width = options.width || model.renderConfig?.width || 720;\n const height = options.height || model.renderConfig?.height || 1280;\n const fps = options.fps || model.fps || 30;\n\n eventBus.emit(MeframeEvent.ExportStart, {\n format: options.format || 'mp4',\n width,\n height,\n fps,\n durationUs: model.durationUs,\n });\n\n try {\n // 1. Start Muxer\n muxManager.start({\n width,\n height,\n fps,\n });\n\n // 2. Preload Audio Tracks (BGM/Speech)\n // Identify pure audio clips and start downloading them immediately\n // This ensures BGM is ready when we need to mix it with video clips\n for (const track of model.tracks) {\n if (track.kind === 'audio') {\n for (const clip of track.clips) {\n if (hasResourceId(clip)) {\n // Fire and forget - we don't await here, let them download in background\n // GlobalAudioSession will wait for them if needed during mixing\n resourceLoader.fetch(clip.resourceId, {\n priority: 'high',\n clipId: clip.id,\n trackId: clip.trackId,\n });\n }\n }\n }\n }\n\n // 3. Process Video Clips (Sequential) and Audio (Interleaved)\n const videoTrack = model.tracks.find((t) => t.kind === 'video');\n if (videoTrack && videoTrack.clips.length > 0) {\n await this.processVideoClipsSequentially(\n videoTrack.clips,\n muxManager,\n model,\n checkStatus,\n audioSession\n );\n } else {\n console.warn('[ExportScheduler] No video clips found');\n }\n\n // Finalize audio session (close encoder)\n await audioSession.finalizeExportAudio();\n\n if (signal?.aborted) {\n throw new DOMException('Export aborted', 'AbortError');\n }\n\n // 4. Finalize\n const blob = await muxManager.finalize();\n\n eventBus.emit(MeframeEvent.ExportComplete, {\n size: blob.size,\n durationMs: model.durationUs / 1000,\n format: options.format || 'mp4',\n });\n\n return blob;\n } catch (error) {\n eventBus.emit(MeframeEvent.ExportError, {\n error: error instanceof Error ? error : new Error(String(error)),\n stage: 'export',\n });\n throw error;\n }\n }\n\n private async processVideoClipsSequentially(\n clips: any[],\n muxManager: MuxManager,\n model: CompositionModel,\n checkStatus: () => Promise<void>,\n audioSession: GlobalAudioSession\n ) {\n let accumulatedDurationUs = 0;\n\n for (let i = 0; i < clips.length; i++) {\n const clip = clips[i];\n const nextClip = clips[i + 1];\n\n await checkStatus(); // Check before starting new clip\n\n // --- Preload Next Clip ---\n // Start downloading next clip's resource while current clip is processing\n if (nextClip && hasResourceId(nextClip)) {\n // Fire and forget - ResourceLoader handles deduping\n this.deps.resourceLoader.fetch(nextClip.resourceId, {\n priority: 'normal',\n clipId: nextClip.id,\n trackId: nextClip.trackId,\n isMainTrack: true,\n });\n }\n // -------------------------\n\n const sessionId = `${clip.id}-export`;\n let streamFinishedResolver: () => void;\n let streamFinishedRejecter: (err: any) => void;\n const streamFinishedPromise = new Promise<void>((resolve, reject) => {\n streamFinishedResolver = resolve;\n streamFinishedRejecter = reject;\n });\n\n let audioFinishedResolver: () => void;\n const audioFinishedPromise = new Promise<void>((resolve) => {\n audioFinishedResolver = resolve;\n });\n let audioStreamStarted = false;\n\n const session = await VideoClipSession.create({\n clipId: clip.id,\n sessionId,\n forL2Only: true,\n planner: this.deps.planner,\n workerPool: this.deps.workerPool,\n cacheManager: this.deps.cacheManager,\n compositionModel: model,\n workerConfigs: this.deps.workerConfigsProvider(),\n callbacks: {\n onComposedStreamReady: async () => {},\n onEncodedStreamReady: async (stream, track) => {\n if (track === 'video') {\n const reader = stream.getReader();\n try {\n while (true) {\n await checkStatus();\n\n const { done, value } = await reader.read();\n if (done) break;\n if (value) {\n const originalChunk = value.chunk;\n const metadata = value.metadata;\n\n const buffer = new ArrayBuffer(originalChunk.byteLength);\n originalChunk.copyTo(buffer);\n\n const remappedChunk = new EncodedVideoChunk({\n type: originalChunk.type,\n timestamp: originalChunk.timestamp + accumulatedDurationUs,\n duration: originalChunk.duration ?? undefined,\n data: buffer,\n });\n\n muxManager.writeVideoChunk(remappedChunk, metadata);\n\n // Emit progress\n const progress = Math.min(\n 1.0,\n (accumulatedDurationUs + originalChunk.timestamp) / model.durationUs\n );\n this.deps.eventBus.emit(MeframeEvent.ExportProgress, {\n progress,\n stage: 'muxing',\n timeUs: accumulatedDurationUs + originalChunk.timestamp,\n });\n }\n }\n streamFinishedResolver();\n } catch (error) {\n if (error instanceof DOMException && error.name === 'AbortError') {\n streamFinishedRejecter(error);\n } else {\n console.error(`[ExportScheduler] Stream error for clip ${clip.id}:`, error);\n streamFinishedRejecter(error);\n }\n } finally {\n reader.releaseLock();\n }\n }\n },\n onAudioStreamReady: (stream, metadata) => {\n audioStreamStarted = true;\n // Handle audio stream from VideoClipSession (AudioDecodeWorker)\n const reader = stream.getReader();\n const pump = async () => {\n try {\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n if (value) {\n // Put into CacheManager immediately so GlobalAudioSession can find it\n // Use clipId as sessionId because GlobalAudioSession expects that\n this.deps.cacheManager.putClipAudioData(\n clip.id, // Use clip.id, NOT sessionId (which is clipId-export)\n value,\n metadata.clipDurationUs\n );\n }\n }\n } catch (e) {\n console.error('[ExportScheduler] Audio stream error', e);\n } finally {\n reader.releaseLock();\n audioFinishedResolver(); // Signal audio stream completion\n }\n };\n pump();\n },\n onPipelineReady: async (attachmentResourceIds) => {\n // Load Main Track Resource\n if (hasResourceId(clip)) {\n await this.deps.resourceLoader.fetch(clip.resourceId, {\n priority: 'high',\n sessionId,\n clipId: clip.id,\n trackId: clip.trackId,\n isMainTrack: true,\n });\n }\n\n // Load Attachment Resources\n if (attachmentResourceIds) {\n for (const rid of attachmentResourceIds) {\n await this.deps.resourceLoader.fetch(rid, {\n priority: 'normal',\n sessionId,\n clipId: clip.id,\n isMainTrack: false,\n });\n }\n }\n },\n },\n });\n\n try {\n await session.activate();\n\n await streamFinishedPromise;\n\n // If audio stream started, we wait for it to finish.\n // This ensures we capture the tail of the audio.\n if (audioStreamStarted) {\n // Use a race with timeout to prevent hanging indefinitely if audio stream is stuck\n await Promise.race([\n audioFinishedPromise,\n new Promise((resolve) => setTimeout(resolve, 5000)), // 5s timeout for audio tail\n ]);\n } else {\n // If audio didn't start, maybe it's a silent clip, or audio init failed.\n // We just proceed.\n }\n\n // Mix and encode audio for this segment\n await audioSession.mixAndEncodeSegment(\n accumulatedDurationUs,\n accumulatedDurationUs + clip.durationUs,\n (chunk, meta) => muxManager.writeAudioChunk(chunk, meta)\n );\n } finally {\n await session.dispose();\n }\n\n accumulatedDurationUs += clip.durationUs;\n }\n }\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ExportScheduler.js","sources":["../../src/orchestrator/ExportScheduler.ts"],"sourcesContent":["import { CompositionModel } from '../model';\nimport { ExportOptions } from '../types';\nimport { WorkerPool } from '../worker/WorkerPool';\nimport { CompositionPlanner } from './CompositionPlanner';\nimport { CacheManager } from '../cache/CacheManager';\nimport { ResourceLoader } from '../stages/load/ResourceLoader';\nimport { MuxManager } from '../stages/mux/MuxManager';\nimport { GlobalAudioSession } from './GlobalAudioSession';\nimport { VideoClipSession } from './VideoClipSession';\nimport { WorkerType } from '../worker/types';\nimport { hasResourceId, type TimeUs } from '../model/types';\nimport type { ExportController } from '../controllers/ExportController';\nimport { EventBus } from '../event/EventBus';\nimport { MeframeEvent, EventPayloadMap } from '../event/events';\n\ninterface ExportSchedulerDeps {\n workerPool: WorkerPool;\n planner: CompositionPlanner;\n cacheManager: CacheManager;\n resourceLoader: ResourceLoader;\n muxManager: MuxManager;\n audioSession: GlobalAudioSession;\n workerConfigsProvider: () => Record<WorkerType, any>;\n eventBus: EventBus<EventPayloadMap>;\n}\n\ninterface ExtendedExportOptions extends ExportOptions {\n signal?: AbortSignal;\n controller?: ExportController;\n}\n\nexport class ExportScheduler {\n private deps: ExportSchedulerDeps;\n\n constructor(deps: ExportSchedulerDeps) {\n this.deps = deps;\n }\n\n async execute(model: CompositionModel, options: ExtendedExportOptions): Promise<Blob> {\n const { muxManager, audioSession, eventBus, resourceLoader } = this.deps;\n const signal = options.signal;\n const controller = options.controller;\n\n const checkStatus = async () => {\n if (signal?.aborted) {\n throw new DOMException('Export aborted', 'AbortError');\n }\n if (controller?.isPaused()) {\n // Wait until resumed\n while (controller.isPaused()) {\n if (signal?.aborted) throw new DOMException('Export aborted', 'AbortError');\n await new Promise((resolve) => setTimeout(resolve, 100));\n }\n }\n };\n\n const width = options.width || model.renderConfig?.width || 720;\n const height = options.height || model.renderConfig?.height || 1280;\n const fps = options.fps || model.fps || 30;\n\n eventBus.emit(MeframeEvent.ExportStart, {\n format: options.format || 'mp4',\n width,\n height,\n fps,\n durationUs: model.durationUs,\n });\n\n try {\n // 1. Preload and parse all resources (ensures OPFS + AudioSampleCache + MP4IndexCache)\n eventBus.emit(MeframeEvent.ExportProgress, {\n progress: 0,\n stage: 'preparing',\n message: 'Loading and parsing resources...',\n });\n\n const allResourceIds = new Set<string>();\n for (const track of model.tracks) {\n for (const clip of track.clips) {\n if (hasResourceId(clip)) {\n allResourceIds.add(clip.resourceId);\n }\n }\n }\n\n // Parallel loading and parsing\n // fetch() now returns Promise that resolves after parsing completes\n await Promise.all(\n Array.from(allResourceIds).map((rid) => resourceLoader.fetch(rid, { priority: 'high' }))\n );\n\n // 2. Start Muxer\n muxManager.start({\n width,\n height,\n fps,\n });\n\n // 3. Process Video and Audio\n const mainTrack = model.tracks.find((t) => t.id === model.mainTrackId);\n if (mainTrack && mainTrack.clips.length > 0) {\n // Process audio with 60s windows (balance quality and memory)\n const audioPromise = this.processAudioInWindows(\n model.durationUs,\n audioSession,\n muxManager,\n checkStatus\n );\n\n // Process video clips sequentially\n await this.processVideoClipsSequentially(mainTrack.clips, muxManager, model, checkStatus);\n\n // Wait for audio encoding to complete\n await audioPromise;\n } else {\n console.warn('[ExportScheduler] No video clips found');\n }\n\n // Finalize audio session (close encoder)\n await audioSession.finalizeExportAudio();\n\n if (signal?.aborted) {\n throw new DOMException('Export aborted', 'AbortError');\n }\n\n // 4. Finalize\n const blob = await muxManager.finalize();\n\n eventBus.emit(MeframeEvent.ExportComplete, {\n size: blob.size,\n durationMs: model.durationUs / 1000,\n format: options.format || 'mp4',\n });\n\n return blob;\n } catch (error) {\n eventBus.emit(MeframeEvent.ExportError, {\n error: error instanceof Error ? error : new Error(String(error)),\n stage: 'export',\n });\n throw error;\n }\n }\n\n /**\n * Process audio in 60-second windows\n * - Videos ≤60s: Single pass (zero boundaries)\n * - Videos >60s: 60s windows (minimal boundaries, ~23MB per window)\n */\n private async processAudioInWindows(\n totalDurationUs: TimeUs,\n audioSession: GlobalAudioSession,\n muxManager: MuxManager,\n checkStatus: () => Promise<void>\n ): Promise<void> {\n const WINDOW_DURATION_US = 60_000_000; // 60 seconds\n let currentUs = 0;\n\n while (currentUs < totalDurationUs) {\n await checkStatus();\n\n const endUs = Math.min(currentUs + WINDOW_DURATION_US, totalDurationUs);\n\n await audioSession.mixAndEncodeSegment(currentUs, endUs, (chunk, meta) =>\n muxManager.writeAudioChunk(chunk, meta)\n );\n\n currentUs = endUs;\n }\n }\n\n private async processVideoClipsSequentially(\n clips: any[],\n muxManager: MuxManager,\n model: CompositionModel,\n checkStatus: () => Promise<void>\n ) {\n let accumulatedDurationUs = 0;\n\n for (let i = 0; i < clips.length; i++) {\n const clip = clips[i];\n const nextClip = clips[i + 1];\n\n await checkStatus(); // Check before starting new clip\n\n // --- Preload Next Clip ---\n // Start downloading next clip's resource while current clip is processing\n if (nextClip && hasResourceId(nextClip)) {\n // Fire and forget - ResourceLoader handles deduping\n this.deps.resourceLoader.fetch(nextClip.resourceId, {\n priority: 'normal',\n clipId: nextClip.id,\n trackId: nextClip.trackId,\n isMainTrack: true,\n });\n }\n // -------------------------\n\n const sessionId = `${clip.id}-export`;\n let streamFinishedResolver: () => void;\n let streamFinishedRejecter: (err: any) => void;\n const streamFinishedPromise = new Promise<void>((resolve, reject) => {\n streamFinishedResolver = resolve;\n streamFinishedRejecter = reject;\n });\n\n const session = await VideoClipSession.create({\n clipId: clip.id,\n sessionId,\n forL2Only: true,\n planner: this.deps.planner,\n workerPool: this.deps.workerPool,\n cacheManager: this.deps.cacheManager,\n compositionModel: model,\n workerConfigs: this.deps.workerConfigsProvider(),\n callbacks: {\n onComposedStreamReady: async () => {},\n onEncodedStreamReady: async (stream, track) => {\n if (track === 'video') {\n const reader = stream.getReader();\n try {\n while (true) {\n await checkStatus();\n\n const { done, value } = await reader.read();\n if (done) break;\n if (value) {\n const originalChunk = value.chunk;\n const metadata = value.metadata;\n\n const buffer = new ArrayBuffer(originalChunk.byteLength);\n originalChunk.copyTo(buffer);\n\n const remappedChunk = new EncodedVideoChunk({\n type: originalChunk.type,\n timestamp: originalChunk.timestamp + accumulatedDurationUs,\n duration: originalChunk.duration ?? undefined,\n data: buffer,\n });\n\n muxManager.writeVideoChunk(remappedChunk, metadata);\n\n // Emit progress\n const progress = Math.min(\n 1.0,\n (accumulatedDurationUs + originalChunk.timestamp) / model.durationUs\n );\n this.deps.eventBus.emit(MeframeEvent.ExportProgress, {\n progress,\n stage: 'muxing',\n timeUs: accumulatedDurationUs + originalChunk.timestamp,\n });\n }\n }\n streamFinishedResolver();\n } catch (error) {\n if (error instanceof DOMException && error.name === 'AbortError') {\n streamFinishedRejecter(error);\n } else {\n console.error(`[ExportScheduler] Stream error for clip ${clip.id}:`, error);\n streamFinishedRejecter(error);\n }\n } finally {\n reader.releaseLock();\n }\n }\n },\n onPipelineReady: async (attachmentResourceIds) => {\n // Load Main Track Resource\n if (hasResourceId(clip)) {\n await this.deps.resourceLoader.fetch(clip.resourceId, {\n priority: 'high',\n sessionId,\n clipId: clip.id,\n trackId: clip.trackId,\n isMainTrack: true,\n });\n }\n\n // Load Attachment Resources\n if (attachmentResourceIds) {\n for (const rid of attachmentResourceIds) {\n await this.deps.resourceLoader.fetch(rid, {\n priority: 'normal',\n sessionId,\n clipId: clip.id,\n isMainTrack: false,\n });\n }\n }\n },\n },\n });\n\n try {\n await session.activate();\n await streamFinishedPromise;\n } finally {\n await session.dispose();\n }\n\n accumulatedDurationUs += clip.durationUs;\n }\n }\n}\n"],"names":[],"mappings":";;;AA+BO,MAAM,gBAAgB;AAAA,EACnB;AAAA,EAER,YAAY,MAA2B;AACrC,SAAK,OAAO;AAAA,EACd;AAAA,EAEA,MAAM,QAAQ,OAAyB,SAA+C;AACpF,UAAM,EAAE,YAAY,cAAc,UAAU,eAAA,IAAmB,KAAK;AACpE,UAAM,SAAS,QAAQ;AACvB,UAAM,aAAa,QAAQ;AAE3B,UAAM,cAAc,YAAY;AAC9B,UAAI,QAAQ,SAAS;AACnB,cAAM,IAAI,aAAa,kBAAkB,YAAY;AAAA,MACvD;AACA,UAAI,YAAY,YAAY;AAE1B,eAAO,WAAW,YAAY;AAC5B,cAAI,QAAQ,QAAS,OAAM,IAAI,aAAa,kBAAkB,YAAY;AAC1E,gBAAM,IAAI,QAAQ,CAAC,YAAY,WAAW,SAAS,GAAG,CAAC;AAAA,QACzD;AAAA,MACF;AAAA,IACF;AAEA,UAAM,QAAQ,QAAQ,SAAS,MAAM,cAAc,SAAS;AAC5D,UAAM,SAAS,QAAQ,UAAU,MAAM,cAAc,UAAU;AAC/D,UAAM,MAAM,QAAQ,OAAO,MAAM,OAAO;AAExC,aAAS,KAAK,aAAa,aAAa;AAAA,MACtC,QAAQ,QAAQ,UAAU;AAAA,MAC1B;AAAA,MACA;AAAA,MACA;AAAA,MACA,YAAY,MAAM;AAAA,IAAA,CACnB;AAED,QAAI;AAEF,eAAS,KAAK,aAAa,gBAAgB;AAAA,QACzC,UAAU;AAAA,QACV,OAAO;AAAA,QACP,SAAS;AAAA,MAAA,CACV;AAED,YAAM,qCAAqB,IAAA;AAC3B,iBAAW,SAAS,MAAM,QAAQ;AAChC,mBAAW,QAAQ,MAAM,OAAO;AAC9B,cAAI,cAAc,IAAI,GAAG;AACvB,2BAAe,IAAI,KAAK,UAAU;AAAA,UACpC;AAAA,QACF;AAAA,MACF;AAIA,YAAM,QAAQ;AAAA,QACZ,MAAM,KAAK,cAAc,EAAE,IAAI,CAAC,QAAQ,eAAe,MAAM,KAAK,EAAE,UAAU,OAAA,CAAQ,CAAC;AAAA,MAAA;AAIzF,iBAAW,MAAM;AAAA,QACf;AAAA,QACA;AAAA,QACA;AAAA,MAAA,CACD;AAGD,YAAM,YAAY,MAAM,OAAO,KAAK,CAAC,MAAM,EAAE,OAAO,MAAM,WAAW;AACrE,UAAI,aAAa,UAAU,MAAM,SAAS,GAAG;AAE3C,cAAM,eAAe,KAAK;AAAA,UACxB,MAAM;AAAA,UACN;AAAA,UACA;AAAA,UACA;AAAA,QAAA;AAIF,cAAM,KAAK,8BAA8B,UAAU,OAAO,YAAY,OAAO,WAAW;AAGxF,cAAM;AAAA,MACR,OAAO;AACL,gBAAQ,KAAK,wCAAwC;AAAA,MACvD;AAGA,YAAM,aAAa,oBAAA;AAEnB,UAAI,QAAQ,SAAS;AACnB,cAAM,IAAI,aAAa,kBAAkB,YAAY;AAAA,MACvD;AAGA,YAAM,OAAO,MAAM,WAAW,SAAA;AAE9B,eAAS,KAAK,aAAa,gBAAgB;AAAA,QACzC,MAAM,KAAK;AAAA,QACX,YAAY,MAAM,aAAa;AAAA,QAC/B,QAAQ,QAAQ,UAAU;AAAA,MAAA,CAC3B;AAED,aAAO;AAAA,IACT,SAAS,OAAO;AACd,eAAS,KAAK,aAAa,aAAa;AAAA,QACtC,OAAO,iBAAiB,QAAQ,QAAQ,IAAI,MAAM,OAAO,KAAK,CAAC;AAAA,QAC/D,OAAO;AAAA,MAAA,CACR;AACD,YAAM;AAAA,IACR;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAc,sBACZ,iBACA,cACA,YACA,aACe;AACf,UAAM,qBAAqB;AAC3B,QAAI,YAAY;AAEhB,WAAO,YAAY,iBAAiB;AAClC,YAAM,YAAA;AAEN,YAAM,QAAQ,KAAK,IAAI,YAAY,oBAAoB,eAAe;AAEtE,YAAM,aAAa;AAAA,QAAoB;AAAA,QAAW;AAAA,QAAO,CAAC,OAAO,SAC/D,WAAW,gBAAgB,OAAO,IAAI;AAAA,MAAA;AAGxC,kBAAY;AAAA,IACd;AAAA,EACF;AAAA,EAEA,MAAc,8BACZ,OACA,YACA,OACA,aACA;AACA,QAAI,wBAAwB;AAE5B,aAAS,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK;AACrC,YAAM,OAAO,MAAM,CAAC;AACpB,YAAM,WAAW,MAAM,IAAI,CAAC;AAE5B,YAAM,YAAA;AAIN,UAAI,YAAY,cAAc,QAAQ,GAAG;AAEvC,aAAK,KAAK,eAAe,MAAM,SAAS,YAAY;AAAA,UAClD,UAAU;AAAA,UACV,QAAQ,SAAS;AAAA,UACjB,SAAS,SAAS;AAAA,UAClB,aAAa;AAAA,QAAA,CACd;AAAA,MACH;AAGA,YAAM,YAAY,GAAG,KAAK,EAAE;AAC5B,UAAI;AACJ,UAAI;AACJ,YAAM,wBAAwB,IAAI,QAAc,CAAC,SAAS,WAAW;AACnE,iCAAyB;AACzB,iCAAyB;AAAA,MAC3B,CAAC;AAED,YAAM,UAAU,MAAM,iBAAiB,OAAO;AAAA,QAC5C,QAAQ,KAAK;AAAA,QACb;AAAA,QACA,WAAW;AAAA,QACX,SAAS,KAAK,KAAK;AAAA,QACnB,YAAY,KAAK,KAAK;AAAA,QACtB,cAAc,KAAK,KAAK;AAAA,QACxB,kBAAkB;AAAA,QAClB,eAAe,KAAK,KAAK,sBAAA;AAAA,QACzB,WAAW;AAAA,UACT,uBAAuB,YAAY;AAAA,UAAC;AAAA,UACpC,sBAAsB,OAAO,QAAQ,UAAU;AAC7C,gBAAI,UAAU,SAAS;AACrB,oBAAM,SAAS,OAAO,UAAA;AACtB,kBAAI;AACF,uBAAO,MAAM;AACX,wBAAM,YAAA;AAEN,wBAAM,EAAE,MAAM,MAAA,IAAU,MAAM,OAAO,KAAA;AACrC,sBAAI,KAAM;AACV,sBAAI,OAAO;AACT,0BAAM,gBAAgB,MAAM;AAC5B,0BAAM,WAAW,MAAM;AAEvB,0BAAM,SAAS,IAAI,YAAY,cAAc,UAAU;AACvD,kCAAc,OAAO,MAAM;AAE3B,0BAAM,gBAAgB,IAAI,kBAAkB;AAAA,sBAC1C,MAAM,cAAc;AAAA,sBACpB,WAAW,cAAc,YAAY;AAAA,sBACrC,UAAU,cAAc,YAAY;AAAA,sBACpC,MAAM;AAAA,oBAAA,CACP;AAED,+BAAW,gBAAgB,eAAe,QAAQ;AAGlD,0BAAM,WAAW,KAAK;AAAA,sBACpB;AAAA,uBACC,wBAAwB,cAAc,aAAa,MAAM;AAAA,oBAAA;AAE5D,yBAAK,KAAK,SAAS,KAAK,aAAa,gBAAgB;AAAA,sBACnD;AAAA,sBACA,OAAO;AAAA,sBACP,QAAQ,wBAAwB,cAAc;AAAA,oBAAA,CAC/C;AAAA,kBACH;AAAA,gBACF;AACA,uCAAA;AAAA,cACF,SAAS,OAAO;AACd,oBAAI,iBAAiB,gBAAgB,MAAM,SAAS,cAAc;AAChE,yCAAuB,KAAK;AAAA,gBAC9B,OAAO;AACL,0BAAQ,MAAM,2CAA2C,KAAK,EAAE,KAAK,KAAK;AAC1E,yCAAuB,KAAK;AAAA,gBAC9B;AAAA,cACF,UAAA;AACE,uBAAO,YAAA;AAAA,cACT;AAAA,YACF;AAAA,UACF;AAAA,UACA,iBAAiB,OAAO,0BAA0B;AAEhD,gBAAI,cAAc,IAAI,GAAG;AACvB,oBAAM,KAAK,KAAK,eAAe,MAAM,KAAK,YAAY;AAAA,gBACpD,UAAU;AAAA,gBACV;AAAA,gBACA,QAAQ,KAAK;AAAA,gBACb,SAAS,KAAK;AAAA,gBACd,aAAa;AAAA,cAAA,CACd;AAAA,YACH;AAGA,gBAAI,uBAAuB;AACzB,yBAAW,OAAO,uBAAuB;AACvC,sBAAM,KAAK,KAAK,eAAe,MAAM,KAAK;AAAA,kBACxC,UAAU;AAAA,kBACV;AAAA,kBACA,QAAQ,KAAK;AAAA,kBACb,aAAa;AAAA,gBAAA,CACd;AAAA,cACH;AAAA,YACF;AAAA,UACF;AAAA,QAAA;AAAA,MACF,CACD;AAED,UAAI;AACF,cAAM,QAAQ,SAAA;AACd,cAAM;AAAA,MACR,UAAA;AACE,cAAM,QAAQ,QAAA;AAAA,MAChB;AAEA,+BAAyB,KAAK;AAAA,IAChC;AAAA,EACF;AACF;"}
@@ -22,29 +22,37 @@ interface AudioSessionDeps {
22
22
  export declare class GlobalAudioSession {
23
23
  private mixer;
24
24
  private activeClips;
25
- private streamEndedClips;
26
25
  private deps;
27
26
  private model;
28
27
  private audioContext;
29
- private audioSources;
30
- private audioGainNodes;
31
28
  private volume;
32
29
  private playbackRate;
33
30
  private isPlaying;
34
- private currentPlaybackTimeUs;
35
- private ensuringClips;
31
+ private nextScheduleTime;
32
+ private nextContentTimeUs;
33
+ private scheduledSources;
34
+ private readonly LOOKAHEAD_TIME;
35
+ private readonly CHUNK_DURATION;
36
36
  constructor(deps: AudioSessionDeps);
37
37
  setModel(model: CompositionModel): void;
38
38
  onAudioData(message: AudioDataMessage): void;
39
- ensureAudioForTime(timeUs: TimeUs): Promise<void>;
39
+ ensureAudioForTime(timeUs: TimeUs, options?: {
40
+ immediate?: boolean;
41
+ }): Promise<void>;
40
42
  activateAllAudioClips(): Promise<void>;
41
43
  deactivateClip(clipId: string): Promise<void>;
42
- restartPlayingClip(clipId: string, currentTimeUs?: TimeUs): void;
43
- private stopClipAudioSources;
44
- handleAudioStream(stream: ReadableStream<AudioData>, metadata: Record<string, any>): void;
45
44
  startPlayback(timeUs: TimeUs, audioContext: AudioContext): Promise<void>;
46
45
  stopPlayback(): void;
47
- updateTime(timeUs: TimeUs): void;
46
+ updateTime(_timeUs: TimeUs): void;
47
+ /**
48
+ * Schedule audio chunks ahead of playback cursor
49
+ * Uses OfflineAudioMixer for proper mixing, then plays the result
50
+ */
51
+ scheduleAudio(currentTimelineUs: TimeUs, audioContext: AudioContext): Promise<void>;
52
+ /**
53
+ * Reset playback states (called on seek)
54
+ */
55
+ resetPlaybackStates(): void;
48
56
  setVolume(volume: number): void;
49
57
  setPlaybackRate(rate: number): void;
50
58
  reset(): void;
@@ -52,40 +60,39 @@ export declare class GlobalAudioSession {
52
60
  * Mix and encode audio for a specific segment (used by ExportScheduler)
53
61
  */
54
62
  mixAndEncodeSegment(startUs: TimeUs, endUs: TimeUs, onChunk: (chunk: EncodedAudioChunk, metadata?: EncodedAudioChunkMetadata) => void): Promise<void>;
63
+ /**
64
+ * Ensure audio clips in time range are decoded (for export)
65
+ * Decodes from AudioSampleCache (replaces Worker pipeline)
66
+ */
67
+ private ensureAudioForSegment;
55
68
  private exportEncoder;
56
69
  private exportEncoderStream;
57
70
  private exportEncoderWriter;
58
71
  private startExportEncoderReader;
59
72
  finalizeExportAudio(): Promise<void>;
60
- /**
61
- * Create export audio stream
62
- */
63
- createExportAudioStream(): Promise<ReadableStream<AudioData> | null>;
64
- private waitForAudioClipsReady;
65
- private waitForClipPCM;
66
- private startAllActiveClips;
67
- private checkAndStartNewClips;
68
- private startClipPlayback;
69
73
  private stopAllAudioSources;
70
- private getActiveAudioClips;
71
74
  /**
72
- * Ensure PCM for a clip is available
73
- * Priority: AudioSampleCache (Resource) > L2 > None
75
+ * Ensure audio window for a clip (aligned with video architecture)
76
+ *
77
+ * Note: Unlike video getFrame(), this method doesn't need a 'preheat' parameter
78
+ * Why: Audio cache check is window-level (range query) via hasWindowPCM()
79
+ * It verifies the entire window has ≥80% data, not just a single point
80
+ * This naturally prevents premature return during preheating
74
81
  */
75
- ensureClipAudio(clipId: string): Promise<void>;
82
+ ensureAudioWindow(clipId: string, startUs: TimeUs, endUs: TimeUs): Promise<void>;
76
83
  /**
77
- * Ensure PCM from AudioSampleCache (Resource-level)
78
- * Returns true if successful
84
+ * Decode audio window for a clip (aligned with video architecture)
85
+ * Simple strategy: decode entire window range, cache handles duplicates
79
86
  */
80
- private ensureClipAudioFromResource;
87
+ private decodeAudioWindow;
81
88
  /**
82
89
  * Decode audio samples to PCM and cache
90
+ * Uses AudioChunkDecoder for consistency with project architecture
91
+ * Resamples to AudioContext sample rate if needed for better quality
83
92
  */
84
93
  private decodeAudioSamples;
85
- private pcmToAudioBuffer;
86
94
  private audioBufferToAudioData;
87
95
  private interleavePlanarData;
88
- private setupAudioPipeline;
89
96
  }
90
97
  export {};
91
98
  //# sourceMappingURL=GlobalAudioSession.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"GlobalAudioSession.d.ts","sourceRoot":"","sources":["../../src/orchestrator/GlobalAudioSession.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"GlobalAudioSession.d.ts","sourceRoot":"","sources":["../../src/orchestrator/GlobalAudioSession.ts"],"names":[],"mappings":"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"}