@meframe/core 0.0.1
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/CHANGELOG.md +42 -0
- package/LICENSE +22 -0
- package/README.md +396 -0
- package/dist/Meframe.d.ts +82 -0
- package/dist/Meframe.d.ts.map +1 -0
- package/dist/Meframe.js +290 -0
- package/dist/Meframe.js.map +1 -0
- package/dist/_virtual/mp4box.all.js +5 -0
- package/dist/_virtual/mp4box.all.js.map +1 -0
- package/dist/cache/BatchWriter.d.ts +25 -0
- package/dist/cache/BatchWriter.d.ts.map +1 -0
- package/dist/cache/CacheManager.d.ts +115 -0
- package/dist/cache/CacheManager.d.ts.map +1 -0
- package/dist/cache/CacheManager.js +388 -0
- package/dist/cache/CacheManager.js.map +1 -0
- package/dist/cache/CacheStatsDecorator.d.ts +27 -0
- package/dist/cache/CacheStatsDecorator.d.ts.map +1 -0
- package/dist/cache/L2Cache.d.ts +39 -0
- package/dist/cache/L2Cache.d.ts.map +1 -0
- package/dist/cache/L2Cache.js +282 -0
- package/dist/cache/L2Cache.js.map +1 -0
- package/dist/cache/index.d.ts +7 -0
- package/dist/cache/index.d.ts.map +1 -0
- package/dist/cache/l1/AudioL1Cache.d.ts +30 -0
- package/dist/cache/l1/AudioL1Cache.d.ts.map +1 -0
- package/dist/cache/l1/AudioL1Cache.js +306 -0
- package/dist/cache/l1/AudioL1Cache.js.map +1 -0
- package/dist/cache/l1/MixedAudioL1Cache.d.ts +13 -0
- package/dist/cache/l1/MixedAudioL1Cache.d.ts.map +1 -0
- package/dist/cache/l1/MixedAudioL1Cache.js +52 -0
- package/dist/cache/l1/MixedAudioL1Cache.js.map +1 -0
- package/dist/cache/l1/VideoL1Cache.d.ts +69 -0
- package/dist/cache/l1/VideoL1Cache.d.ts.map +1 -0
- package/dist/cache/l1/VideoL1Cache.js +318 -0
- package/dist/cache/l1/VideoL1Cache.js.map +1 -0
- package/dist/cache/l1/gop-utils.d.ts +10 -0
- package/dist/cache/l1/gop-utils.d.ts.map +1 -0
- package/dist/cache/l1/gop-utils.js +78 -0
- package/dist/cache/l1/gop-utils.js.map +1 -0
- package/dist/cache/l1/index.d.ts +4 -0
- package/dist/cache/l1/index.d.ts.map +1 -0
- package/dist/cache/l1/types.d.ts +17 -0
- package/dist/cache/l1/types.d.ts.map +1 -0
- package/dist/cache/types.d.ts +93 -0
- package/dist/cache/types.d.ts.map +1 -0
- package/dist/config/ConfigLoader.d.ts +69 -0
- package/dist/config/ConfigLoader.d.ts.map +1 -0
- package/dist/config/ConfigLoader.js +133 -0
- package/dist/config/ConfigLoader.js.map +1 -0
- package/dist/config/defaults.d.ts +125 -0
- package/dist/config/defaults.d.ts.map +1 -0
- package/dist/config/defaults.js +191 -0
- package/dist/config/defaults.js.map +1 -0
- package/dist/config/index.d.ts +6 -0
- package/dist/config/index.d.ts.map +1 -0
- package/dist/config/presets.d.ts +32 -0
- package/dist/config/presets.d.ts.map +1 -0
- package/dist/config/presets.js +11 -0
- package/dist/config/presets.js.map +1 -0
- package/dist/config/types.d.ts +199 -0
- package/dist/config/types.d.ts.map +1 -0
- package/dist/config/validation.d.ts +19 -0
- package/dist/config/validation.d.ts.map +1 -0
- package/dist/config/validation.js +232 -0
- package/dist/config/validation.js.map +1 -0
- package/dist/controllers/PlaybackController.d.ts +55 -0
- package/dist/controllers/PlaybackController.d.ts.map +1 -0
- package/dist/controllers/PlaybackController.js +369 -0
- package/dist/controllers/PlaybackController.js.map +1 -0
- package/dist/controllers/PreRenderService.d.ts +34 -0
- package/dist/controllers/PreRenderService.d.ts.map +1 -0
- package/dist/controllers/PreRenderService.js +83 -0
- package/dist/controllers/PreRenderService.js.map +1 -0
- package/dist/controllers/PreRenderTaskQueue.d.ts +21 -0
- package/dist/controllers/PreRenderTaskQueue.d.ts.map +1 -0
- package/dist/controllers/PreviewHandle.d.ts +23 -0
- package/dist/controllers/PreviewHandle.d.ts.map +1 -0
- package/dist/controllers/PreviewHandle.js +39 -0
- package/dist/controllers/PreviewHandle.js.map +1 -0
- package/dist/controllers/index.d.ts +8 -0
- package/dist/controllers/index.d.ts.map +1 -0
- package/dist/controllers/types.d.ts +102 -0
- package/dist/controllers/types.d.ts.map +1 -0
- package/dist/event/EventBus.d.ts +42 -0
- package/dist/event/EventBus.d.ts.map +1 -0
- package/dist/event/EventBus.js +94 -0
- package/dist/event/EventBus.js.map +1 -0
- package/dist/event/events.d.ts +371 -0
- package/dist/event/events.d.ts.map +1 -0
- package/dist/event/events.js +71 -0
- package/dist/event/events.js.map +1 -0
- package/dist/event/index.d.ts +4 -0
- package/dist/event/index.d.ts.map +1 -0
- package/dist/index.d.ts +14 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +15 -0
- package/dist/index.js.map +1 -0
- package/dist/model/CompositionModel.d.ts +48 -0
- package/dist/model/CompositionModel.d.ts.map +1 -0
- package/dist/model/CompositionModel.js +197 -0
- package/dist/model/CompositionModel.js.map +1 -0
- package/dist/model/RcFrame.d.ts +34 -0
- package/dist/model/RcFrame.d.ts.map +1 -0
- package/dist/model/RcFrame.js +97 -0
- package/dist/model/RcFrame.js.map +1 -0
- package/dist/model/dirty-range.d.ts +5 -0
- package/dist/model/dirty-range.d.ts.map +1 -0
- package/dist/model/dirty-range.js +220 -0
- package/dist/model/dirty-range.js.map +1 -0
- package/dist/model/index.d.ts +7 -0
- package/dist/model/index.d.ts.map +1 -0
- package/dist/model/patch.d.ts +5 -0
- package/dist/model/patch.d.ts.map +1 -0
- package/dist/model/patch.js +250 -0
- package/dist/model/patch.js.map +1 -0
- package/dist/model/types.d.ts +135 -0
- package/dist/model/types.d.ts.map +1 -0
- package/dist/model/types.js +5 -0
- package/dist/model/types.js.map +1 -0
- package/dist/model/validation.d.ts +15 -0
- package/dist/model/validation.d.ts.map +1 -0
- package/dist/model/validation.js +74 -0
- package/dist/model/validation.js.map +1 -0
- package/dist/node_modules/.pnpm/mp4box@0.5.4/node_modules/mp4box/dist/mp4box.all.js +7046 -0
- package/dist/node_modules/.pnpm/mp4box@0.5.4/node_modules/mp4box/dist/mp4box.all.js.map +1 -0
- package/dist/orchestrator/ClipSessionManager.d.ts +75 -0
- package/dist/orchestrator/ClipSessionManager.d.ts.map +1 -0
- package/dist/orchestrator/ClipSessionManager.js +160 -0
- package/dist/orchestrator/ClipSessionManager.js.map +1 -0
- package/dist/orchestrator/CompositionPlanner.d.ts +55 -0
- package/dist/orchestrator/CompositionPlanner.d.ts.map +1 -0
- package/dist/orchestrator/CompositionPlanner.js +411 -0
- package/dist/orchestrator/CompositionPlanner.js.map +1 -0
- package/dist/orchestrator/Orchestrator.d.ts +59 -0
- package/dist/orchestrator/Orchestrator.d.ts.map +1 -0
- package/dist/orchestrator/Orchestrator.js +390 -0
- package/dist/orchestrator/Orchestrator.js.map +1 -0
- package/dist/orchestrator/VideoClipSession.d.ts +64 -0
- package/dist/orchestrator/VideoClipSession.d.ts.map +1 -0
- package/dist/orchestrator/VideoClipSession.js +309 -0
- package/dist/orchestrator/VideoClipSession.js.map +1 -0
- package/dist/orchestrator/index.d.ts +5 -0
- package/dist/orchestrator/index.d.ts.map +1 -0
- package/dist/orchestrator/types.d.ts +64 -0
- package/dist/orchestrator/types.d.ts.map +1 -0
- package/dist/plugins/BackpressureMonitor.d.ts +33 -0
- package/dist/plugins/BackpressureMonitor.d.ts.map +1 -0
- package/dist/plugins/BackpressureMonitor.js +62 -0
- package/dist/plugins/BackpressureMonitor.js.map +1 -0
- package/dist/plugins/PluginManager.d.ts +37 -0
- package/dist/plugins/PluginManager.d.ts.map +1 -0
- package/dist/plugins/PluginManager.js +66 -0
- package/dist/plugins/PluginManager.js.map +1 -0
- package/dist/plugins/types.d.ts +60 -0
- package/dist/plugins/types.d.ts.map +1 -0
- package/dist/stages/compose/AudioDucker.d.ts +59 -0
- package/dist/stages/compose/AudioDucker.d.ts.map +1 -0
- package/dist/stages/compose/AudioDucker.js +161 -0
- package/dist/stages/compose/AudioDucker.js.map +1 -0
- package/dist/stages/compose/AudioMixer.d.ts +29 -0
- package/dist/stages/compose/AudioMixer.d.ts.map +1 -0
- package/dist/stages/compose/AudioMixer.js +373 -0
- package/dist/stages/compose/AudioMixer.js.map +1 -0
- package/dist/stages/compose/FilterProcessor.d.ts +41 -0
- package/dist/stages/compose/FilterProcessor.d.ts.map +1 -0
- package/dist/stages/compose/FilterProcessor.js +226 -0
- package/dist/stages/compose/FilterProcessor.js.map +1 -0
- package/dist/stages/compose/GlobalAudioSession.d.ts +38 -0
- package/dist/stages/compose/GlobalAudioSession.d.ts.map +1 -0
- package/dist/stages/compose/GlobalAudioSession.js +122 -0
- package/dist/stages/compose/GlobalAudioSession.js.map +1 -0
- package/dist/stages/compose/LayerRenderer.d.ts +30 -0
- package/dist/stages/compose/LayerRenderer.d.ts.map +1 -0
- package/dist/stages/compose/LayerRenderer.js +215 -0
- package/dist/stages/compose/LayerRenderer.js.map +1 -0
- package/dist/stages/compose/OfflineAudioMixer.d.ts +14 -0
- package/dist/stages/compose/OfflineAudioMixer.d.ts.map +1 -0
- package/dist/stages/compose/OfflineAudioMixer.js +68 -0
- package/dist/stages/compose/OfflineAudioMixer.js.map +1 -0
- package/dist/stages/compose/TransitionProcessor.d.ts +30 -0
- package/dist/stages/compose/TransitionProcessor.d.ts.map +1 -0
- package/dist/stages/compose/TransitionProcessor.js +189 -0
- package/dist/stages/compose/TransitionProcessor.js.map +1 -0
- package/dist/stages/compose/VideoComposer.d.ts +30 -0
- package/dist/stages/compose/VideoComposer.d.ts.map +1 -0
- package/dist/stages/compose/VideoComposer.js +186 -0
- package/dist/stages/compose/VideoComposer.js.map +1 -0
- package/dist/stages/compose/audio-compose.worker.d.ts +79 -0
- package/dist/stages/compose/audio-compose.worker.d.ts.map +1 -0
- package/dist/stages/compose/audio-compose.worker.js +541 -0
- package/dist/stages/compose/audio-compose.worker.js.map +1 -0
- package/dist/stages/compose/instructions.d.ts +95 -0
- package/dist/stages/compose/instructions.d.ts.map +1 -0
- package/dist/stages/compose/types.d.ts +245 -0
- package/dist/stages/compose/types.d.ts.map +1 -0
- package/dist/stages/compose/video-compose.worker.d.ts +60 -0
- package/dist/stages/compose/video-compose.worker.d.ts.map +1 -0
- package/dist/stages/compose/video-compose.worker.js +369 -0
- package/dist/stages/compose/video-compose.worker.js.map +1 -0
- package/dist/stages/decode/AudioChunkDecoder.d.ts +41 -0
- package/dist/stages/decode/AudioChunkDecoder.d.ts.map +1 -0
- package/dist/stages/decode/AudioChunkDecoder.js +83 -0
- package/dist/stages/decode/AudioChunkDecoder.js.map +1 -0
- package/dist/stages/decode/BaseDecoder.d.ts +35 -0
- package/dist/stages/decode/BaseDecoder.d.ts.map +1 -0
- package/dist/stages/decode/BaseDecoder.js +130 -0
- package/dist/stages/decode/BaseDecoder.js.map +1 -0
- package/dist/stages/decode/VideoChunkDecoder.d.ts +54 -0
- package/dist/stages/decode/VideoChunkDecoder.d.ts.map +1 -0
- package/dist/stages/decode/VideoChunkDecoder.js +209 -0
- package/dist/stages/decode/VideoChunkDecoder.js.map +1 -0
- package/dist/stages/decode/decode.worker.d.ts +70 -0
- package/dist/stages/decode/decode.worker.d.ts.map +1 -0
- package/dist/stages/decode/decode.worker.js +436 -0
- package/dist/stages/decode/decode.worker.js.map +1 -0
- package/dist/stages/decode/index.d.ts +5 -0
- package/dist/stages/decode/index.d.ts.map +1 -0
- package/dist/stages/decode/types.d.ts +108 -0
- package/dist/stages/decode/types.d.ts.map +1 -0
- package/dist/stages/demux/MP3FrameParser.d.ts +33 -0
- package/dist/stages/demux/MP3FrameParser.d.ts.map +1 -0
- package/dist/stages/demux/MP3FrameParser.js +186 -0
- package/dist/stages/demux/MP3FrameParser.js.map +1 -0
- package/dist/stages/demux/MP4Demuxer.d.ts +45 -0
- package/dist/stages/demux/MP4Demuxer.d.ts.map +1 -0
- package/dist/stages/demux/MP4Demuxer.js +227 -0
- package/dist/stages/demux/MP4Demuxer.js.map +1 -0
- package/dist/stages/demux/aac-esds-extractor.d.ts +7 -0
- package/dist/stages/demux/aac-esds-extractor.d.ts.map +1 -0
- package/dist/stages/demux/audio-demux.worker.d.ts +51 -0
- package/dist/stages/demux/audio-demux.worker.d.ts.map +1 -0
- package/dist/stages/demux/audio-demux.worker.js +312 -0
- package/dist/stages/demux/audio-demux.worker.js.map +1 -0
- package/dist/stages/demux/types.d.ts +77 -0
- package/dist/stages/demux/types.d.ts.map +1 -0
- package/dist/stages/demux/video-demux.worker.d.ts +48 -0
- package/dist/stages/demux/video-demux.worker.d.ts.map +1 -0
- package/dist/stages/demux/video-demux.worker.js +173 -0
- package/dist/stages/demux/video-demux.worker.js.map +1 -0
- package/dist/stages/encode/AudioChunkEncoder.d.ts +21 -0
- package/dist/stages/encode/AudioChunkEncoder.d.ts.map +1 -0
- package/dist/stages/encode/AudioChunkEncoder.js +37 -0
- package/dist/stages/encode/AudioChunkEncoder.js.map +1 -0
- package/dist/stages/encode/BaseEncoder.d.ts +44 -0
- package/dist/stages/encode/BaseEncoder.d.ts.map +1 -0
- package/dist/stages/encode/BaseEncoder.js +164 -0
- package/dist/stages/encode/BaseEncoder.js.map +1 -0
- package/dist/stages/encode/EncoderPool.d.ts +28 -0
- package/dist/stages/encode/EncoderPool.d.ts.map +1 -0
- package/dist/stages/encode/VideoChunkEncoder.d.ts +26 -0
- package/dist/stages/encode/VideoChunkEncoder.d.ts.map +1 -0
- package/dist/stages/encode/VideoChunkEncoder.js +50 -0
- package/dist/stages/encode/VideoChunkEncoder.js.map +1 -0
- package/dist/stages/encode/encode.worker.d.ts +3 -0
- package/dist/stages/encode/encode.worker.d.ts.map +1 -0
- package/dist/stages/encode/encode.worker.js +318 -0
- package/dist/stages/encode/encode.worker.js.map +1 -0
- package/dist/stages/encode/index.d.ts +6 -0
- package/dist/stages/encode/index.d.ts.map +1 -0
- package/dist/stages/encode/types.d.ts +127 -0
- package/dist/stages/encode/types.d.ts.map +1 -0
- package/dist/stages/load/EventHandlers.d.ts +35 -0
- package/dist/stages/load/EventHandlers.d.ts.map +1 -0
- package/dist/stages/load/EventHandlers.js +65 -0
- package/dist/stages/load/EventHandlers.js.map +1 -0
- package/dist/stages/load/ResourceLoader.d.ts +36 -0
- package/dist/stages/load/ResourceLoader.d.ts.map +1 -0
- package/dist/stages/load/ResourceLoader.js +184 -0
- package/dist/stages/load/ResourceLoader.js.map +1 -0
- package/dist/stages/load/StreamFactory.d.ts +42 -0
- package/dist/stages/load/StreamFactory.d.ts.map +1 -0
- package/dist/stages/load/StreamFactory.js +201 -0
- package/dist/stages/load/StreamFactory.js.map +1 -0
- package/dist/stages/load/TaskManager.d.ts +50 -0
- package/dist/stages/load/TaskManager.d.ts.map +1 -0
- package/dist/stages/load/TaskManager.js +103 -0
- package/dist/stages/load/TaskManager.js.map +1 -0
- package/dist/stages/load/WindowByteRangeResolver.d.ts +47 -0
- package/dist/stages/load/WindowByteRangeResolver.d.ts.map +1 -0
- package/dist/stages/load/WindowByteRangeResolver.js +270 -0
- package/dist/stages/load/WindowByteRangeResolver.js.map +1 -0
- package/dist/stages/load/index.d.ts +11 -0
- package/dist/stages/load/index.d.ts.map +1 -0
- package/dist/stages/load/types.d.ts +177 -0
- package/dist/stages/load/types.d.ts.map +1 -0
- package/dist/stages/mux/MP4Muxer.d.ts +44 -0
- package/dist/stages/mux/MP4Muxer.d.ts.map +1 -0
- package/dist/stages/mux/MP4Muxer.js +262 -0
- package/dist/stages/mux/MP4Muxer.js.map +1 -0
- package/dist/stages/mux/OPFSWriter.d.ts +46 -0
- package/dist/stages/mux/OPFSWriter.d.ts.map +1 -0
- package/dist/stages/mux/index.d.ts +5 -0
- package/dist/stages/mux/index.d.ts.map +1 -0
- package/dist/stages/mux/mux.worker.d.ts +65 -0
- package/dist/stages/mux/mux.worker.d.ts.map +1 -0
- package/dist/stages/mux/mux.worker.js +219 -0
- package/dist/stages/mux/mux.worker.js.map +1 -0
- package/dist/stages/mux/types.d.ts +95 -0
- package/dist/stages/mux/types.d.ts.map +1 -0
- package/dist/stages/mux/utils.d.ts +32 -0
- package/dist/stages/mux/utils.d.ts.map +1 -0
- package/dist/stages/mux/utils.js +34 -0
- package/dist/stages/mux/utils.js.map +1 -0
- package/dist/types.d.ts +25 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/utils/BackpressureAdapter.d.ts +26 -0
- package/dist/utils/BackpressureAdapter.d.ts.map +1 -0
- package/dist/utils/binary-search.d.ts +33 -0
- package/dist/utils/binary-search.d.ts.map +1 -0
- package/dist/utils/binary-search.js +62 -0
- package/dist/utils/binary-search.js.map +1 -0
- package/dist/utils/canvas-utils.d.ts +96 -0
- package/dist/utils/canvas-utils.d.ts.map +1 -0
- package/dist/utils/canvas-utils.js +58 -0
- package/dist/utils/canvas-utils.js.map +1 -0
- package/dist/utils/object-utils.d.ts +34 -0
- package/dist/utils/object-utils.d.ts.map +1 -0
- package/dist/utils/object-utils.js +22 -0
- package/dist/utils/object-utils.js.map +1 -0
- package/dist/utils/time-utils.d.ts +10 -0
- package/dist/utils/time-utils.d.ts.map +1 -0
- package/dist/utils/time-utils.js +60 -0
- package/dist/utils/time-utils.js.map +1 -0
- package/dist/worker/BaseWorker.d.ts +44 -0
- package/dist/worker/BaseWorker.d.ts.map +1 -0
- package/dist/worker/BaseWorker.js +98 -0
- package/dist/worker/BaseWorker.js.map +1 -0
- package/dist/worker/WorkerChannel.d.ts +105 -0
- package/dist/worker/WorkerChannel.d.ts.map +1 -0
- package/dist/worker/WorkerChannel.js +355 -0
- package/dist/worker/WorkerChannel.js.map +1 -0
- package/dist/worker/WorkerPool.d.ts +52 -0
- package/dist/worker/WorkerPool.d.ts.map +1 -0
- package/dist/worker/WorkerPool.js +124 -0
- package/dist/worker/WorkerPool.js.map +1 -0
- package/dist/worker/index.d.ts +11 -0
- package/dist/worker/index.d.ts.map +1 -0
- package/dist/worker/transferable-helper.d.ts +89 -0
- package/dist/worker/transferable-helper.d.ts.map +1 -0
- package/dist/worker/transferable-helper.js +44 -0
- package/dist/worker/transferable-helper.js.map +1 -0
- package/dist/worker/types.d.ts +179 -0
- package/dist/worker/types.d.ts.map +1 -0
- package/dist/worker/types.js +50 -0
- package/dist/worker/types.js.map +1 -0
- package/dist/worker/worker-event-whitelist.d.ts +23 -0
- package/dist/worker/worker-event-whitelist.d.ts.map +1 -0
- package/dist/worker/worker-retry.d.ts +36 -0
- package/dist/worker/worker-retry.d.ts.map +1 -0
- package/dist/worker/worker-retry.js +55 -0
- package/dist/worker/worker-retry.js.map +1 -0
- package/package.json +105 -0
|
@@ -0,0 +1,318 @@
|
|
|
1
|
+
import { WorkerChannel } from "../../worker/WorkerChannel.js";
|
|
2
|
+
import { WorkerMessageType, WorkerState } from "../../worker/types.js";
|
|
3
|
+
import { VideoChunkEncoder } from "./VideoChunkEncoder.js";
|
|
4
|
+
import { AudioChunkEncoder } from "./AudioChunkEncoder.js";
|
|
5
|
+
class EncodeWorker {
|
|
6
|
+
channel;
|
|
7
|
+
videoEncoder = null;
|
|
8
|
+
audioEncoder = null;
|
|
9
|
+
// Connections to other workers
|
|
10
|
+
cachePort = null;
|
|
11
|
+
muxPort = null;
|
|
12
|
+
composePorts = /* @__PURE__ */ new Map();
|
|
13
|
+
// Connections from compose workers
|
|
14
|
+
constructor() {
|
|
15
|
+
this.channel = new WorkerChannel(self, {
|
|
16
|
+
name: "EncodeWorker",
|
|
17
|
+
timeout: 3e4
|
|
18
|
+
});
|
|
19
|
+
this.setupHandlers();
|
|
20
|
+
}
|
|
21
|
+
setupHandlers() {
|
|
22
|
+
this.channel.registerHandler("configure", this.handleConfigure.bind(this));
|
|
23
|
+
this.channel.registerHandler("connect", this.handleConnect.bind(this));
|
|
24
|
+
this.channel.registerHandler("configure_video", this.handleConfigureVideo.bind(this));
|
|
25
|
+
this.channel.registerHandler("configure_audio", this.handleConfigureAudio.bind(this));
|
|
26
|
+
this.channel.registerHandler("flush", this.handleFlush.bind(this));
|
|
27
|
+
this.channel.registerHandler("reset", this.handleReset.bind(this));
|
|
28
|
+
this.channel.registerHandler("get_stats", this.handleGetStats.bind(this));
|
|
29
|
+
this.channel.registerHandler(WorkerMessageType.Dispose, this.handleDispose.bind(this));
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Connect handler used by stream pipeline
|
|
33
|
+
*/
|
|
34
|
+
async handleConnect(payload) {
|
|
35
|
+
const { port, streamType } = payload;
|
|
36
|
+
if (streamType === "video") return this.handleConnectComposer({ composeType: "video", port });
|
|
37
|
+
if (streamType === "audio") return this.handleConnectComposer({ composeType: "audio", port });
|
|
38
|
+
if (streamType === "chunk") return this.handleConnectMux({ port });
|
|
39
|
+
return { success: true };
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Handle configuration message from orchestrator
|
|
43
|
+
* @param payload.initial - If true, initialize worker and recreate encoder instances; otherwise just update config
|
|
44
|
+
*/
|
|
45
|
+
async handleConfigure(payload) {
|
|
46
|
+
const { config, initial = false } = payload;
|
|
47
|
+
if (initial) {
|
|
48
|
+
this.channel.state = WorkerState.Ready;
|
|
49
|
+
}
|
|
50
|
+
if (config.video) {
|
|
51
|
+
if (initial || !this.videoEncoder) {
|
|
52
|
+
if (this.videoEncoder) {
|
|
53
|
+
await this.videoEncoder.close();
|
|
54
|
+
}
|
|
55
|
+
this.videoEncoder = new VideoChunkEncoder(config.video);
|
|
56
|
+
await this.videoEncoder.initialize();
|
|
57
|
+
const videoStream = config.video.stream?.pipeThrough(this.videoEncoder.createStream());
|
|
58
|
+
if (videoStream && this.cachePort) {
|
|
59
|
+
const cacheChannel = new WorkerChannel(this.cachePort, {
|
|
60
|
+
name: "Encode-Cache-Video",
|
|
61
|
+
timeout: 3e4
|
|
62
|
+
});
|
|
63
|
+
await cacheChannel.sendStream(videoStream, {
|
|
64
|
+
type: "video",
|
|
65
|
+
width: config.video.width,
|
|
66
|
+
height: config.video.height,
|
|
67
|
+
framerate: config.video.framerate
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
} else {
|
|
71
|
+
await this.videoEncoder.reconfigure(config.video);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
if (config.audio) {
|
|
75
|
+
if (initial || !this.audioEncoder) {
|
|
76
|
+
if (this.audioEncoder) {
|
|
77
|
+
await this.audioEncoder.close();
|
|
78
|
+
}
|
|
79
|
+
this.audioEncoder = new AudioChunkEncoder(config.audio);
|
|
80
|
+
await this.audioEncoder.initialize();
|
|
81
|
+
const audioStream = config.audio.stream?.pipeThrough(this.audioEncoder.createStream());
|
|
82
|
+
if (audioStream && this.cachePort) {
|
|
83
|
+
const cacheChannel = new WorkerChannel(this.cachePort, {
|
|
84
|
+
name: "Encode-Cache-Audio",
|
|
85
|
+
timeout: 3e4
|
|
86
|
+
});
|
|
87
|
+
await cacheChannel.sendStream(audioStream, {
|
|
88
|
+
type: "audio",
|
|
89
|
+
sampleRate: config.audio.sampleRate,
|
|
90
|
+
numberOfChannels: config.audio.numberOfChannels
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
} else {
|
|
94
|
+
await this.audioEncoder.reconfigure(config.audio);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
return { success: true };
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Connect to a compose worker to receive frames/audio data
|
|
101
|
+
*/
|
|
102
|
+
async handleConnectComposer(payload) {
|
|
103
|
+
const { composeType, port } = payload;
|
|
104
|
+
this.composePorts.set(composeType, port);
|
|
105
|
+
const composeChannel = new WorkerChannel(port, {
|
|
106
|
+
name: `Encode-${composeType}Compose`,
|
|
107
|
+
timeout: 3e4
|
|
108
|
+
});
|
|
109
|
+
composeChannel.receiveStream(async (stream, metadata) => {
|
|
110
|
+
console.log("[EncodeWorker] receiveStream", metadata);
|
|
111
|
+
if (metadata?.streamType === "video" && this.videoEncoder) {
|
|
112
|
+
const reader = stream.getReader();
|
|
113
|
+
try {
|
|
114
|
+
while (true) {
|
|
115
|
+
const { done, value } = await reader.read();
|
|
116
|
+
if (done) break;
|
|
117
|
+
const wrappedValue = value;
|
|
118
|
+
const videoFrame = wrappedValue.frame || wrappedValue;
|
|
119
|
+
try {
|
|
120
|
+
const frame = videoFrame.clone();
|
|
121
|
+
this.videoEncoder.encode(frame);
|
|
122
|
+
} finally {
|
|
123
|
+
videoFrame.close();
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
} finally {
|
|
127
|
+
reader.releaseLock();
|
|
128
|
+
}
|
|
129
|
+
} else if (metadata?.streamType === "audio" && this.audioEncoder) {
|
|
130
|
+
const composedConfig = {
|
|
131
|
+
sampleRate: metadata.sampleRate,
|
|
132
|
+
numberOfChannels: metadata.numberOfChannels
|
|
133
|
+
};
|
|
134
|
+
const currentConfig = this.audioEncoder.getConfig();
|
|
135
|
+
if (typeof composedConfig.sampleRate === "number" && composedConfig.sampleRate > 0 && composedConfig.sampleRate !== currentConfig.sampleRate) {
|
|
136
|
+
await this.audioEncoder.reconfigure({ sampleRate: composedConfig.sampleRate });
|
|
137
|
+
}
|
|
138
|
+
if (typeof composedConfig.numberOfChannels === "number" && composedConfig.numberOfChannels > 0 && composedConfig.numberOfChannels !== currentConfig.numberOfChannels) {
|
|
139
|
+
await this.audioEncoder.reconfigure({
|
|
140
|
+
numberOfChannels: composedConfig.numberOfChannels
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
const reader = stream.getReader();
|
|
144
|
+
try {
|
|
145
|
+
while (true) {
|
|
146
|
+
const { done, value } = await reader.read();
|
|
147
|
+
if (done) break;
|
|
148
|
+
this.audioEncoder.encode(value);
|
|
149
|
+
}
|
|
150
|
+
} finally {
|
|
151
|
+
reader.releaseLock();
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
});
|
|
155
|
+
return { success: true };
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* Connect to cache manager for output streaming
|
|
159
|
+
*/
|
|
160
|
+
// private async handleConnectCache(payload: { port: MessagePort }): Promise<{ success: boolean }> {
|
|
161
|
+
// this.cachePort = payload.port;
|
|
162
|
+
// return { success: true };
|
|
163
|
+
// }
|
|
164
|
+
/**
|
|
165
|
+
* Connect to mux worker for output streaming
|
|
166
|
+
*/
|
|
167
|
+
async handleConnectMux(payload) {
|
|
168
|
+
this.muxPort = payload.port;
|
|
169
|
+
return { success: true };
|
|
170
|
+
}
|
|
171
|
+
/**
|
|
172
|
+
* Configure video encoder with specific settings
|
|
173
|
+
*/
|
|
174
|
+
async handleConfigureVideo(config) {
|
|
175
|
+
try {
|
|
176
|
+
if (!this.videoEncoder) {
|
|
177
|
+
this.videoEncoder = new VideoChunkEncoder(config);
|
|
178
|
+
await this.videoEncoder.initialize();
|
|
179
|
+
} else {
|
|
180
|
+
await this.videoEncoder.reconfigure(config);
|
|
181
|
+
}
|
|
182
|
+
this.channel.notify("video_configured", {
|
|
183
|
+
codec: config.codec,
|
|
184
|
+
width: config.width,
|
|
185
|
+
height: config.height,
|
|
186
|
+
bitrate: config.bitrate
|
|
187
|
+
});
|
|
188
|
+
return { success: true };
|
|
189
|
+
} catch (error) {
|
|
190
|
+
throw {
|
|
191
|
+
code: "VIDEO_CONFIG_ERROR",
|
|
192
|
+
message: error.message
|
|
193
|
+
};
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
/**
|
|
197
|
+
* Configure audio encoder with specific settings
|
|
198
|
+
*/
|
|
199
|
+
async handleConfigureAudio(config) {
|
|
200
|
+
try {
|
|
201
|
+
if (!this.audioEncoder) {
|
|
202
|
+
this.audioEncoder = new AudioChunkEncoder(config);
|
|
203
|
+
await this.audioEncoder.initialize();
|
|
204
|
+
} else {
|
|
205
|
+
await this.audioEncoder.reconfigure(config);
|
|
206
|
+
}
|
|
207
|
+
this.channel.notify("audio_configured", {
|
|
208
|
+
codec: config.codec,
|
|
209
|
+
sampleRate: config.sampleRate,
|
|
210
|
+
numberOfChannels: config.numberOfChannels,
|
|
211
|
+
bitrate: config.bitrate
|
|
212
|
+
});
|
|
213
|
+
return { success: true };
|
|
214
|
+
} catch (error) {
|
|
215
|
+
throw {
|
|
216
|
+
code: "AUDIO_CONFIG_ERROR",
|
|
217
|
+
message: error.message
|
|
218
|
+
};
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
/**
|
|
222
|
+
* Flush encoders and get buffered chunks
|
|
223
|
+
*/
|
|
224
|
+
async handleFlush(payload) {
|
|
225
|
+
try {
|
|
226
|
+
const result = {};
|
|
227
|
+
if (!payload?.type || payload.type === "video") {
|
|
228
|
+
const chunks = await this.videoEncoder?.flush();
|
|
229
|
+
if (chunks) {
|
|
230
|
+
result.videoChunks = chunks;
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
if (!payload?.type || payload.type === "audio") {
|
|
234
|
+
const chunks = await this.audioEncoder?.flush();
|
|
235
|
+
if (chunks) {
|
|
236
|
+
result.audioChunks = chunks;
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
return result;
|
|
240
|
+
} catch (error) {
|
|
241
|
+
throw {
|
|
242
|
+
code: "FLUSH_ERROR",
|
|
243
|
+
message: error.message
|
|
244
|
+
};
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
/**
|
|
248
|
+
* Reset encoders
|
|
249
|
+
*/
|
|
250
|
+
async handleReset(payload) {
|
|
251
|
+
try {
|
|
252
|
+
if (!payload?.type || payload.type === "video") {
|
|
253
|
+
await this.videoEncoder?.reset();
|
|
254
|
+
}
|
|
255
|
+
if (!payload?.type || payload.type === "audio") {
|
|
256
|
+
await this.audioEncoder?.reset();
|
|
257
|
+
}
|
|
258
|
+
this.channel.notify("reset_complete", {
|
|
259
|
+
type: payload?.type || "all"
|
|
260
|
+
});
|
|
261
|
+
return { success: true };
|
|
262
|
+
} catch (error) {
|
|
263
|
+
throw {
|
|
264
|
+
code: "RESET_ERROR",
|
|
265
|
+
message: error.message
|
|
266
|
+
};
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
/**
|
|
270
|
+
* Get encoder statistics
|
|
271
|
+
*/
|
|
272
|
+
async handleGetStats() {
|
|
273
|
+
const stats = {};
|
|
274
|
+
if (this.videoEncoder) {
|
|
275
|
+
stats.video = {
|
|
276
|
+
configured: this.videoEncoder.isReady,
|
|
277
|
+
queueSize: this.videoEncoder.queueSize
|
|
278
|
+
};
|
|
279
|
+
}
|
|
280
|
+
if (this.audioEncoder) {
|
|
281
|
+
stats.audio = {
|
|
282
|
+
configured: this.audioEncoder.isReady,
|
|
283
|
+
queueSize: this.audioEncoder.queueSize
|
|
284
|
+
};
|
|
285
|
+
}
|
|
286
|
+
return stats;
|
|
287
|
+
}
|
|
288
|
+
// Output and error handling is done via streams in the encoder itself
|
|
289
|
+
// These placeholder methods can be implemented when needed for direct callback handling
|
|
290
|
+
/**
|
|
291
|
+
* Dispose worker and cleanup resources
|
|
292
|
+
*/
|
|
293
|
+
async handleDispose() {
|
|
294
|
+
await this.videoEncoder?.close();
|
|
295
|
+
await this.audioEncoder?.close();
|
|
296
|
+
this.videoEncoder = null;
|
|
297
|
+
this.audioEncoder = null;
|
|
298
|
+
this.cachePort?.close();
|
|
299
|
+
this.cachePort = null;
|
|
300
|
+
this.muxPort?.close();
|
|
301
|
+
this.muxPort = null;
|
|
302
|
+
for (const port of this.composePorts.values()) {
|
|
303
|
+
port.close();
|
|
304
|
+
}
|
|
305
|
+
this.composePorts.clear();
|
|
306
|
+
this.channel.state = WorkerState.Disposed;
|
|
307
|
+
return { success: true };
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
const worker = new EncodeWorker();
|
|
311
|
+
self.addEventListener("beforeunload", () => {
|
|
312
|
+
worker["handleDispose"]();
|
|
313
|
+
});
|
|
314
|
+
const encode_worker = null;
|
|
315
|
+
export {
|
|
316
|
+
encode_worker as default
|
|
317
|
+
};
|
|
318
|
+
//# sourceMappingURL=encode.worker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"encode.worker.js","sources":["../../../src/stages/encode/encode.worker.ts"],"sourcesContent":["import { WorkerChannel } from '../../worker/WorkerChannel';\nimport { WorkerMessageType, WorkerState } from '../../worker/types';\nimport { VideoChunkEncoder } from './VideoChunkEncoder';\nimport { AudioChunkEncoder } from './AudioChunkEncoder';\nimport { VideoEncoderConfig, AudioEncoderConfig } from './types';\n\n/**\n * EncodeWorker - Seventh stage in the pipeline\n * Receives composed frames from ComposeWorkers and outputs encoded chunks to CacheManager/MuxWorker\n *\n * Pipeline: VideoComposeWorker/AudioComposeWorker → EncodeWorker → CacheManager/MuxWorker\n *\n * Features:\n * - Hardware-accelerated encoding via WebCodecs\n * - Configurable bitrate and quality settings\n * - Batch flush for efficient I/O (0.5s batches)\n * - Direct streaming to cache/mux workers\n */\nclass EncodeWorker {\n private channel: WorkerChannel;\n private videoEncoder: VideoChunkEncoder | null = null;\n private audioEncoder: AudioChunkEncoder | null = null;\n\n // Connections to other workers\n private cachePort: MessagePort | null = null;\n private muxPort: MessagePort | null = null;\n private composePorts = new Map<string, MessagePort>(); // Connections from compose workers\n\n constructor() {\n // Initialize WorkerChannel with MessagePort\n this.channel = new WorkerChannel(self as any, {\n name: 'EncodeWorker',\n timeout: 30000,\n });\n\n this.setupHandlers();\n }\n\n private setupHandlers(): void {\n // Register message handlers\n this.channel.registerHandler('configure', this.handleConfigure.bind(this));\n this.channel.registerHandler('connect', this.handleConnect.bind(this));\n this.channel.registerHandler('configure_video', this.handleConfigureVideo.bind(this));\n this.channel.registerHandler('configure_audio', this.handleConfigureAudio.bind(this));\n this.channel.registerHandler('flush', this.handleFlush.bind(this));\n this.channel.registerHandler('reset', this.handleReset.bind(this));\n this.channel.registerHandler('get_stats', this.handleGetStats.bind(this));\n this.channel.registerHandler(WorkerMessageType.Dispose, this.handleDispose.bind(this));\n }\n\n /**\n * Connect handler used by stream pipeline\n */\n private async handleConnect(payload: {\n direction: 'upstream';\n port: MessagePort;\n streamType: 'video' | 'audio' | 'frame' | 'chunk';\n }): Promise<{ success: boolean }> {\n const { port, streamType } = payload;\n if (streamType === 'video') return this.handleConnectComposer({ composeType: 'video', port });\n if (streamType === 'audio') return this.handleConnectComposer({ composeType: 'audio', port });\n if (streamType === 'chunk') return this.handleConnectMux({ port });\n return { success: true };\n }\n\n /**\n * Handle configuration message from orchestrator\n * @param payload.initial - If true, initialize worker and recreate encoder instances; otherwise just update config\n */\n private async handleConfigure(payload: {\n config: {\n video?: Partial<VideoEncoderConfig> & { stream?: ReadableStream<VideoFrame> };\n audio?: Partial<AudioEncoderConfig> & { stream?: ReadableStream<AudioData> };\n };\n initial?: boolean;\n }): Promise<{ success: boolean }> {\n const { config, initial = false } = payload;\n\n // Set worker state to ready on initial configuration\n if (initial) {\n this.channel.state = WorkerState.Ready;\n }\n\n // Handle video encoder configuration\n if (config.video) {\n if (initial || !this.videoEncoder) {\n if (this.videoEncoder) {\n await this.videoEncoder.close();\n }\n this.videoEncoder = new VideoChunkEncoder(config.video as VideoEncoderConfig);\n await this.videoEncoder.initialize();\n\n const videoStream = config.video.stream?.pipeThrough(this.videoEncoder.createStream());\n if (videoStream && this.cachePort) {\n const cacheChannel = new WorkerChannel(this.cachePort, {\n name: 'Encode-Cache-Video',\n timeout: 30000,\n });\n await cacheChannel.sendStream(videoStream, {\n type: 'video',\n width: config.video.width,\n height: config.video.height,\n framerate: config.video.framerate,\n });\n }\n } else {\n await this.videoEncoder.reconfigure(config.video);\n }\n }\n\n if (config.audio) {\n if (initial || !this.audioEncoder) {\n if (this.audioEncoder) {\n await this.audioEncoder.close();\n }\n this.audioEncoder = new AudioChunkEncoder(config.audio as AudioEncoderConfig);\n await this.audioEncoder.initialize();\n\n const audioStream = config.audio.stream?.pipeThrough(this.audioEncoder.createStream());\n if (audioStream && this.cachePort) {\n const cacheChannel = new WorkerChannel(this.cachePort, {\n name: 'Encode-Cache-Audio',\n timeout: 30000,\n });\n await cacheChannel.sendStream(audioStream, {\n type: 'audio',\n sampleRate: config.audio.sampleRate,\n numberOfChannels: config.audio.numberOfChannels,\n });\n }\n } else {\n await this.audioEncoder.reconfigure(config.audio);\n }\n }\n\n return { success: true };\n }\n\n /**\n * Connect to a compose worker to receive frames/audio data\n */\n private async handleConnectComposer(payload: {\n composeType: 'video' | 'audio';\n port: MessagePort;\n }): Promise<{ success: boolean }> {\n const { composeType, port } = payload;\n\n // Store the port\n this.composePorts.set(composeType, port);\n\n // Setup channel for receiving streams\n const composeChannel = new WorkerChannel(port, {\n name: `Encode-${composeType}Compose`,\n timeout: 30000,\n });\n\n // Receive stream from composer\n composeChannel.receiveStream(async (stream, metadata) => {\n console.log('[EncodeWorker] receiveStream', metadata);\n if (metadata?.streamType === 'video' && this.videoEncoder) {\n // Process video frames\n const reader = stream.getReader();\n try {\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n\n // value might be wrapped object {frame, metadata} or plain VideoFrame\n const wrappedValue = value as any;\n const videoFrame = wrappedValue.frame || wrappedValue;\n\n try {\n const frame = (videoFrame as VideoFrame).clone();\n this.videoEncoder.encode(frame);\n } finally {\n // Close the original frame after cloning and encoding\n (videoFrame as VideoFrame).close();\n }\n }\n } finally {\n reader.releaseLock();\n }\n } else if (metadata?.streamType === 'audio' && this.audioEncoder) {\n const composedConfig = {\n sampleRate: metadata.sampleRate,\n numberOfChannels: metadata.numberOfChannels,\n };\n\n const currentConfig = this.audioEncoder.getConfig();\n\n if (\n typeof composedConfig.sampleRate === 'number' &&\n composedConfig.sampleRate > 0 &&\n composedConfig.sampleRate !== currentConfig.sampleRate\n ) {\n await this.audioEncoder.reconfigure({ sampleRate: composedConfig.sampleRate });\n }\n\n if (\n typeof composedConfig.numberOfChannels === 'number' &&\n composedConfig.numberOfChannels > 0 &&\n composedConfig.numberOfChannels !== currentConfig.numberOfChannels\n ) {\n await this.audioEncoder.reconfigure({\n numberOfChannels: composedConfig.numberOfChannels,\n });\n }\n\n const reader = stream.getReader();\n try {\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n\n this.audioEncoder.encode(value as unknown as AudioData);\n }\n } finally {\n reader.releaseLock();\n }\n }\n });\n\n return { success: true };\n }\n\n /**\n * Connect to cache manager for output streaming\n */\n // private async handleConnectCache(payload: { port: MessagePort }): Promise<{ success: boolean }> {\n // this.cachePort = payload.port;\n // return { success: true };\n // }\n\n /**\n * Connect to mux worker for output streaming\n */\n private async handleConnectMux(payload: { port: MessagePort }): Promise<{ success: boolean }> {\n this.muxPort = payload.port;\n return { success: true };\n }\n\n /**\n * Configure video encoder with specific settings\n */\n private async handleConfigureVideo(config: VideoEncoderConfig): Promise<{ success: boolean }> {\n try {\n // Create encoder if not exists (shouldn't happen if configure was called)\n if (!this.videoEncoder) {\n this.videoEncoder = new VideoChunkEncoder(config);\n await this.videoEncoder.initialize();\n } else {\n await this.videoEncoder.reconfigure(config);\n }\n\n // Notify configuration complete\n this.channel.notify('video_configured', {\n codec: config.codec,\n width: config.width,\n height: config.height,\n bitrate: config.bitrate,\n });\n\n return { success: true };\n } catch (error: any) {\n throw {\n code: 'VIDEO_CONFIG_ERROR',\n message: error.message,\n };\n }\n }\n\n /**\n * Configure audio encoder with specific settings\n */\n private async handleConfigureAudio(config: AudioEncoderConfig): Promise<{ success: boolean }> {\n try {\n // Create encoder if not exists (shouldn't happen if configure was called)\n if (!this.audioEncoder) {\n this.audioEncoder = new AudioChunkEncoder(config);\n await this.audioEncoder.initialize();\n } else {\n await this.audioEncoder.reconfigure(config);\n }\n\n // Notify configuration complete\n this.channel.notify('audio_configured', {\n codec: config.codec,\n sampleRate: config.sampleRate,\n numberOfChannels: config.numberOfChannels,\n bitrate: config.bitrate,\n });\n\n return { success: true };\n } catch (error: any) {\n throw {\n code: 'AUDIO_CONFIG_ERROR',\n message: error.message,\n };\n }\n }\n\n /**\n * Flush encoders and get buffered chunks\n */\n private async handleFlush(payload?: { type?: 'video' | 'audio' }): Promise<{\n videoChunks?: any[];\n audioChunks?: any[];\n }> {\n try {\n const result: any = {};\n\n if (!payload?.type || payload.type === 'video') {\n const chunks = await this.videoEncoder?.flush();\n if (chunks) {\n result.videoChunks = chunks;\n }\n }\n\n if (!payload?.type || payload.type === 'audio') {\n const chunks = await this.audioEncoder?.flush();\n if (chunks) {\n result.audioChunks = chunks;\n }\n }\n\n return result;\n } catch (error: any) {\n throw {\n code: 'FLUSH_ERROR',\n message: error.message,\n };\n }\n }\n\n /**\n * Reset encoders\n */\n private async handleReset(payload?: { type?: 'video' | 'audio' }): Promise<{ success: boolean }> {\n try {\n if (!payload?.type || payload.type === 'video') {\n await this.videoEncoder?.reset();\n }\n if (!payload?.type || payload.type === 'audio') {\n await this.audioEncoder?.reset();\n }\n\n // Notify reset complete\n this.channel.notify('reset_complete', {\n type: payload?.type || 'all',\n });\n\n return { success: true };\n } catch (error: any) {\n throw {\n code: 'RESET_ERROR',\n message: error.message,\n };\n }\n }\n\n /**\n * Get encoder statistics\n */\n private async handleGetStats(): Promise<{\n video?: any;\n audio?: any;\n }> {\n const stats: any = {};\n\n if (this.videoEncoder) {\n stats.video = {\n configured: this.videoEncoder.isReady,\n queueSize: this.videoEncoder.queueSize,\n };\n }\n\n if (this.audioEncoder) {\n stats.audio = {\n configured: this.audioEncoder.isReady,\n queueSize: this.audioEncoder.queueSize,\n };\n }\n\n return stats;\n }\n\n // Output and error handling is done via streams in the encoder itself\n // These placeholder methods can be implemented when needed for direct callback handling\n\n /**\n * Dispose worker and cleanup resources\n */\n private async handleDispose(): Promise<{ success: boolean }> {\n // Close encoders\n await this.videoEncoder?.close();\n await this.audioEncoder?.close();\n\n this.videoEncoder = null;\n this.audioEncoder = null;\n\n // Close connections\n this.cachePort?.close();\n this.cachePort = null;\n\n this.muxPort?.close();\n this.muxPort = null;\n\n for (const port of this.composePorts.values()) {\n port.close();\n }\n this.composePorts.clear();\n\n this.channel.state = WorkerState.Disposed;\n\n return { success: true };\n }\n}\n\n// Initialize worker\nconst worker = new EncodeWorker();\n\n// Handle worker termination\nself.addEventListener('beforeunload', () => {\n worker['handleDispose']();\n});\n\nexport default null; // Required for TypeScript worker compilation\n"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export { VideoChunkEncoder } from './VideoChunkEncoder';
|
|
2
|
+
export { AudioChunkEncoder } from './AudioChunkEncoder';
|
|
3
|
+
export { BaseEncoder } from './BaseEncoder';
|
|
4
|
+
export { EncoderPool } from './EncoderPool';
|
|
5
|
+
export * from './types';
|
|
6
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/stages/encode/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,cAAc,SAAS,CAAC"}
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
export interface VideoEncoderConfig {
|
|
2
|
+
codec: string;
|
|
3
|
+
width: number;
|
|
4
|
+
height: number;
|
|
5
|
+
bitrate?: number;
|
|
6
|
+
framerate?: number;
|
|
7
|
+
hardwareAcceleration?: HardwarePreference;
|
|
8
|
+
scalabilityMode?: string;
|
|
9
|
+
latencyMode?: LatencyMode;
|
|
10
|
+
bitrateMode?: BitrateMode;
|
|
11
|
+
avc?: AvcEncoderConfig;
|
|
12
|
+
backpressure?: {
|
|
13
|
+
highWaterMark?: number;
|
|
14
|
+
encodeQueueThreshold?: number;
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
export interface AudioEncoderConfig {
|
|
18
|
+
codec: string;
|
|
19
|
+
sampleRate: number;
|
|
20
|
+
numberOfChannels: number;
|
|
21
|
+
bitrate?: number;
|
|
22
|
+
opus?: OpusEncoderConfig;
|
|
23
|
+
aac?: AacEncoderConfig;
|
|
24
|
+
backpressure?: {
|
|
25
|
+
highWaterMark?: number;
|
|
26
|
+
encodeQueueThreshold?: number;
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
export interface AvcEncoderConfig {
|
|
30
|
+
format?: 'avc' | 'annexb';
|
|
31
|
+
}
|
|
32
|
+
export interface OpusEncoderConfig {
|
|
33
|
+
complexity?: number;
|
|
34
|
+
signal?: 'auto' | 'music' | 'voice';
|
|
35
|
+
application?: 'voip' | 'audio' | 'lowdelay';
|
|
36
|
+
packetlossperc?: number;
|
|
37
|
+
useinbandfec?: boolean;
|
|
38
|
+
usedtx?: boolean;
|
|
39
|
+
}
|
|
40
|
+
export interface AacEncoderConfig {
|
|
41
|
+
format?: 'aac' | 'adts';
|
|
42
|
+
}
|
|
43
|
+
export type HardwarePreference = 'no-preference' | 'prefer-hardware' | 'prefer-software';
|
|
44
|
+
export type LatencyMode = 'quality' | 'realtime';
|
|
45
|
+
export type BitrateMode = 'constant' | 'variable' | 'quantizer';
|
|
46
|
+
export interface EncoderPreset {
|
|
47
|
+
name: string;
|
|
48
|
+
description: string;
|
|
49
|
+
video?: Partial<VideoEncoderConfig>;
|
|
50
|
+
audio?: Partial<AudioEncoderConfig>;
|
|
51
|
+
}
|
|
52
|
+
export interface EncodedChunkWithMetadata {
|
|
53
|
+
chunk: EncodedVideoChunk | EncodedAudioChunk;
|
|
54
|
+
timestamp: number;
|
|
55
|
+
duration?: number;
|
|
56
|
+
isKeyFrame?: boolean;
|
|
57
|
+
}
|
|
58
|
+
export interface EncoderStats {
|
|
59
|
+
encodedFrames: number;
|
|
60
|
+
droppedFrames: number;
|
|
61
|
+
encodedBytes: number;
|
|
62
|
+
averageBitrate: number;
|
|
63
|
+
currentBitrate: number;
|
|
64
|
+
encodingTime: number;
|
|
65
|
+
queueSize: number;
|
|
66
|
+
}
|
|
67
|
+
export interface BitrateController {
|
|
68
|
+
targetBitrate: number;
|
|
69
|
+
minBitrate: number;
|
|
70
|
+
maxBitrate: number;
|
|
71
|
+
mode: BitrateMode;
|
|
72
|
+
adaptiveBitrate: boolean;
|
|
73
|
+
qualityLevel?: number;
|
|
74
|
+
}
|
|
75
|
+
export interface CodecCapability {
|
|
76
|
+
codec: string;
|
|
77
|
+
supported: boolean;
|
|
78
|
+
hardwareAccelerated: boolean;
|
|
79
|
+
maxWidth?: number;
|
|
80
|
+
maxHeight?: number;
|
|
81
|
+
maxFramerate?: number;
|
|
82
|
+
profiles?: string[];
|
|
83
|
+
}
|
|
84
|
+
export interface EncoderPoolOptions {
|
|
85
|
+
maxVideoEncoders?: number;
|
|
86
|
+
maxAudioEncoders?: number;
|
|
87
|
+
reuseEncoders?: boolean;
|
|
88
|
+
preWarmEncoders?: boolean;
|
|
89
|
+
}
|
|
90
|
+
export interface EncoderHandle {
|
|
91
|
+
id: string;
|
|
92
|
+
type: 'video' | 'audio';
|
|
93
|
+
encoder: VideoEncoder | AudioEncoder;
|
|
94
|
+
config: VideoEncoderConfig | AudioEncoderConfig;
|
|
95
|
+
stats: EncoderStats;
|
|
96
|
+
inUse: boolean;
|
|
97
|
+
createdAt: number;
|
|
98
|
+
lastUsedAt: number;
|
|
99
|
+
}
|
|
100
|
+
export interface EncodingProgress {
|
|
101
|
+
totalFrames: number;
|
|
102
|
+
encodedFrames: number;
|
|
103
|
+
progress: number;
|
|
104
|
+
estimatedTimeRemaining: number;
|
|
105
|
+
currentFps: number;
|
|
106
|
+
}
|
|
107
|
+
export interface EncoderErrorEvent {
|
|
108
|
+
type: 'video' | 'audio';
|
|
109
|
+
error: DOMException;
|
|
110
|
+
timestamp: number;
|
|
111
|
+
recoverable: boolean;
|
|
112
|
+
}
|
|
113
|
+
export interface EncoderOutput {
|
|
114
|
+
videoChunks: EncodedVideoChunk[];
|
|
115
|
+
audioChunks: EncodedAudioChunk[];
|
|
116
|
+
metadata: {
|
|
117
|
+
duration: number;
|
|
118
|
+
videoCodec: string;
|
|
119
|
+
audioCodec: string;
|
|
120
|
+
width: number;
|
|
121
|
+
height: number;
|
|
122
|
+
framerate: number;
|
|
123
|
+
sampleRate: number;
|
|
124
|
+
numberOfChannels: number;
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/stages/encode/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,oBAAoB,CAAC,EAAE,kBAAkB,CAAC;IAC1C,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,GAAG,CAAC,EAAE,gBAAgB,CAAC;IAGvB,YAAY,CAAC,EAAE;QACb,aAAa,CAAC,EAAE,MAAM,CAAC;QACvB,oBAAoB,CAAC,EAAE,MAAM,CAAC;KAC/B,CAAC;CACH;AAED,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;IACnB,gBAAgB,EAAE,MAAM,CAAC;IACzB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,iBAAiB,CAAC;IACzB,GAAG,CAAC,EAAE,gBAAgB,CAAC;IAGvB,YAAY,CAAC,EAAE;QACb,aAAa,CAAC,EAAE,MAAM,CAAC;QACvB,oBAAoB,CAAC,EAAE,MAAM,CAAC;KAC/B,CAAC;CACH;AAED,MAAM,WAAW,gBAAgB;IAC/B,MAAM,CAAC,EAAE,KAAK,GAAG,QAAQ,CAAC;CAC3B;AAED,MAAM,WAAW,iBAAiB;IAChC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,GAAG,OAAO,CAAC;IACpC,WAAW,CAAC,EAAE,MAAM,GAAG,OAAO,GAAG,UAAU,CAAC;IAC5C,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED,MAAM,WAAW,gBAAgB;IAC/B,MAAM,CAAC,EAAE,KAAK,GAAG,MAAM,CAAC;CACzB;AAED,MAAM,MAAM,kBAAkB,GAAG,eAAe,GAAG,iBAAiB,GAAG,iBAAiB,CAAC;AACzF,MAAM,MAAM,WAAW,GAAG,SAAS,GAAG,UAAU,CAAC;AACjD,MAAM,MAAM,WAAW,GAAG,UAAU,GAAG,UAAU,GAAG,WAAW,CAAC;AAEhE,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,CAAC,EAAE,OAAO,CAAC,kBAAkB,CAAC,CAAC;IACpC,KAAK,CAAC,EAAE,OAAO,CAAC,kBAAkB,CAAC,CAAC;CACrC;AAED,MAAM,WAAW,wBAAwB;IACvC,KAAK,EAAE,iBAAiB,GAAG,iBAAiB,CAAC;IAC7C,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,MAAM,WAAW,YAAY;IAC3B,aAAa,EAAE,MAAM,CAAC;IACtB,aAAa,EAAE,MAAM,CAAC;IACtB,YAAY,EAAE,MAAM,CAAC;IACrB,cAAc,EAAE,MAAM,CAAC;IACvB,cAAc,EAAE,MAAM,CAAC;IACvB,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,iBAAiB;IAChC,aAAa,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,WAAW,CAAC;IAClB,eAAe,EAAE,OAAO,CAAC;IACzB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,OAAO,CAAC;IACnB,mBAAmB,EAAE,OAAO,CAAC;IAC7B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;CACrB;AAED,MAAM,WAAW,kBAAkB;IACjC,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,eAAe,CAAC,EAAE,OAAO,CAAC;CAC3B;AAED,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,OAAO,GAAG,OAAO,CAAC;IACxB,OAAO,EAAE,YAAY,GAAG,YAAY,CAAC;IACrC,MAAM,EAAE,kBAAkB,GAAG,kBAAkB,CAAC;IAChD,KAAK,EAAE,YAAY,CAAC;IACpB,KAAK,EAAE,OAAO,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,gBAAgB;IAC/B,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,MAAM,CAAC;IACtB,QAAQ,EAAE,MAAM,CAAC;IACjB,sBAAsB,EAAE,MAAM,CAAC;IAC/B,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,OAAO,GAAG,OAAO,CAAC;IACxB,KAAK,EAAE,YAAY,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,OAAO,CAAC;CACtB;AAED,MAAM,WAAW,aAAa;IAC5B,WAAW,EAAE,iBAAiB,EAAE,CAAC;IACjC,WAAW,EAAE,iBAAiB,EAAE,CAAC;IACjC,QAAQ,EAAE;QACR,QAAQ,EAAE,MAAM,CAAC;QACjB,UAAU,EAAE,MAAM,CAAC;QACnB,UAAU,EAAE,MAAM,CAAC;QACnB,KAAK,EAAE,MAAM,CAAC;QACd,MAAM,EAAE,MAAM,CAAC;QACf,SAAS,EAAE,MAAM,CAAC;QAClB,UAAU,EAAE,MAAM,CAAC;QACnB,gBAAgB,EAAE,MAAM,CAAC;KAC1B,CAAC;CACH"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { Resource, CompositionModel } from '../../model';
|
|
2
|
+
import { Orchestrator } from './types';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Handles resource events from Orchestrator
|
|
6
|
+
*/
|
|
7
|
+
export declare class EventHandlers {
|
|
8
|
+
private orchestrator;
|
|
9
|
+
private onResourceLoad;
|
|
10
|
+
private onResourceCancel;
|
|
11
|
+
private onModelSet;
|
|
12
|
+
private eventHandlers;
|
|
13
|
+
constructor(orchestrator: Orchestrator, onResourceLoad: (resource: Resource, priority?: 'high' | 'normal' | 'low') => void, onResourceCancel: (resourceId: string) => void, onModelSet: (model: CompositionModel) => void);
|
|
14
|
+
/**
|
|
15
|
+
* Setup event handlers
|
|
16
|
+
*/
|
|
17
|
+
private setupHandlers;
|
|
18
|
+
/**
|
|
19
|
+
* Handle resource add event
|
|
20
|
+
*/
|
|
21
|
+
private handleResourceAdd;
|
|
22
|
+
/**
|
|
23
|
+
* Handle resource update event
|
|
24
|
+
*/
|
|
25
|
+
private handleResourceUpdate;
|
|
26
|
+
/**
|
|
27
|
+
* Handle resource remove event
|
|
28
|
+
*/
|
|
29
|
+
private handleResourceRemove;
|
|
30
|
+
/**
|
|
31
|
+
* Clean up event handlers
|
|
32
|
+
*/
|
|
33
|
+
dispose(): void;
|
|
34
|
+
}
|
|
35
|
+
//# sourceMappingURL=EventHandlers.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"EventHandlers.d.ts","sourceRoot":"","sources":["../../../src/stages/load/EventHandlers.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAC9D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAE5C;;GAEG;AACH,qBAAa,aAAa;IAItB,OAAO,CAAC,YAAY;IACpB,OAAO,CAAC,cAAc;IACtB,OAAO,CAAC,gBAAgB;IACxB,OAAO,CAAC,UAAU;IANpB,OAAO,CAAC,aAAa,CAA0C;gBAGrD,YAAY,EAAE,YAAY,EAC1B,cAAc,EAAE,CAAC,QAAQ,EAAE,QAAQ,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,QAAQ,GAAG,KAAK,KAAK,IAAI,EAClF,gBAAgB,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,IAAI,EAC9C,UAAU,EAAE,CAAC,KAAK,EAAE,gBAAgB,KAAK,IAAI;IAKvD;;OAEG;IACH,OAAO,CAAC,aAAa;IAcrB;;OAEG;IACH,OAAO,CAAC,iBAAiB;IASzB;;OAEG;IACH,OAAO,CAAC,oBAAoB;IAW5B;;OAEG;IACH,OAAO,CAAC,oBAAoB;IAI5B;;OAEG;IACH,OAAO,IAAI,IAAI;CAMhB"}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { MeframeEvent } from "../../event/events.js";
|
|
2
|
+
class EventHandlers {
|
|
3
|
+
constructor(orchestrator, onResourceLoad, onResourceCancel, onModelSet) {
|
|
4
|
+
this.orchestrator = orchestrator;
|
|
5
|
+
this.onResourceLoad = onResourceLoad;
|
|
6
|
+
this.onResourceCancel = onResourceCancel;
|
|
7
|
+
this.onModelSet = onModelSet;
|
|
8
|
+
this.setupHandlers();
|
|
9
|
+
}
|
|
10
|
+
eventHandlers = /* @__PURE__ */ new Map();
|
|
11
|
+
/**
|
|
12
|
+
* Setup event handlers
|
|
13
|
+
*/
|
|
14
|
+
setupHandlers() {
|
|
15
|
+
const handlers = {
|
|
16
|
+
[MeframeEvent.ResourceAdd]: (event) => this.handleResourceAdd(event),
|
|
17
|
+
[MeframeEvent.ResourceUpdate]: (event) => this.handleResourceUpdate(event),
|
|
18
|
+
[MeframeEvent.ResourceRemove]: (event) => this.handleResourceRemove(event),
|
|
19
|
+
[MeframeEvent.ModelSet]: (model) => this.onModelSet(model)
|
|
20
|
+
};
|
|
21
|
+
for (const [event, handler] of Object.entries(handlers)) {
|
|
22
|
+
this.orchestrator.on(event, handler);
|
|
23
|
+
this.eventHandlers.set(event, handler);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Handle resource add event
|
|
28
|
+
*/
|
|
29
|
+
handleResourceAdd(event) {
|
|
30
|
+
if (!event.resource) return;
|
|
31
|
+
const resource = event.resource;
|
|
32
|
+
if (resource.state === "pending" || resource.state === void 0) {
|
|
33
|
+
this.onResourceLoad(resource);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Handle resource update event
|
|
38
|
+
*/
|
|
39
|
+
handleResourceUpdate(event) {
|
|
40
|
+
if (!event.resource) return;
|
|
41
|
+
const resource = event.resource;
|
|
42
|
+
if (event.oldState === "error" && resource.state === "pending") {
|
|
43
|
+
this.onResourceLoad(resource, "high");
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Handle resource remove event
|
|
48
|
+
*/
|
|
49
|
+
handleResourceRemove(event) {
|
|
50
|
+
this.onResourceCancel(event.resourceId);
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Clean up event handlers
|
|
54
|
+
*/
|
|
55
|
+
dispose() {
|
|
56
|
+
for (const [event, handler] of this.eventHandlers) {
|
|
57
|
+
this.orchestrator.off(event, handler);
|
|
58
|
+
}
|
|
59
|
+
this.eventHandlers.clear();
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
export {
|
|
63
|
+
EventHandlers
|
|
64
|
+
};
|
|
65
|
+
//# sourceMappingURL=EventHandlers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"EventHandlers.js","sources":["../../../src/stages/load/EventHandlers.ts"],"sourcesContent":["import { MeframeEvent, ResourceEvent } from '../../event/events';\nimport type { Resource, CompositionModel } from '../../model';\nimport type { Orchestrator } from './types';\n\n/**\n * Handles resource events from Orchestrator\n */\nexport class EventHandlers {\n private eventHandlers = new Map<string, (data: any) => void>();\n\n constructor(\n private orchestrator: Orchestrator,\n private onResourceLoad: (resource: Resource, priority?: 'high' | 'normal' | 'low') => void,\n private onResourceCancel: (resourceId: string) => void,\n private onModelSet: (model: CompositionModel) => void\n ) {\n this.setupHandlers();\n }\n\n /**\n * Setup event handlers\n */\n private setupHandlers(): void {\n const handlers = {\n [MeframeEvent.ResourceAdd]: (event: ResourceEvent) => this.handleResourceAdd(event),\n [MeframeEvent.ResourceUpdate]: (event: ResourceEvent) => this.handleResourceUpdate(event),\n [MeframeEvent.ResourceRemove]: (event: ResourceEvent) => this.handleResourceRemove(event),\n [MeframeEvent.ModelSet]: (model: CompositionModel) => this.onModelSet(model),\n };\n\n for (const [event, handler] of Object.entries(handlers)) {\n this.orchestrator.on(event, handler);\n this.eventHandlers.set(event, handler);\n }\n }\n\n /**\n * Handle resource add event\n */\n private handleResourceAdd(event: ResourceEvent): void {\n if (!event.resource) return;\n\n const resource = event.resource;\n if (resource.state === 'pending' || resource.state === undefined) {\n this.onResourceLoad(resource);\n }\n }\n\n /**\n * Handle resource update event\n */\n private handleResourceUpdate(event: ResourceEvent): void {\n if (!event.resource) return;\n\n const resource = event.resource;\n\n // Retry if error state changed to pending\n if (event.oldState === 'error' && resource.state === 'pending') {\n this.onResourceLoad(resource, 'high');\n }\n }\n\n /**\n * Handle resource remove event\n */\n private handleResourceRemove(event: ResourceEvent): void {\n this.onResourceCancel(event.resourceId);\n }\n\n /**\n * Clean up event handlers\n */\n dispose(): void {\n for (const [event, handler] of this.eventHandlers) {\n this.orchestrator.off(event, handler);\n }\n this.eventHandlers.clear();\n }\n}\n"],"names":[],"mappings":";AAOO,MAAM,cAAc;AAAA,EAGzB,YACU,cACA,gBACA,kBACA,YACR;AAJQ,SAAA,eAAA;AACA,SAAA,iBAAA;AACA,SAAA,mBAAA;AACA,SAAA,aAAA;AAER,SAAK,cAAA;AAAA,EACP;AAAA,EATQ,oCAAoB,IAAA;AAAA;AAAA;AAAA;AAAA,EAcpB,gBAAsB;AAC5B,UAAM,WAAW;AAAA,MACf,CAAC,aAAa,WAAW,GAAG,CAAC,UAAyB,KAAK,kBAAkB,KAAK;AAAA,MAClF,CAAC,aAAa,cAAc,GAAG,CAAC,UAAyB,KAAK,qBAAqB,KAAK;AAAA,MACxF,CAAC,aAAa,cAAc,GAAG,CAAC,UAAyB,KAAK,qBAAqB,KAAK;AAAA,MACxF,CAAC,aAAa,QAAQ,GAAG,CAAC,UAA4B,KAAK,WAAW,KAAK;AAAA,IAAA;AAG7E,eAAW,CAAC,OAAO,OAAO,KAAK,OAAO,QAAQ,QAAQ,GAAG;AACvD,WAAK,aAAa,GAAG,OAAO,OAAO;AACnC,WAAK,cAAc,IAAI,OAAO,OAAO;AAAA,IACvC;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKQ,kBAAkB,OAA4B;AACpD,QAAI,CAAC,MAAM,SAAU;AAErB,UAAM,WAAW,MAAM;AACvB,QAAI,SAAS,UAAU,aAAa,SAAS,UAAU,QAAW;AAChE,WAAK,eAAe,QAAQ;AAAA,IAC9B;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKQ,qBAAqB,OAA4B;AACvD,QAAI,CAAC,MAAM,SAAU;AAErB,UAAM,WAAW,MAAM;AAGvB,QAAI,MAAM,aAAa,WAAW,SAAS,UAAU,WAAW;AAC9D,WAAK,eAAe,UAAU,MAAM;AAAA,IACtC;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKQ,qBAAqB,OAA4B;AACvD,SAAK,iBAAiB,MAAM,UAAU;AAAA,EACxC;AAAA;AAAA;AAAA;AAAA,EAKA,UAAgB;AACd,eAAW,CAAC,OAAO,OAAO,KAAK,KAAK,eAAe;AACjD,WAAK,aAAa,IAAI,OAAO,OAAO;AAAA,IACtC;AACA,SAAK,cAAc,MAAA;AAAA,EACrB;AACF;"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { Orchestrator, ResourceLoadOptions, LoadTask, ResourceLoaderOptions } from './types';
|
|
2
|
+
|
|
3
|
+
export declare class ResourceLoader {
|
|
4
|
+
private orchestrator?;
|
|
5
|
+
private model?;
|
|
6
|
+
private taskManager;
|
|
7
|
+
private streamFactory;
|
|
8
|
+
private eventHandlers?;
|
|
9
|
+
private eventBus?;
|
|
10
|
+
private onStateChange?;
|
|
11
|
+
private byteRangeResolver;
|
|
12
|
+
constructor(options?: ResourceLoaderOptions);
|
|
13
|
+
/**
|
|
14
|
+
* Bind to Orchestrator event system
|
|
15
|
+
*/
|
|
16
|
+
bind(orchestrator: Orchestrator): void;
|
|
17
|
+
/**
|
|
18
|
+
* Unbind from Orchestrator
|
|
19
|
+
*/
|
|
20
|
+
unbind(): void;
|
|
21
|
+
private handleModelSet;
|
|
22
|
+
private enqueueLoad;
|
|
23
|
+
private processQueue;
|
|
24
|
+
private startLoad;
|
|
25
|
+
private loadNonStreamingResource;
|
|
26
|
+
private transferToDemuxWorker;
|
|
27
|
+
private updateResourceState;
|
|
28
|
+
fetch(resourceId?: string, options?: ResourceLoadOptions): Promise<void>;
|
|
29
|
+
cancel(resourceId: string): void;
|
|
30
|
+
pause(resourceId: string): void;
|
|
31
|
+
resume(resourceId: string, options?: ResourceLoadOptions): Promise<void>;
|
|
32
|
+
get activeTasks(): Map<string, LoadTask>;
|
|
33
|
+
get taskQueue(): LoadTask[];
|
|
34
|
+
dispose(): void;
|
|
35
|
+
}
|
|
36
|
+
//# sourceMappingURL=ResourceLoader.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ResourceLoader.d.ts","sourceRoot":"","sources":["../../../src/stages/load/ResourceLoader.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,mBAAmB,EAAE,QAAQ,EAAE,qBAAqB,EAAE,MAAM,SAAS,CAAC;AAQlG,qBAAa,cAAc;IACzB,OAAO,CAAC,YAAY,CAAC,CAAe;IACpC,OAAO,CAAC,KAAK,CAAC,CAAmB;IACjC,OAAO,CAAC,WAAW,CAAc;IACjC,OAAO,CAAC,aAAa,CAAgB;IACrC,OAAO,CAAC,aAAa,CAAC,CAAgB;IACtC,OAAO,CAAC,QAAQ,CAAC,CAA4B;IAC7C,OAAO,CAAC,aAAa,CAAC,CAAyD;IAC/E,OAAO,CAAC,iBAAiB,CAA0B;gBAEvC,OAAO,CAAC,EAAE,qBAAqB;IAa3C;;OAEG;IACH,IAAI,CAAC,YAAY,EAAE,YAAY,GAAG,IAAI;IAYtC;;OAEG;IACH,MAAM,IAAI,IAAI;IAMd,OAAO,CAAC,cAAc;IAItB,OAAO,CAAC,WAAW;IAqBnB,OAAO,CAAC,YAAY;YAQN,SAAS;YA2CT,wBAAwB;YAaxB,qBAAqB;IAoBnC,OAAO,CAAC,mBAAmB;IAkBrB,KAAK,CAAC,UAAU,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,mBAAmB,GAAG,OAAO,CAAC,IAAI,CAAC;IAc9E,MAAM,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI;IAKhC,KAAK,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI;IAOzB,MAAM,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,mBAAmB,GAAG,OAAO,CAAC,IAAI,CAAC;IAe9E,IAAI,WAAW,IAAI,GAAG,CAAC,MAAM,EAAE,QAAQ,CAAC,CAEvC;IAED,IAAI,SAAS,IAAI,QAAQ,EAAE,CAE1B;IAED,OAAO,IAAI,IAAI;CAKhB"}
|