@meframe/core 0.0.38-beta.3 → 0.0.39
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/orchestrator/ExportScheduler.d.ts.map +1 -1
- package/dist/orchestrator/ExportScheduler.js +11 -7
- package/dist/orchestrator/ExportScheduler.js.map +1 -1
- package/dist/orchestrator/GlobalAudioSession.d.ts.map +1 -1
- package/dist/orchestrator/GlobalAudioSession.js +19 -17
- package/dist/orchestrator/GlobalAudioSession.js.map +1 -1
- package/dist/orchestrator/OnDemandVideoSession.d.ts.map +1 -1
- package/dist/orchestrator/OnDemandVideoSession.js +1 -21
- package/dist/orchestrator/OnDemandVideoSession.js.map +1 -1
- package/dist/orchestrator/Orchestrator.d.ts +5 -1
- package/dist/orchestrator/Orchestrator.d.ts.map +1 -1
- package/dist/orchestrator/Orchestrator.js +39 -26
- package/dist/orchestrator/Orchestrator.js.map +1 -1
- package/dist/stages/compose/FrameRateConverter.d.ts +6 -1
- package/dist/stages/compose/FrameRateConverter.d.ts.map +1 -1
- package/dist/stages/decode/BaseDecoder.d.ts.map +1 -1
- package/dist/stages/decode/BaseDecoder.js +0 -29
- package/dist/stages/decode/BaseDecoder.js.map +1 -1
- package/dist/stages/decode/VideoChunkDecoder.d.ts.map +1 -1
- package/dist/stages/encode/BaseEncoder.d.ts.map +1 -1
- package/dist/stages/encode/BaseEncoder.js +0 -24
- package/dist/stages/encode/BaseEncoder.js.map +1 -1
- package/dist/stages/load/ResourceLoader.d.ts.map +1 -1
- package/dist/stages/load/ResourceLoader.js +36 -20
- package/dist/stages/load/ResourceLoader.js.map +1 -1
- package/dist/stages/load/TaskManager.d.ts +6 -1
- package/dist/stages/load/TaskManager.d.ts.map +1 -1
- package/dist/stages/load/TaskManager.js +11 -8
- package/dist/stages/load/TaskManager.js.map +1 -1
- package/dist/stages/load/types.d.ts +3 -3
- package/dist/stages/load/types.d.ts.map +1 -1
- package/dist/workers/{BaseDecoder.DWHTBMDB.js → BaseDecoder.CB5XmTpS.js} +1 -30
- package/dist/workers/BaseDecoder.CB5XmTpS.js.map +1 -0
- package/dist/workers/stages/compose/{video-compose.worker.BhpN-lxf.js → video-compose.worker.DM_bsOY8.js} +27 -4
- package/dist/workers/stages/compose/{video-compose.worker.BhpN-lxf.js.map → video-compose.worker.DM_bsOY8.js.map} +1 -1
- package/dist/workers/stages/decode/{audio-decode.worker.BsuBzFx5.js → audio-decode.worker.B__6tqsy.js} +2 -2
- package/dist/workers/stages/decode/{audio-decode.worker.BsuBzFx5.js.map → audio-decode.worker.B__6tqsy.js.map} +1 -1
- package/dist/workers/stages/decode/{video-decode.worker.CwOjEmre.js → video-decode.worker.tOv-QR2f.js} +2 -4
- package/dist/workers/stages/decode/video-decode.worker.tOv-QR2f.js.map +1 -0
- package/dist/workers/stages/encode/{video-encode.worker.CXgr5E16.js → video-encode.worker.D8pfFber.js} +1 -25
- package/dist/workers/stages/encode/video-encode.worker.D8pfFber.js.map +1 -0
- package/dist/workers/worker-manifest.json +4 -4
- package/package.json +1 -1
- package/dist/workers/BaseDecoder.DWHTBMDB.js.map +0 -1
- package/dist/workers/stages/decode/video-decode.worker.CwOjEmre.js.map +0 -1
- package/dist/workers/stages/encode/video-encode.worker.CXgr5E16.js.map +0 -1
|
@@ -9,24 +9,7 @@ class BaseDecoder {
|
|
|
9
9
|
if (this.decoder?.state === "configured") {
|
|
10
10
|
return;
|
|
11
11
|
}
|
|
12
|
-
const configInfo = {
|
|
13
|
-
codec: this.config.codec,
|
|
14
|
-
width: this.config.width,
|
|
15
|
-
height: this.config.height,
|
|
16
|
-
sampleRate: this.config.sampleRate,
|
|
17
|
-
numberOfChannels: this.config.numberOfChannels,
|
|
18
|
-
hardwareAcceleration: this.config.hardwareAcceleration
|
|
19
|
-
};
|
|
20
|
-
console.log(`[${this.getDecoderType()}Decoder] Checking config support:`, {
|
|
21
|
-
platform: typeof navigator !== "undefined" ? navigator.platform : "unknown",
|
|
22
|
-
userAgent: typeof navigator !== "undefined" ? navigator.userAgent : "unknown",
|
|
23
|
-
config: configInfo
|
|
24
|
-
});
|
|
25
12
|
const isSupported = await this.isConfigSupported(this.config);
|
|
26
|
-
console.log(`[${this.getDecoderType()}Decoder] Config support result:`, {
|
|
27
|
-
supported: isSupported.supported,
|
|
28
|
-
config: configInfo
|
|
29
|
-
});
|
|
30
13
|
if (!isSupported.supported) {
|
|
31
14
|
throw new Error(
|
|
32
15
|
`Codec not supported: ${this.config.codecString || this.config.codec}`
|
|
@@ -36,12 +19,7 @@ class BaseDecoder {
|
|
|
36
19
|
output: this.handleOutput.bind(this),
|
|
37
20
|
error: this.handleError.bind(this)
|
|
38
21
|
});
|
|
39
|
-
console.log(`[${this.getDecoderType()}Decoder] Decoder created, configuring...`);
|
|
40
22
|
await this.configureDecoder(this.config);
|
|
41
|
-
console.log(
|
|
42
|
-
`[${this.getDecoderType()}Decoder] Configured successfully, state:`,
|
|
43
|
-
this.decoder?.state
|
|
44
|
-
);
|
|
45
23
|
}
|
|
46
24
|
async reconfigure(config) {
|
|
47
25
|
this.config = { ...this.config, ...config };
|
|
@@ -107,13 +85,6 @@ class BaseDecoder {
|
|
|
107
85
|
}
|
|
108
86
|
}
|
|
109
87
|
handleError(error) {
|
|
110
|
-
console.error(`[${this.getDecoderType()}Decoder] Decode error:`, {
|
|
111
|
-
name: error.name,
|
|
112
|
-
message: error.message,
|
|
113
|
-
decoderState: this.decoder?.state,
|
|
114
|
-
queueSize: this.queueSize,
|
|
115
|
-
platform: typeof navigator !== "undefined" ? navigator.platform : "unknown"
|
|
116
|
-
});
|
|
117
88
|
this.controller?.error(error);
|
|
118
89
|
}
|
|
119
90
|
closeIfPossible(data) {
|
|
@@ -163,4 +134,4 @@ class BaseDecoder {
|
|
|
163
134
|
export {
|
|
164
135
|
BaseDecoder as B
|
|
165
136
|
};
|
|
166
|
-
//# sourceMappingURL=BaseDecoder.
|
|
137
|
+
//# sourceMappingURL=BaseDecoder.CB5XmTpS.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"BaseDecoder.CB5XmTpS.js","sources":["../../src/stages/decode/BaseDecoder.ts"],"sourcesContent":["/**\n * Base decoder class abstracting common WebCodecs decoder workflow.\n * Mirrors BaseEncoder but for decoding path.\n */\nimport { AudioDecoderConfig, DecodedVideoFrame, VideoDecoderConfig } from './types';\n\nexport abstract class BaseDecoder<\n TDecoder extends VideoDecoder | AudioDecoder,\n TConfig extends VideoDecoderConfig | AudioDecoderConfig,\n TInput extends EncodedVideoChunk | EncodedAudioChunk,\n TOutput extends VideoFrame | AudioData | DecodedVideoFrame,\n> {\n protected decoder?: TDecoder;\n protected config: TConfig;\n protected controller: TransformStreamDefaultController<TOutput> | null = null;\n\n constructor(config: TConfig) {\n this.config = config;\n }\n\n async initialize(): Promise<void> {\n if (this.decoder?.state === 'configured') {\n return;\n }\n\n const isSupported = await this.isConfigSupported(this.config);\n\n if (!isSupported.supported) {\n throw new Error(\n `Codec not supported: ${(this.config as any).codecString || (this.config as any).codec}`\n );\n }\n\n this.decoder = this.createDecoder({\n output: this.handleOutput.bind(this),\n error: this.handleError.bind(this),\n });\n\n await this.configureDecoder(this.config);\n }\n\n async reconfigure(config: Partial<TConfig>): Promise<void> {\n this.config = { ...this.config, ...config } as TConfig;\n\n if (!this.decoder) {\n await this.initialize();\n return;\n }\n\n // Flush before reconfiguring\n if (this.decoder.state === 'configured') {\n await this.decoder.flush();\n }\n\n const isSupported = await this.isConfigSupported(this.config);\n if (!isSupported.supported) {\n throw new Error(\n `New configuration not supported: ${(this.config as any).codecString || (this.config as any).codec}`\n );\n }\n\n await this.configureDecoder(this.config);\n }\n\n async flush(): Promise<void> {\n if (!this.decoder) return;\n await this.decoder.flush();\n }\n\n async reset(): Promise<void> {\n if (!this.decoder) return;\n\n // Windows Media Foundation requires flush before reset to avoid decoder error state\n if (this.decoder.state === 'configured') {\n try {\n await this.decoder.flush();\n } catch {\n // Ignore flush errors during reset\n }\n }\n\n this.decoder.reset();\n this.onReset();\n }\n\n async close(): Promise<void> {\n if (!this.decoder) return;\n\n if (this.decoder.state === 'configured') {\n await this.decoder.flush();\n }\n\n this.decoder.close();\n this.decoder = undefined;\n }\n\n get isReady(): boolean {\n return this.decoder?.state === 'configured';\n }\n\n get queueSize(): number {\n return (this.decoder as any)?.decodeQueueSize ?? 0;\n }\n\n protected handleOutput(data: TOutput): void {\n if (!this.controller) {\n this.closeIfPossible(data);\n return;\n }\n\n try {\n this.controller.enqueue(data);\n if (data instanceof VideoFrame && (this.config as VideoDecoderConfig).thread !== 'main') {\n // ugly hack to avoid memory leak\n // setTimeout(() => {\n // data.close();\n // }, 500);\n }\n } catch (error) {\n // Stream closed or errored - silently drop frame\n if (error instanceof TypeError) {\n this.closeIfPossible(data);\n return;\n }\n\n throw error;\n }\n }\n\n protected handleError(error: DOMException): void {\n this.controller?.error(error);\n }\n\n private closeIfPossible(data: TOutput): void {\n (data as any)?.close?.();\n (data as DecodedVideoFrame)?.frame?.close?.();\n }\n\n // Abstracts\n protected abstract isConfigSupported(config: TConfig): Promise<{ supported: boolean }>;\n protected abstract createDecoder(init: DecoderInit): TDecoder;\n protected abstract configureDecoder(config: TConfig): Promise<void>;\n protected abstract getDecoderType(): string;\n protected abstract decode(input: TInput): void;\n protected onReset(): void {}\n\n // Backpressure\n protected abstract readonly highWaterMark: number;\n protected abstract readonly decodeQueueThreshold: number;\n\n createStream(): TransformStream<TInput, TOutput> {\n return new TransformStream<TInput, TOutput>(\n {\n start: async (controller) => {\n this.controller = controller;\n if (!this.isReady) {\n await this.initialize();\n }\n },\n transform: async (input) => {\n if (!this.decoder || this.decoder.state !== 'configured') {\n throw new Error('Decoder not configured');\n }\n // backpressure\n if ((this.decoder as any).decodeQueueSize >= this.decodeQueueThreshold) {\n await new Promise<void>((resolve) => {\n const check = () => {\n if (\n !this.decoder ||\n (this.decoder as any).decodeQueueSize < this.decodeQueueThreshold - 1\n ) {\n resolve();\n } else {\n setTimeout(check, 10);\n }\n };\n check();\n });\n }\n this.decode(input);\n },\n flush: async () => {\n await this.flush();\n },\n },\n {\n highWaterMark: this.highWaterMark,\n size: () => 1,\n }\n );\n }\n}\n\ninterface DecoderInit {\n output: (data: any) => void;\n error: (error: DOMException) => void;\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -1760,11 +1760,12 @@ function applyEasing(t, easing) {
|
|
|
1760
1760
|
class FrameRateConverter {
|
|
1761
1761
|
clipDurationUs;
|
|
1762
1762
|
frameDurationUs;
|
|
1763
|
+
trimStartUs;
|
|
1763
1764
|
// State for frame processing
|
|
1764
1765
|
targetFrameIndex = 0;
|
|
1765
1766
|
targetFrameTimeUs = 0;
|
|
1766
1767
|
sourceFrameBuffer = [];
|
|
1767
|
-
constructor(targetFps, clipDurationUs) {
|
|
1768
|
+
constructor(targetFps, clipDurationUs, trimStartUs = 0) {
|
|
1768
1769
|
if (targetFps <= 0) {
|
|
1769
1770
|
throw new Error(`Invalid target fps: ${targetFps}`);
|
|
1770
1771
|
}
|
|
@@ -1773,6 +1774,7 @@ class FrameRateConverter {
|
|
|
1773
1774
|
}
|
|
1774
1775
|
this.clipDurationUs = clipDurationUs;
|
|
1775
1776
|
this.frameDurationUs = Math.round(1e6 / targetFps);
|
|
1777
|
+
this.trimStartUs = trimStartUs;
|
|
1776
1778
|
}
|
|
1777
1779
|
/**
|
|
1778
1780
|
* Create a TransformStream that converts VFR frames to CFR frames
|
|
@@ -1800,7 +1802,23 @@ class FrameRateConverter {
|
|
|
1800
1802
|
* Process incoming source frame and output target frames
|
|
1801
1803
|
*/
|
|
1802
1804
|
processSourceFrame(sourceFrame, controller) {
|
|
1803
|
-
|
|
1805
|
+
const sourceTimestamp = sourceFrame.timestamp ?? 0;
|
|
1806
|
+
if (sourceTimestamp < this.trimStartUs) {
|
|
1807
|
+
sourceFrame.close();
|
|
1808
|
+
return;
|
|
1809
|
+
}
|
|
1810
|
+
let frameToBuffer;
|
|
1811
|
+
if (this.trimStartUs > 0) {
|
|
1812
|
+
const adjustedTimestamp = sourceTimestamp - this.trimStartUs;
|
|
1813
|
+
frameToBuffer = new VideoFrame(sourceFrame, {
|
|
1814
|
+
timestamp: adjustedTimestamp,
|
|
1815
|
+
duration: sourceFrame.duration ?? void 0
|
|
1816
|
+
});
|
|
1817
|
+
sourceFrame.close();
|
|
1818
|
+
} else {
|
|
1819
|
+
frameToBuffer = sourceFrame;
|
|
1820
|
+
}
|
|
1821
|
+
this.sourceFrameBuffer.push(frameToBuffer);
|
|
1804
1822
|
this.sourceFrameCount++;
|
|
1805
1823
|
while (this.targetFrameTimeUs < this.clipDurationUs) {
|
|
1806
1824
|
const closestFrame = this.findClosestFrame(this.targetFrameTimeUs);
|
|
@@ -2131,10 +2149,15 @@ class VideoComposeWorker {
|
|
|
2131
2149
|
console.warn("[VideoComposeWorker] No instructions installed");
|
|
2132
2150
|
return;
|
|
2133
2151
|
}
|
|
2152
|
+
const mainLayer = this.instructions.layers.find(
|
|
2153
|
+
(l) => l.type === "video" && !l.payload.attachmentId
|
|
2154
|
+
);
|
|
2155
|
+
const trimStartUs = mainLayer?.type === "video" ? mainLayer.payload.trimStartUs ?? 0 : 0;
|
|
2134
2156
|
const timeline = this.instructions.baseConfig.timeline;
|
|
2135
2157
|
const fpsConverter = new FrameRateConverter(
|
|
2136
2158
|
timeline?.compositionFps ?? 30,
|
|
2137
|
-
timeline?.clipDurationUs ?? Infinity
|
|
2159
|
+
timeline?.clipDurationUs ?? Infinity,
|
|
2160
|
+
trimStartUs
|
|
2138
2161
|
);
|
|
2139
2162
|
const cfrStream = stream.pipeThrough(fpsConverter.createStream());
|
|
2140
2163
|
const filteredStream = cfrStream.pipeThrough(
|
|
@@ -2379,4 +2402,4 @@ export {
|
|
|
2379
2402
|
VideoComposeWorker,
|
|
2380
2403
|
videoCompose_worker as default
|
|
2381
2404
|
};
|
|
2382
|
-
//# sourceMappingURL=video-compose.worker.
|
|
2405
|
+
//# sourceMappingURL=video-compose.worker.DM_bsOY8.js.map
|