@meframe/core 0.3.3 → 0.3.5

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 (67) hide show
  1. package/README.md +4 -6
  2. package/dist/event/events.d.ts +4 -2
  3. package/dist/event/events.d.ts.map +1 -1
  4. package/dist/event/events.js.map +1 -1
  5. package/dist/index.d.ts +2 -2
  6. package/dist/index.js +1 -1
  7. package/dist/index.js.map +1 -1
  8. package/dist/node_modules/.pnpm/mp4-muxer@5.2.2/node_modules/mp4-muxer/build/mp4-muxer.js.map +1 -0
  9. package/dist/{medeo-fe/node_modules → node_modules}/.pnpm/mp4box@0.5.4/node_modules/mp4box/dist/mp4box.all.js +2 -2
  10. package/dist/node_modules/.pnpm/mp4box@0.5.4/node_modules/mp4box/dist/mp4box.all.js.map +1 -0
  11. package/dist/orchestrator/ExportScheduler.d.ts +2 -3
  12. package/dist/orchestrator/ExportScheduler.d.ts.map +1 -1
  13. package/dist/orchestrator/ExportScheduler.js +2 -3
  14. package/dist/orchestrator/ExportScheduler.js.map +1 -1
  15. package/dist/orchestrator/Orchestrator.d.ts +2 -1
  16. package/dist/orchestrator/Orchestrator.d.ts.map +1 -1
  17. package/dist/orchestrator/Orchestrator.js +26 -16
  18. package/dist/orchestrator/Orchestrator.js.map +1 -1
  19. package/dist/orchestrator/VideoClipSession.d.ts +1 -1
  20. package/dist/orchestrator/VideoClipSession.d.ts.map +1 -1
  21. package/dist/orchestrator/VideoClipSession.js +2 -2
  22. package/dist/orchestrator/VideoClipSession.js.map +1 -1
  23. package/dist/orchestrator/{OnDemandVideoSession.d.ts → VideoWindowDecodeSession.d.ts} +4 -4
  24. package/dist/orchestrator/VideoWindowDecodeSession.d.ts.map +1 -0
  25. package/dist/orchestrator/{OnDemandVideoSession.js → VideoWindowDecodeSession.js} +10 -10
  26. package/dist/orchestrator/VideoWindowDecodeSession.js.map +1 -0
  27. package/dist/stages/decode/index.d.ts +0 -1
  28. package/dist/stages/decode/index.d.ts.map +1 -1
  29. package/dist/{utils/video-decoder-helpers.d.ts → stages/decode/video-decoder.d.ts} +1 -1
  30. package/dist/stages/decode/video-decoder.d.ts.map +1 -0
  31. package/dist/{utils/video-decoder-helpers.js → stages/decode/video-decoder.js} +2 -2
  32. package/dist/stages/decode/video-decoder.js.map +1 -0
  33. package/dist/stages/mux/MP4Muxer.js +1 -1
  34. package/dist/utils/mp4box.js +1 -1
  35. package/dist/worker/WorkerPool.d.ts.map +1 -1
  36. package/dist/worker/WorkerPool.js +1 -5
  37. package/dist/worker/WorkerPool.js.map +1 -1
  38. package/dist/worker/types.d.ts +1 -1
  39. package/dist/worker/types.d.ts.map +1 -1
  40. package/dist/worker/types.js.map +1 -1
  41. package/dist/worker/worker-event-whitelist.d.ts.map +1 -1
  42. package/dist/worker/worker-manifest.d.ts +2 -2
  43. package/dist/worker/worker-manifest.js.map +1 -1
  44. package/dist/workers/WorkerChannel.DQK8rAab.js.map +1 -1
  45. package/dist/workers/worker-manifest.json +0 -4
  46. package/package.json +1 -1
  47. package/dist/medeo-fe/node_modules/.pnpm/mp4-muxer@5.2.2/node_modules/mp4-muxer/build/mp4-muxer.js.map +0 -1
  48. package/dist/medeo-fe/node_modules/.pnpm/mp4box@0.5.4/node_modules/mp4box/dist/mp4box.all.js.map +0 -1
  49. package/dist/orchestrator/OnDemandVideoSession.d.ts.map +0 -1
  50. package/dist/orchestrator/OnDemandVideoSession.js.map +0 -1
  51. package/dist/stages/decode/VideoChunkDecoder.d.ts +0 -49
  52. package/dist/stages/decode/VideoChunkDecoder.d.ts.map +0 -1
  53. package/dist/utils/video-decoder-helpers.d.ts.map +0 -1
  54. package/dist/utils/video-decoder-helpers.js.map +0 -1
  55. package/dist/workers/BaseDecoder.CB5XmTpS.js +0 -137
  56. package/dist/workers/BaseDecoder.CB5XmTpS.js.map +0 -1
  57. package/dist/workers/MP4Demuxer.DfWiwyjB.js +0 -7396
  58. package/dist/workers/MP4Demuxer.DfWiwyjB.js.map +0 -1
  59. package/dist/workers/stages/decode/audio-decode.worker.-DGlQrJD.js +0 -320
  60. package/dist/workers/stages/decode/audio-decode.worker.-DGlQrJD.js.map +0 -1
  61. package/dist/workers/stages/decode/video-decode.worker.BnWVUkng.js +0 -334
  62. package/dist/workers/stages/decode/video-decode.worker.BnWVUkng.js.map +0 -1
  63. package/dist/workers/stages/demux/audio-demux.worker.D-_LoVqW.js +0 -502
  64. package/dist/workers/stages/demux/audio-demux.worker.D-_LoVqW.js.map +0 -1
  65. package/dist/workers/stages/demux/video-demux.worker.BWDrLGni.js +0 -210
  66. package/dist/workers/stages/demux/video-demux.worker.BWDrLGni.js.map +0 -1
  67. /package/dist/{medeo-fe/node_modules → node_modules}/.pnpm/mp4-muxer@5.2.2/node_modules/mp4-muxer/build/mp4-muxer.js +0 -0
@@ -1,210 +0,0 @@
1
- import { W as WorkerChannel, a as WorkerMessageType, b as WorkerState } from "../../WorkerChannel.DQK8rAab.js";
2
- import { M as MP4Demuxer } from "../../MP4Demuxer.DfWiwyjB.js";
3
- class VideoDemuxWorker {
4
- channel;
5
- demuxer = null;
6
- sessionId = null;
7
- videoDownstreamPort = null;
8
- audioDownstreamPort = null;
9
- constructor() {
10
- this.channel = new WorkerChannel(self, {
11
- name: "VideoDemuxWorker",
12
- timeout: 3e4
13
- });
14
- this.setupHandlers();
15
- }
16
- /* @better-ai.mdc For test visibility */
17
- setupHandlers() {
18
- this.channel.registerHandler("configure", this.handleConfigure.bind(this));
19
- this.channel.registerHandler("connect", this.handleConnect.bind(this));
20
- this.channel.registerHandler("get_stats", this.handleGetStats.bind(this));
21
- this.channel.registerHandler(WorkerMessageType.Dispose, this.handleDispose.bind(this));
22
- this.channel.receiveStream(this.handleReceiveStream.bind(this));
23
- }
24
- // ===== Helper methods (reduce duplication) =====
25
- buildAudioDecoderConfig() {
26
- const info = this.demuxer?.audioTrackInfo;
27
- if (!info) return void 0;
28
- return {
29
- codec: info.codec,
30
- sampleRate: info.sampleRate,
31
- numberOfChannels: info.numberOfChannels,
32
- description: info.description
33
- };
34
- }
35
- sendVideoConfigure() {
36
- if (!this.videoDownstreamPort || !this.demuxer) return;
37
- const videoTrackInfo = this.demuxer.videoTrackInfo;
38
- if (!videoTrackInfo) {
39
- console.error("[VideoDemuxWorker] No video track found after ready");
40
- return;
41
- }
42
- const downstreamChannel = new WorkerChannel(this.videoDownstreamPort, {
43
- name: "VideoDemux-Decoder",
44
- timeout: 3e4
45
- });
46
- downstreamChannel.send("configure", {
47
- sessionId: this.sessionId,
48
- streamType: "video",
49
- codec: videoTrackInfo.codec,
50
- width: videoTrackInfo.width,
51
- height: videoTrackInfo.height,
52
- description: videoTrackInfo.description
53
- });
54
- }
55
- sendAudioConfigure() {
56
- if (!this.audioDownstreamPort) return;
57
- const cfg = this.buildAudioDecoderConfig();
58
- if (!cfg) return;
59
- const audioChannel = new WorkerChannel(this.audioDownstreamPort, {
60
- name: "VideoDemux-AudioDecoder",
61
- timeout: 3e4
62
- });
63
- audioChannel.send("configure", {
64
- sessionId: this.sessionId,
65
- streamType: "audio",
66
- ...cfg
67
- });
68
- }
69
- sendVideoStream(videoStream) {
70
- if (!this.videoDownstreamPort) return;
71
- const videoChannel = new WorkerChannel(this.videoDownstreamPort, {
72
- name: "VideoDemux-Decoder",
73
- timeout: 3e4
74
- });
75
- videoChannel.sendStream(videoStream, {
76
- streamType: "video",
77
- sessionId: this.sessionId
78
- });
79
- }
80
- sendAudioStream(audioStream) {
81
- if (!audioStream) return;
82
- if (this.audioDownstreamPort) {
83
- const audioChannel = new WorkerChannel(this.audioDownstreamPort, {
84
- name: "VideoDemux-AudioDecoder",
85
- timeout: 3e4
86
- });
87
- audioChannel.sendStream(audioStream, {
88
- streamType: "audio",
89
- sessionId: this.sessionId
90
- });
91
- return;
92
- }
93
- }
94
- /**
95
- * Handle connection from orchestrator
96
- */
97
- async handleConnect(payload) {
98
- const { port, sessionId, direction, streamType } = payload;
99
- if (!port) {
100
- return { success: false };
101
- }
102
- if (direction === "downstream") {
103
- if (streamType === "audio") {
104
- this.audioDownstreamPort = port;
105
- } else {
106
- this.videoDownstreamPort = port;
107
- }
108
- }
109
- this.sessionId = sessionId || null;
110
- return { success: true };
111
- }
112
- /**
113
- * Configure demuxer with format settings
114
- * @param payload.config - Demuxer configuration
115
- * @param payload.initial - If true, initialize worker state; otherwise just update config
116
- */
117
- async handleConfigure(payload) {
118
- const { config, initial = false } = payload;
119
- try {
120
- if (initial) {
121
- this.channel.state = WorkerState.Ready;
122
- if (this.demuxer) {
123
- this.demuxer.destroy();
124
- }
125
- this.demuxer = new MP4Demuxer({
126
- ...config,
127
- onReady: () => this.handleDemuxerReady()
128
- });
129
- this.channel.notify("configured");
130
- return { success: true };
131
- } else {
132
- this.demuxer?.updateConfig(config);
133
- return { success: true };
134
- }
135
- } catch (error) {
136
- throw {
137
- code: error.code || "CONFIG_ERROR",
138
- message: error.message
139
- };
140
- }
141
- }
142
- /**
143
- * Handle input stream from ResourceLoader (main thread)
144
- * Strategy: Stream immediately, send codec info when ready
145
- */
146
- async handleReceiveStream(stream, metadata) {
147
- if (!this.sessionId) {
148
- this.sessionId = metadata?.sessionId || this.sessionId;
149
- }
150
- if (!this.demuxer) {
151
- this.demuxer = new MP4Demuxer({
152
- highWaterMark: 10,
153
- onReady: () => this.handleDemuxerReady()
154
- });
155
- }
156
- if (!this.videoDownstreamPort) {
157
- console.error("[VideoDemuxWorker] Decoder not connected", this.sessionId);
158
- return;
159
- }
160
- const videoStream = this.demuxer.createVideoStream();
161
- const audioStream = this.demuxer.createAudioStream();
162
- this.sendVideoStream(videoStream);
163
- this.sendAudioStream(audioStream);
164
- const inputStream = this.demuxer.createInputStream();
165
- await stream.pipeTo(inputStream).catch((error) => {
166
- console.error("[VideoDemuxWorker] Input stream error:", this.sessionId, error);
167
- });
168
- }
169
- handleDemuxerReady() {
170
- if (!this.demuxer) return;
171
- this.sendVideoConfigure();
172
- this.sendAudioConfigure();
173
- }
174
- /**
175
- * Get demuxer statistics
176
- */
177
- async handleGetStats() {
178
- if (!this.demuxer) {
179
- return { state: this.channel.state };
180
- }
181
- return {
182
- tracksInfo: Array.from(this.demuxer.tracks.values()),
183
- state: this.channel.state
184
- };
185
- }
186
- /**
187
- * Dispose worker and cleanup resources
188
- */
189
- async handleDispose() {
190
- this.demuxer?.destroy();
191
- this.demuxer = null;
192
- this.sessionId = null;
193
- this.videoDownstreamPort?.close();
194
- this.videoDownstreamPort = null;
195
- this.audioDownstreamPort?.close();
196
- this.audioDownstreamPort = null;
197
- this.channel.state = WorkerState.Disposed;
198
- return { success: true };
199
- }
200
- }
201
- const worker = new VideoDemuxWorker();
202
- self.addEventListener("beforeunload", () => {
203
- worker["handleDispose"]();
204
- });
205
- const videoDemux_worker = null;
206
- export {
207
- VideoDemuxWorker,
208
- videoDemux_worker as default
209
- };
210
- //# sourceMappingURL=video-demux.worker.BWDrLGni.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"video-demux.worker.BWDrLGni.js","sources":["../../../../src/stages/demux/video-demux.worker.ts"],"sourcesContent":["/**\n * @deprecated VideoDemuxWorker is deprecated and will be removed in a future version.\n *\n * Reason: This worker is no longer needed for export pipeline.\n * The export process now uses IndexedVideoSource (main thread) which directly reads\n * from OPFS using pre-parsed MP4 index, avoiding the need to transfer entire files\n * to this worker and re-parse moov.\n *\n * Replacement: IndexedVideoSource (packages/core/src/stages/demux/IndexedVideoSource.ts)\n *\n * This file is kept for backward compatibility only and may be removed in the future.\n */\n\nimport { WorkerChannel } from '../../worker/WorkerChannel';\nimport { WorkerMessageType, WorkerState } from '../../worker/types';\nimport { MP4Demuxer } from './MP4Demuxer';\nimport type { DemuxConfig } from './types';\n\ninterface LoaderStreamMetadata {\n sessionId?: string;\n byteStart?: number;\n byteEnd?: number;\n}\n/**\n * VideoDemuxWorker - First stage for video processing\n * Extracts video tracks from container formats (MP4, etc.)\n *\n * Pipeline: ResourceLoader (Main Thread) → VideoDemuxWorker → DecodeWorker\n *\n * Architecture Note:\n * - One VideoDemuxWorker instance per CLIP (not per resource)\n * - Multiple clips can share the same resource (different workers, independent processing)\n * - This enables clean 2-Clip strategy lifecycle management\n *\n * Features:\n * - MP4 container demuxing with mp4box.js\n * - Stream-based processing with backpressure\n * - Direct streaming to DecodeWorker\n */\nexport class VideoDemuxWorker {\n private channel: WorkerChannel;\n private demuxer: MP4Demuxer | null = null;\n private sessionId: string | null = null;\n private videoDownstreamPort: MessagePort | null = null;\n private audioDownstreamPort: MessagePort | null = null;\n\n constructor() {\n // Initialize WorkerChannel\n this.channel = new WorkerChannel(self as any, {\n name: 'VideoDemuxWorker',\n timeout: 30000,\n });\n this.setupHandlers();\n }\n\n /* @better-ai.mdc For test visibility */\n protected 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('get_stats', this.handleGetStats.bind(this));\n this.channel.registerHandler(WorkerMessageType.Dispose, this.handleDispose.bind(this));\n\n // Setup stream receiver from ResourceLoader (main thread)\n this.channel.receiveStream(this.handleReceiveStream.bind(this));\n }\n\n // ===== Helper methods (reduce duplication) =====\n private buildAudioDecoderConfig(): any {\n const info = this.demuxer?.audioTrackInfo;\n if (!info) return undefined;\n return {\n codec: info.codec,\n sampleRate: info.sampleRate,\n numberOfChannels: info.numberOfChannels,\n description: info.description,\n };\n }\n\n private sendVideoConfigure(): void {\n if (!this.videoDownstreamPort || !this.demuxer) return;\n const videoTrackInfo = this.demuxer.videoTrackInfo;\n if (!videoTrackInfo) {\n console.error('[VideoDemuxWorker] No video track found after ready');\n return;\n }\n const downstreamChannel = new WorkerChannel(this.videoDownstreamPort, {\n name: 'VideoDemux-Decoder',\n timeout: 30000,\n });\n downstreamChannel.send('configure' as any, {\n sessionId: this.sessionId,\n streamType: 'video',\n codec: videoTrackInfo.codec,\n width: videoTrackInfo.width,\n height: videoTrackInfo.height,\n description: videoTrackInfo.description,\n });\n }\n\n private sendAudioConfigure(): void {\n if (!this.audioDownstreamPort) return;\n const cfg = this.buildAudioDecoderConfig();\n if (!cfg) return;\n const audioChannel = new WorkerChannel(this.audioDownstreamPort, {\n name: 'VideoDemux-AudioDecoder',\n timeout: 30000,\n });\n audioChannel.send('configure' as any, {\n sessionId: this.sessionId,\n streamType: 'audio',\n ...cfg,\n });\n }\n\n private sendVideoStream(videoStream: ReadableStream<EncodedVideoChunk>): void {\n if (!this.videoDownstreamPort) return;\n const videoChannel = new WorkerChannel(this.videoDownstreamPort, {\n name: 'VideoDemux-Decoder',\n timeout: 30000,\n });\n videoChannel.sendStream(videoStream, {\n streamType: 'video',\n sessionId: this.sessionId,\n });\n }\n\n private sendAudioStream(audioStream: ReadableStream<EncodedAudioChunk> | null): void {\n if (!audioStream) return;\n\n // Prefer decoder when connected; otherwise emit to main when enabled\n if (this.audioDownstreamPort) {\n const audioChannel = new WorkerChannel(this.audioDownstreamPort, {\n name: 'VideoDemux-AudioDecoder',\n timeout: 30000,\n });\n audioChannel.sendStream(audioStream, {\n streamType: 'audio',\n sessionId: this.sessionId,\n });\n return;\n }\n }\n\n /**\n * Handle connection from orchestrator\n */\n private async handleConnect(payload: {\n port?: MessagePort;\n streamType?: string;\n sessionId?: string;\n direction?: string;\n }): Promise<{ success: boolean }> {\n const { port, sessionId, direction, streamType } = payload;\n\n if (!port) {\n return { success: false };\n }\n\n if (direction === 'downstream') {\n if (streamType === 'audio') {\n this.audioDownstreamPort = port;\n } else {\n this.videoDownstreamPort = port;\n }\n }\n\n this.sessionId = sessionId || null;\n return { success: true };\n }\n\n /**\n * Configure demuxer with format settings\n * @param payload.config - Demuxer configuration\n * @param payload.initial - If true, initialize worker state; otherwise just update config\n */\n private async handleConfigure(payload: {\n config: DemuxConfig;\n initial?: boolean;\n }): Promise<{ success: boolean; tracks?: any[] }> {\n const { config, initial = false } = payload;\n\n try {\n if (initial) {\n // Initial setup - set worker state to ready\n this.channel.state = WorkerState.Ready;\n\n // Create new demuxer instance\n if (this.demuxer) {\n this.demuxer.destroy();\n }\n\n this.demuxer = new MP4Demuxer({\n ...config,\n onReady: () => this.handleDemuxerReady(),\n });\n\n // Notify configuration complete\n this.channel.notify('configured');\n\n return { success: true };\n } else {\n // Update configuration only (e.g., backpressure settings)\n this.demuxer?.updateConfig(config);\n return { success: true };\n }\n } catch (error: any) {\n throw {\n code: error.code || 'CONFIG_ERROR',\n message: error.message,\n };\n }\n }\n\n /**\n * Handle input stream from ResourceLoader (main thread)\n * Strategy: Stream immediately, send codec info when ready\n */\n private async handleReceiveStream(\n stream: ReadableStream<Uint8Array | ArrayBuffer>,\n metadata?: LoaderStreamMetadata\n ): Promise<void> {\n // Store sessionId from metadata (only happens once per worker lifecycle)\n // Note: Do NOT override if already set by handleConnect (which has correct sessionId)\n if (!this.sessionId) {\n this.sessionId = metadata?.sessionId || this.sessionId;\n }\n\n // Initialize demuxer on first stream\n if (!this.demuxer) {\n this.demuxer = new MP4Demuxer({\n highWaterMark: 10,\n onReady: () => this.handleDemuxerReady(),\n });\n }\n\n // If no video downstream is connected, we can still proceed when\n // we only need to emit audio to the main thread for L2 caching.\n if (!this.videoDownstreamPort) {\n console.error('[VideoDemuxWorker] Decoder not connected', this.sessionId);\n return;\n }\n\n // Create output streams (readable only)\n const videoStream = this.demuxer.createVideoStream();\n const audioStream = this.demuxer.createAudioStream();\n\n // Send streams\n this.sendVideoStream(videoStream);\n this.sendAudioStream(audioStream);\n\n // Create input stream and pipe source to it (single appendBuffer)\n const inputStream = this.demuxer.createInputStream();\n await stream.pipeTo(inputStream).catch((error) => {\n console.error('[VideoDemuxWorker] Input stream error:', this.sessionId, error);\n });\n }\n\n private handleDemuxerReady(): void {\n if (!this.demuxer) return;\n this.sendVideoConfigure();\n this.sendAudioConfigure();\n }\n\n /**\n * Get demuxer statistics\n */\n private async handleGetStats(): Promise<{\n queueSize?: number;\n tracksInfo?: any[];\n state?: WorkerState;\n }> {\n if (!this.demuxer) {\n return { state: this.channel.state };\n }\n\n return {\n tracksInfo: Array.from(this.demuxer.tracks.values()),\n state: this.channel.state,\n };\n }\n\n /**\n * Dispose worker and cleanup resources\n */\n private async handleDispose(): Promise<{ success: boolean }> {\n // Destroy demuxer\n this.demuxer?.destroy();\n this.demuxer = null;\n this.sessionId = null;\n\n // Close connections\n this.videoDownstreamPort?.close();\n this.videoDownstreamPort = null;\n this.audioDownstreamPort?.close();\n this.audioDownstreamPort = null;\n\n this.channel.state = WorkerState.Disposed;\n\n return { success: true };\n }\n}\n// Initialize worker\nconst worker = new VideoDemuxWorker();\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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"}