@meframe/core 0.0.11 → 0.0.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cache/CacheManager.d.ts +3 -4
- package/dist/cache/CacheManager.d.ts.map +1 -1
- package/dist/cache/CacheManager.js +5 -30
- package/dist/cache/CacheManager.js.map +1 -1
- package/dist/cache/l1/VideoL1Cache.d.ts +1 -1
- package/dist/cache/l1/VideoL1Cache.d.ts.map +1 -1
- package/dist/cache/l1/VideoL1Cache.js +1 -1
- package/dist/cache/l1/VideoL1Cache.js.map +1 -1
- package/dist/controllers/PlaybackController.d.ts.map +1 -1
- package/dist/controllers/PlaybackController.js +1 -2
- package/dist/controllers/PlaybackController.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/model/CompositionModel.d.ts +2 -1
- package/dist/model/CompositionModel.d.ts.map +1 -1
- package/dist/model/CompositionModel.js +80 -11
- package/dist/model/CompositionModel.js.map +1 -1
- package/dist/model/types.d.ts +30 -1
- package/dist/model/types.d.ts.map +1 -1
- package/dist/orchestrator/ClipSessionManager.d.ts +1 -5
- package/dist/orchestrator/ClipSessionManager.d.ts.map +1 -1
- package/dist/orchestrator/ClipSessionManager.js +1 -6
- package/dist/orchestrator/ClipSessionManager.js.map +1 -1
- package/dist/orchestrator/CompositionPlanner.d.ts.map +1 -1
- package/dist/orchestrator/CompositionPlanner.js +18 -2
- package/dist/orchestrator/CompositionPlanner.js.map +1 -1
- package/dist/orchestrator/Orchestrator.d.ts +1 -0
- package/dist/orchestrator/Orchestrator.d.ts.map +1 -1
- package/dist/orchestrator/Orchestrator.js +70 -7
- package/dist/orchestrator/Orchestrator.js.map +1 -1
- package/dist/orchestrator/VideoClipSession.d.ts +2 -1
- package/dist/orchestrator/VideoClipSession.d.ts.map +1 -1
- package/dist/orchestrator/VideoClipSession.js +16 -1
- package/dist/orchestrator/VideoClipSession.js.map +1 -1
- package/dist/stages/compose/LayerRenderer.d.ts +2 -0
- package/dist/stages/compose/LayerRenderer.d.ts.map +1 -1
- package/dist/stages/compose/instructions.d.ts +24 -1
- package/dist/stages/compose/instructions.d.ts.map +1 -1
- package/dist/stages/compose/types.d.ts +2 -0
- package/dist/stages/compose/types.d.ts.map +1 -1
- package/dist/stages/decode/BaseDecoder.js +130 -0
- package/dist/stages/decode/BaseDecoder.js.map +1 -0
- package/dist/stages/decode/VideoChunkDecoder.js +199 -0
- package/dist/stages/decode/VideoChunkDecoder.js.map +1 -0
- package/dist/stages/load/ResourceLoader.d.ts +8 -0
- package/dist/stages/load/ResourceLoader.d.ts.map +1 -1
- package/dist/stages/load/ResourceLoader.js +74 -12
- package/dist/stages/load/ResourceLoader.js.map +1 -1
- package/dist/stages/load/types.d.ts +1 -0
- package/dist/stages/load/types.d.ts.map +1 -1
- package/dist/utils/animation-utils.d.ts +16 -0
- package/dist/utils/animation-utils.d.ts.map +1 -0
- package/dist/utils/image-utils.d.ts +5 -0
- package/dist/utils/image-utils.d.ts.map +1 -0
- package/dist/utils/image-utils.js +32 -0
- package/dist/utils/image-utils.js.map +1 -0
- package/dist/workers/stages/compose/video-compose.worker.js +256 -29
- package/dist/workers/stages/compose/video-compose.worker.js.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/stages/load/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,mBAAmB,CAAC;AAC9C,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAC1D,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAGrD,MAAM,WAAW,YAAY;IAC3B,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,IAAI,EAAE,GAAG,KAAK,IAAI,GAAG,IAAI,CAAC;IACtD,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,IAAI,EAAE,GAAG,KAAK,IAAI,GAAG,IAAI,CAAC;IACvD,IAAI,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,GAAG,IAAI,CAAC;IACrC,OAAO,EAAE;QACP,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC;KAC7E,CAAC;CACH;AAGD,MAAM,WAAW,YAAY;IAC3B,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAGD,MAAM,WAAW,mBAAmB;IAClC,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,GAAG,QAAQ,GAAG,KAAK,CAAC;IACrC,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,KAAK,CAAC,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,CAAC;IACvC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/stages/load/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { Transform2D } from '../model/types';
|
|
2
|
+
|
|
3
|
+
export interface AnimationKeyframeInput {
|
|
4
|
+
time: number;
|
|
5
|
+
transform?: Transform2D;
|
|
6
|
+
opacity?: number;
|
|
7
|
+
easing?: string;
|
|
8
|
+
}
|
|
9
|
+
export declare function interpolateKeyframes(keyframes: AnimationKeyframeInput[], timeUs: number): {
|
|
10
|
+
transform: Transform2D;
|
|
11
|
+
opacity?: number;
|
|
12
|
+
};
|
|
13
|
+
export declare function interpolateTransform(from: Transform2D, to: Transform2D, t: number): Transform2D;
|
|
14
|
+
export declare function lerp(a: number, b: number, t: number): number;
|
|
15
|
+
export declare function applyEasing(t: number, easing: string): number;
|
|
16
|
+
//# sourceMappingURL=animation-utils.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"animation-utils.d.ts","sourceRoot":"","sources":["../../src/utils/animation-utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAElD,MAAM,WAAW,sBAAsB;IACrC,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,CAAC,EAAE,WAAW,CAAC;IACxB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,wBAAgB,oBAAoB,CAClC,SAAS,EAAE,sBAAsB,EAAE,EACnC,MAAM,EAAE,MAAM,GACb;IAAE,SAAS,EAAE,WAAW,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAAE,CA8D9C;AAED,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,WAAW,EAAE,EAAE,EAAE,WAAW,EAAE,CAAC,EAAE,MAAM,GAAG,WAAW,CAU/F;AAED,wBAAgB,IAAI,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAE5D;AAED,wBAAgB,WAAW,CAAC,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAkB7D"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"image-utils.d.ts","sourceRoot":"","sources":["../../src/utils/image-utils.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,wBAAsB,yBAAyB,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAAC,WAAW,CAAC,CAYhF"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
async function createImageBitmapFromBlob(blob) {
|
|
2
|
+
if (blob.type === "image/svg+xml") {
|
|
3
|
+
return createImageBitmapFromSVG(blob);
|
|
4
|
+
}
|
|
5
|
+
return createImageBitmap(blob, {
|
|
6
|
+
premultiplyAlpha: "premultiply",
|
|
7
|
+
colorSpaceConversion: "default",
|
|
8
|
+
imageOrientation: "from-image"
|
|
9
|
+
});
|
|
10
|
+
}
|
|
11
|
+
async function createImageBitmapFromSVG(blob) {
|
|
12
|
+
return new Promise((resolve, reject) => {
|
|
13
|
+
const url = URL.createObjectURL(blob);
|
|
14
|
+
const img = new Image();
|
|
15
|
+
img.onload = () => {
|
|
16
|
+
URL.revokeObjectURL(url);
|
|
17
|
+
createImageBitmap(img, {
|
|
18
|
+
premultiplyAlpha: "premultiply",
|
|
19
|
+
colorSpaceConversion: "default"
|
|
20
|
+
}).then(resolve).catch(reject);
|
|
21
|
+
};
|
|
22
|
+
img.onerror = () => {
|
|
23
|
+
URL.revokeObjectURL(url);
|
|
24
|
+
reject(new Error("Failed to load SVG image"));
|
|
25
|
+
};
|
|
26
|
+
img.src = url;
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
export {
|
|
30
|
+
createImageBitmapFromBlob
|
|
31
|
+
};
|
|
32
|
+
//# sourceMappingURL=image-utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"image-utils.js","sources":["../../src/utils/image-utils.ts"],"sourcesContent":["/**\n * Create ImageBitmap from Blob with format-specific handling\n */\nexport async function createImageBitmapFromBlob(blob: Blob): Promise<ImageBitmap> {\n // SVG needs special handling (load via Image element first)\n if (blob.type === 'image/svg+xml') {\n return createImageBitmapFromSVG(blob);\n }\n\n // Standard raster images\n return createImageBitmap(blob, {\n premultiplyAlpha: 'premultiply',\n colorSpaceConversion: 'default',\n imageOrientation: 'from-image',\n });\n}\n\n/**\n * Create ImageBitmap from SVG blob\n * SVG requires loading through Image element first for proper rendering\n */\nasync function createImageBitmapFromSVG(blob: Blob): Promise<ImageBitmap> {\n return new Promise((resolve, reject) => {\n const url = URL.createObjectURL(blob);\n const img = new Image();\n\n img.onload = () => {\n URL.revokeObjectURL(url);\n createImageBitmap(img, {\n premultiplyAlpha: 'premultiply',\n colorSpaceConversion: 'default',\n })\n .then(resolve)\n .catch(reject);\n };\n\n img.onerror = () => {\n URL.revokeObjectURL(url);\n reject(new Error('Failed to load SVG image'));\n };\n\n img.src = url;\n });\n}\n"],"names":[],"mappings":"AAGA,eAAsB,0BAA0B,MAAkC;AAEhF,MAAI,KAAK,SAAS,iBAAiB;AACjC,WAAO,yBAAyB,IAAI;AAAA,EACtC;AAGA,SAAO,kBAAkB,MAAM;AAAA,IAC7B,kBAAkB;AAAA,IAClB,sBAAsB;AAAA,IACtB,kBAAkB;AAAA,EAAA,CACnB;AACH;AAMA,eAAe,yBAAyB,MAAkC;AACxE,SAAO,IAAI,QAAQ,CAAC,SAAS,WAAW;AACtC,UAAM,MAAM,IAAI,gBAAgB,IAAI;AACpC,UAAM,MAAM,IAAI,MAAA;AAEhB,QAAI,SAAS,MAAM;AACjB,UAAI,gBAAgB,GAAG;AACvB,wBAAkB,KAAK;AAAA,QACrB,kBAAkB;AAAA,QAClB,sBAAsB;AAAA,MAAA,CACvB,EACE,KAAK,OAAO,EACZ,MAAM,MAAM;AAAA,IACjB;AAEA,QAAI,UAAU,MAAM;AAClB,UAAI,gBAAgB,GAAG;AACvB,aAAO,IAAI,MAAM,0BAA0B,CAAC;AAAA,IAC9C;AAEA,QAAI,MAAM;AAAA,EACZ,CAAC;AACH;"}
|
|
@@ -39,7 +39,8 @@ class LayerRenderer {
|
|
|
39
39
|
this.ctx.globalCompositeOperation = layer.blendMode;
|
|
40
40
|
}
|
|
41
41
|
if (layer.transform) {
|
|
42
|
-
this.
|
|
42
|
+
const layerDimensions = this.getLayerDimensions(layer);
|
|
43
|
+
this.applyTransform(layer.transform, layerDimensions);
|
|
43
44
|
}
|
|
44
45
|
switch (layer.type) {
|
|
45
46
|
case "video":
|
|
@@ -59,9 +60,60 @@ class LayerRenderer {
|
|
|
59
60
|
this.ctx.restore();
|
|
60
61
|
}
|
|
61
62
|
}
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
63
|
+
parseDimension(value, canvasSize) {
|
|
64
|
+
if (value === void 0) return void 0;
|
|
65
|
+
if (typeof value === "number") return value;
|
|
66
|
+
const strValue = value;
|
|
67
|
+
if (strValue.includes("%")) {
|
|
68
|
+
const numValue = parseFloat(strValue);
|
|
69
|
+
return isNaN(numValue) ? void 0 : numValue / 100 * canvasSize;
|
|
70
|
+
}
|
|
71
|
+
const parsed = parseFloat(strValue);
|
|
72
|
+
return isNaN(parsed) ? void 0 : parsed;
|
|
73
|
+
}
|
|
74
|
+
getLayerDimensions(layer) {
|
|
75
|
+
if (layer.type === "image") {
|
|
76
|
+
const imageLayer = layer;
|
|
77
|
+
if (imageLayer.source) {
|
|
78
|
+
const imgWidth = imageLayer.source.width;
|
|
79
|
+
const imgHeight = imageLayer.source.height;
|
|
80
|
+
const isAttachment = !!imageLayer.attachmentId;
|
|
81
|
+
if (isAttachment) {
|
|
82
|
+
const targetWidthRaw = imageLayer.targetWidth;
|
|
83
|
+
const targetHeightRaw = imageLayer.targetHeight;
|
|
84
|
+
const targetWidth = this.parseDimension(targetWidthRaw, this.width);
|
|
85
|
+
const targetHeight = this.parseDimension(targetHeightRaw, this.height);
|
|
86
|
+
if (targetWidth && targetHeight) {
|
|
87
|
+
return { width: targetWidth, height: targetHeight };
|
|
88
|
+
} else if (targetWidth) {
|
|
89
|
+
return {
|
|
90
|
+
width: targetWidth,
|
|
91
|
+
height: imgHeight / imgWidth * targetWidth
|
|
92
|
+
};
|
|
93
|
+
} else if (targetHeight) {
|
|
94
|
+
return {
|
|
95
|
+
width: imgWidth / imgHeight * targetHeight,
|
|
96
|
+
height: targetHeight
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
return { width: imgWidth, height: imgHeight };
|
|
101
|
+
}
|
|
102
|
+
} else if (layer.type === "video") {
|
|
103
|
+
const videoLayer = layer;
|
|
104
|
+
const videoFrame = videoLayer.videoFrame;
|
|
105
|
+
return {
|
|
106
|
+
width: videoFrame.displayWidth || videoFrame.codedWidth,
|
|
107
|
+
height: videoFrame.displayHeight || videoFrame.codedHeight
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
return { width: this.width, height: this.height };
|
|
111
|
+
}
|
|
112
|
+
applyTransform(transform, layerDimensions) {
|
|
113
|
+
const anchorX = transform.anchorX ?? 0.5;
|
|
114
|
+
const anchorY = transform.anchorY ?? 0.5;
|
|
115
|
+
const centerX = layerDimensions.width * anchorX;
|
|
116
|
+
const centerY = layerDimensions.height * anchorY;
|
|
65
117
|
this.ctx.translate(transform.x + centerX, transform.y + centerY);
|
|
66
118
|
if (transform.rotation) {
|
|
67
119
|
this.ctx.rotate(transform.rotation);
|
|
@@ -114,6 +166,33 @@ class LayerRenderer {
|
|
|
114
166
|
if (!source) {
|
|
115
167
|
return;
|
|
116
168
|
}
|
|
169
|
+
const isAttachment = !!layer.attachmentId;
|
|
170
|
+
const imgWidth = source.width;
|
|
171
|
+
const imgHeight = source.height;
|
|
172
|
+
let renderWidth;
|
|
173
|
+
let renderHeight;
|
|
174
|
+
if (isAttachment) {
|
|
175
|
+
const targetWidthRaw = layer.targetWidth;
|
|
176
|
+
const targetHeightRaw = layer.targetHeight;
|
|
177
|
+
const targetWidth = this.parseDimension(targetWidthRaw, this.width);
|
|
178
|
+
const targetHeight = this.parseDimension(targetHeightRaw, this.height);
|
|
179
|
+
if (targetWidth && targetHeight) {
|
|
180
|
+
renderWidth = targetWidth;
|
|
181
|
+
renderHeight = targetHeight;
|
|
182
|
+
} else if (targetWidth) {
|
|
183
|
+
renderWidth = targetWidth;
|
|
184
|
+
renderHeight = imgHeight / imgWidth * targetWidth;
|
|
185
|
+
} else if (targetHeight) {
|
|
186
|
+
renderHeight = targetHeight;
|
|
187
|
+
renderWidth = imgWidth / imgHeight * targetHeight;
|
|
188
|
+
} else {
|
|
189
|
+
renderWidth = imgWidth;
|
|
190
|
+
renderHeight = imgHeight;
|
|
191
|
+
}
|
|
192
|
+
} else {
|
|
193
|
+
renderWidth = this.width;
|
|
194
|
+
renderHeight = this.height;
|
|
195
|
+
}
|
|
117
196
|
if (crop) {
|
|
118
197
|
this.ctx.drawImage(
|
|
119
198
|
source,
|
|
@@ -123,11 +202,11 @@ class LayerRenderer {
|
|
|
123
202
|
crop.height,
|
|
124
203
|
0,
|
|
125
204
|
0,
|
|
126
|
-
|
|
127
|
-
|
|
205
|
+
renderWidth,
|
|
206
|
+
renderHeight
|
|
128
207
|
);
|
|
129
208
|
} else {
|
|
130
|
-
this.ctx.drawImage(source, 0, 0,
|
|
209
|
+
this.ctx.drawImage(source, 0, 0, renderWidth, renderHeight);
|
|
131
210
|
}
|
|
132
211
|
}
|
|
133
212
|
}
|
|
@@ -810,9 +889,87 @@ class VideoComposer {
|
|
|
810
889
|
this.filterProcessor.clearCache();
|
|
811
890
|
}
|
|
812
891
|
}
|
|
892
|
+
function interpolateKeyframes(keyframes, timeUs) {
|
|
893
|
+
const defaultTransform = {
|
|
894
|
+
x: 0,
|
|
895
|
+
y: 0,
|
|
896
|
+
scaleX: 1,
|
|
897
|
+
scaleY: 1,
|
|
898
|
+
rotation: 0,
|
|
899
|
+
anchorX: 0.5,
|
|
900
|
+
anchorY: 0.5
|
|
901
|
+
};
|
|
902
|
+
if (keyframes.length === 0) {
|
|
903
|
+
return { transform: defaultTransform };
|
|
904
|
+
}
|
|
905
|
+
const firstFrame = keyframes[0];
|
|
906
|
+
const lastFrame = keyframes[keyframes.length - 1];
|
|
907
|
+
if (timeUs <= firstFrame.time) {
|
|
908
|
+
return {
|
|
909
|
+
transform: { ...defaultTransform, ...firstFrame.transform },
|
|
910
|
+
opacity: firstFrame.opacity
|
|
911
|
+
};
|
|
912
|
+
}
|
|
913
|
+
if (timeUs >= lastFrame.time) {
|
|
914
|
+
return {
|
|
915
|
+
transform: { ...defaultTransform, ...lastFrame.transform },
|
|
916
|
+
opacity: lastFrame.opacity
|
|
917
|
+
};
|
|
918
|
+
}
|
|
919
|
+
let prevFrame = firstFrame;
|
|
920
|
+
let nextFrame = lastFrame;
|
|
921
|
+
for (let i = 0; i < keyframes.length - 1; i++) {
|
|
922
|
+
const currentFrame = keyframes[i];
|
|
923
|
+
const followingFrame = keyframes[i + 1];
|
|
924
|
+
if (timeUs >= currentFrame.time && timeUs < followingFrame.time) {
|
|
925
|
+
prevFrame = currentFrame;
|
|
926
|
+
nextFrame = followingFrame;
|
|
927
|
+
break;
|
|
928
|
+
}
|
|
929
|
+
}
|
|
930
|
+
const duration = nextFrame.time - prevFrame.time;
|
|
931
|
+
const elapsed = timeUs - prevFrame.time;
|
|
932
|
+
const progress = elapsed / duration;
|
|
933
|
+
const easedProgress = applyEasing(progress, prevFrame.easing ?? "linear");
|
|
934
|
+
const prevTransform = prevFrame.transform ?? { x: 0, y: 0 };
|
|
935
|
+
const nextTransform = nextFrame.transform ?? { x: 0, y: 0 };
|
|
936
|
+
const transform = interpolateTransform(prevTransform, nextTransform, easedProgress);
|
|
937
|
+
const opacity = prevFrame.opacity !== void 0 && nextFrame.opacity !== void 0 ? lerp(prevFrame.opacity, nextFrame.opacity, easedProgress) : void 0;
|
|
938
|
+
return { transform, opacity };
|
|
939
|
+
}
|
|
940
|
+
function interpolateTransform(from, to, t) {
|
|
941
|
+
return {
|
|
942
|
+
x: lerp(from.x ?? 0, to.x ?? 0, t),
|
|
943
|
+
y: lerp(from.y ?? 0, to.y ?? 0, t),
|
|
944
|
+
scaleX: lerp(from.scaleX ?? 1, to.scaleX ?? 1, t),
|
|
945
|
+
scaleY: lerp(from.scaleY ?? 1, to.scaleY ?? 1, t),
|
|
946
|
+
rotation: lerp(from.rotation ?? 0, to.rotation ?? 0, t),
|
|
947
|
+
anchorX: lerp(from.anchorX ?? 0.5, to.anchorX ?? 0.5, t),
|
|
948
|
+
anchorY: lerp(from.anchorY ?? 0.5, to.anchorY ?? 0.5, t)
|
|
949
|
+
};
|
|
950
|
+
}
|
|
951
|
+
function lerp(a, b, t) {
|
|
952
|
+
return a + (b - a) * t;
|
|
953
|
+
}
|
|
954
|
+
function applyEasing(t, easing) {
|
|
955
|
+
switch (easing) {
|
|
956
|
+
case "linear":
|
|
957
|
+
return t;
|
|
958
|
+
case "ease-in":
|
|
959
|
+
return t * t * t;
|
|
960
|
+
case "ease-out": {
|
|
961
|
+
const oneMinusT = 1 - t;
|
|
962
|
+
return 1 - oneMinusT * oneMinusT * oneMinusT;
|
|
963
|
+
}
|
|
964
|
+
case "ease-in-out":
|
|
965
|
+
return t < 0.5 ? 4 * t * t * t : 1 - Math.pow(-2 * t + 2, 3) / 2;
|
|
966
|
+
default:
|
|
967
|
+
return t;
|
|
968
|
+
}
|
|
969
|
+
}
|
|
813
970
|
function resolveActiveLayers(layers, timestamp) {
|
|
814
971
|
return layers.filter((layer) => {
|
|
815
|
-
if (layer.
|
|
972
|
+
if (!layer.payload.attachmentId) {
|
|
816
973
|
return true;
|
|
817
974
|
}
|
|
818
975
|
if (layer.status !== "ready") {
|
|
@@ -823,7 +980,7 @@ function resolveActiveLayers(layers, timestamp) {
|
|
|
823
980
|
);
|
|
824
981
|
});
|
|
825
982
|
}
|
|
826
|
-
function materializeLayer(layer, frame) {
|
|
983
|
+
function materializeLayer(layer, frame, imageMap, globalTimeUs) {
|
|
827
984
|
const baseLayer = {
|
|
828
985
|
id: layer.layerId,
|
|
829
986
|
type: layer.type,
|
|
@@ -853,22 +1010,74 @@ function materializeLayer(layer, frame) {
|
|
|
853
1010
|
lineHeight: payload.lineHeight,
|
|
854
1011
|
textAlign: payload.align,
|
|
855
1012
|
verticalAlign: "bottom"
|
|
856
|
-
// Subtitles positioned at bottom
|
|
857
1013
|
};
|
|
858
1014
|
}
|
|
859
1015
|
if (layer.type === "image") {
|
|
860
1016
|
const payload = layer.payload;
|
|
861
|
-
const
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
1017
|
+
const resourceId = payload.resourceId;
|
|
1018
|
+
const source = imageMap.get(resourceId) ?? null;
|
|
1019
|
+
const imageLayer = {
|
|
1020
|
+
...baseLayer,
|
|
1021
|
+
type: "image",
|
|
1022
|
+
source,
|
|
1023
|
+
attachmentId: payload.attachmentId
|
|
1024
|
+
};
|
|
1025
|
+
if (payload.targetWidth !== void 0) {
|
|
1026
|
+
imageLayer.targetWidth = payload.targetWidth;
|
|
1027
|
+
}
|
|
1028
|
+
if (payload.targetHeight !== void 0) {
|
|
1029
|
+
imageLayer.targetHeight = payload.targetHeight;
|
|
1030
|
+
}
|
|
1031
|
+
if (payload.animation && globalTimeUs !== void 0) {
|
|
1032
|
+
const animState = computeAnimationState(payload.animation, globalTimeUs);
|
|
1033
|
+
if (!animState.visible) {
|
|
1034
|
+
return null;
|
|
1035
|
+
}
|
|
1036
|
+
imageLayer.transform = {
|
|
1037
|
+
x: animState.transform.x ?? 0,
|
|
1038
|
+
y: animState.transform.y ?? 0,
|
|
1039
|
+
scaleX: animState.transform.scaleX ?? 1,
|
|
1040
|
+
scaleY: animState.transform.scaleY ?? 1,
|
|
1041
|
+
rotation: animState.transform.rotation ?? 0,
|
|
1042
|
+
anchorX: animState.transform.anchorX ?? 0.5,
|
|
1043
|
+
anchorY: animState.transform.anchorY ?? 0.5
|
|
867
1044
|
};
|
|
1045
|
+
if (animState.opacity !== void 0) {
|
|
1046
|
+
imageLayer.opacity = animState.opacity;
|
|
1047
|
+
}
|
|
868
1048
|
}
|
|
1049
|
+
return imageLayer;
|
|
869
1050
|
}
|
|
870
1051
|
return baseLayer;
|
|
871
1052
|
}
|
|
1053
|
+
function computeAnimationState(animation, globalTimeUs) {
|
|
1054
|
+
const { position, keyframes, overlayClipStartUs } = animation;
|
|
1055
|
+
const relativeTimeUs = globalTimeUs - overlayClipStartUs;
|
|
1056
|
+
if (relativeTimeUs < 0 || relativeTimeUs > keyframes[keyframes.length - 1].time) {
|
|
1057
|
+
return {
|
|
1058
|
+
transform: { x: 0, y: 0, scaleX: 1, scaleY: 1, rotation: 0, anchorX: 0.5, anchorY: 0.5 },
|
|
1059
|
+
opacity: 0,
|
|
1060
|
+
visible: false
|
|
1061
|
+
};
|
|
1062
|
+
}
|
|
1063
|
+
const animState = interpolateKeyframes(keyframes, relativeTimeUs);
|
|
1064
|
+
const rotationDeg = animState.transform?.rotation ?? 0;
|
|
1065
|
+
const rotationRad = rotationDeg * Math.PI / 180;
|
|
1066
|
+
const finalTransform = {
|
|
1067
|
+
x: position.x + (animState.transform?.x ?? 0),
|
|
1068
|
+
y: position.y + (animState.transform?.y ?? 0),
|
|
1069
|
+
scaleX: animState.transform?.scaleX ?? 1,
|
|
1070
|
+
scaleY: animState.transform?.scaleY ?? 1,
|
|
1071
|
+
rotation: rotationRad,
|
|
1072
|
+
anchorX: animState.transform?.anchorX ?? 0.5,
|
|
1073
|
+
anchorY: animState.transform?.anchorY ?? 0.5
|
|
1074
|
+
};
|
|
1075
|
+
return {
|
|
1076
|
+
transform: finalTransform,
|
|
1077
|
+
opacity: animState.opacity,
|
|
1078
|
+
visible: true
|
|
1079
|
+
};
|
|
1080
|
+
}
|
|
872
1081
|
class VideoComposeWorker {
|
|
873
1082
|
channel;
|
|
874
1083
|
composer = null;
|
|
@@ -878,7 +1087,7 @@ class VideoComposeWorker {
|
|
|
878
1087
|
upstreamPort = null;
|
|
879
1088
|
instructions = null;
|
|
880
1089
|
streamState = null;
|
|
881
|
-
|
|
1090
|
+
imageMap = /* @__PURE__ */ new Map();
|
|
882
1091
|
constructor() {
|
|
883
1092
|
this.channel = new WorkerChannel(self, {
|
|
884
1093
|
name: "VideoComposeWorker",
|
|
@@ -923,7 +1132,6 @@ class VideoComposeWorker {
|
|
|
923
1132
|
*/
|
|
924
1133
|
async handleConfigure(payload) {
|
|
925
1134
|
const { config, initial } = payload;
|
|
926
|
-
console.log("[VideoComposeWorker] handleConfigure", config, initial);
|
|
927
1135
|
const hasValidDimensions = config.width > 0 && config.height > 0;
|
|
928
1136
|
const hasValidFps = config.fps > 0;
|
|
929
1137
|
if (!hasValidDimensions || !hasValidFps) {
|
|
@@ -1043,8 +1251,8 @@ class VideoComposeWorker {
|
|
|
1043
1251
|
this.upstreamPort?.close();
|
|
1044
1252
|
this.downstreamPort = null;
|
|
1045
1253
|
this.upstreamPort = null;
|
|
1046
|
-
this.
|
|
1047
|
-
this.
|
|
1254
|
+
this.imageMap.forEach((bitmap) => bitmap.close());
|
|
1255
|
+
this.imageMap.clear();
|
|
1048
1256
|
this.instructions = null;
|
|
1049
1257
|
this.streamState = null;
|
|
1050
1258
|
this.channel.state = WorkerState.Disposed;
|
|
@@ -1067,16 +1275,21 @@ class VideoComposeWorker {
|
|
|
1067
1275
|
* only accepts ImageBitmap/OffscreenCanvas, not HTMLImageElement or Blob
|
|
1068
1276
|
*/
|
|
1069
1277
|
async handleReceiveImage(payload) {
|
|
1070
|
-
const { sessionId, imageBitmap } = payload;
|
|
1278
|
+
const { resourceId, sessionId, imageBitmap } = payload;
|
|
1071
1279
|
if (!this.sessionId) {
|
|
1072
1280
|
this.sessionId = sessionId;
|
|
1073
1281
|
}
|
|
1074
|
-
|
|
1075
|
-
|
|
1282
|
+
const existing = this.imageMap.get(resourceId);
|
|
1283
|
+
if (existing) {
|
|
1284
|
+
existing.close();
|
|
1076
1285
|
}
|
|
1077
|
-
this.
|
|
1286
|
+
this.imageMap.set(resourceId, imageBitmap);
|
|
1078
1287
|
if (this.instructions) {
|
|
1079
|
-
|
|
1288
|
+
const mainLayer = this.instructions.layers.find((l) => !l.payload.attachmentId);
|
|
1289
|
+
const mainResourceId = mainLayer?.payload.resourceId;
|
|
1290
|
+
if (resourceId === mainResourceId) {
|
|
1291
|
+
await this.startImageFrameStream();
|
|
1292
|
+
}
|
|
1080
1293
|
}
|
|
1081
1294
|
return { success: true };
|
|
1082
1295
|
}
|
|
@@ -1087,8 +1300,8 @@ class VideoComposeWorker {
|
|
|
1087
1300
|
this.upstreamPort?.close();
|
|
1088
1301
|
this.downstreamPort = null;
|
|
1089
1302
|
this.upstreamPort = null;
|
|
1090
|
-
this.
|
|
1091
|
-
this.
|
|
1303
|
+
this.imageMap.forEach((bitmap) => bitmap.close());
|
|
1304
|
+
this.imageMap.clear();
|
|
1092
1305
|
return { success: true };
|
|
1093
1306
|
}
|
|
1094
1307
|
async startImageFrameStream() {
|
|
@@ -1099,6 +1312,14 @@ class VideoComposeWorker {
|
|
|
1099
1312
|
if (!timeline) {
|
|
1100
1313
|
return;
|
|
1101
1314
|
}
|
|
1315
|
+
const mainLayer = this.instructions.layers.find((l) => !l.payload.attachmentId);
|
|
1316
|
+
if (!mainLayer) return;
|
|
1317
|
+
const mainResourceId = mainLayer.payload.resourceId;
|
|
1318
|
+
const imageBitmap = this.imageMap.get(mainResourceId);
|
|
1319
|
+
if (!imageBitmap) {
|
|
1320
|
+
console.warn("[VideoComposeWorker] Main track ImageBitmap not found:", mainResourceId);
|
|
1321
|
+
return;
|
|
1322
|
+
}
|
|
1102
1323
|
const { composeStream, cacheStream, encodeStream } = this.composer.createStreams();
|
|
1103
1324
|
const { clipDurationUs, compositionFps } = timeline;
|
|
1104
1325
|
let currentTimeUs = 0;
|
|
@@ -1108,7 +1329,7 @@ class VideoComposeWorker {
|
|
|
1108
1329
|
controller.close();
|
|
1109
1330
|
return;
|
|
1110
1331
|
}
|
|
1111
|
-
const videoFrame = new VideoFrame(
|
|
1332
|
+
const videoFrame = new VideoFrame(imageBitmap, {
|
|
1112
1333
|
timestamp: currentTimeUs,
|
|
1113
1334
|
duration: frameDurationFromFps(compositionFps)
|
|
1114
1335
|
});
|
|
@@ -1149,9 +1370,15 @@ class VideoComposeWorker {
|
|
|
1149
1370
|
if (!activeLayers.length) {
|
|
1150
1371
|
return null;
|
|
1151
1372
|
}
|
|
1152
|
-
const
|
|
1373
|
+
const clipStartUs = instruction.baseConfig.timeline?.clipStartUs ?? 0;
|
|
1374
|
+
const globalTimeUs = clipStartUs + clipRelativeTime;
|
|
1375
|
+
const layers = activeLayers.map((layer) => materializeLayer(layer, frame, this.imageMap, globalTimeUs)).filter((layer) => layer !== null);
|
|
1376
|
+
if (!layers.length) {
|
|
1377
|
+
return null;
|
|
1378
|
+
}
|
|
1153
1379
|
return {
|
|
1154
1380
|
timeUs: clipRelativeTime,
|
|
1381
|
+
globalTimeUs,
|
|
1155
1382
|
layers,
|
|
1156
1383
|
transition: VideoComposeWorker.buildTransition(
|
|
1157
1384
|
instruction.transitions,
|