@meframe/core 0.4.3 → 0.4.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.
- package/dist/model/types.d.ts +6 -0
- package/dist/model/types.d.ts.map +1 -1
- package/dist/model/types.js +14 -1
- package/dist/model/types.js.map +1 -1
- package/dist/orchestrator/AudioPreviewSession.d.ts.map +1 -1
- package/dist/orchestrator/AudioPreviewSession.js +3 -3
- package/dist/orchestrator/AudioPreviewSession.js.map +1 -1
- package/dist/orchestrator/AudioWindowPreparer.d.ts.map +1 -1
- package/dist/orchestrator/AudioWindowPreparer.js +6 -3
- package/dist/orchestrator/AudioWindowPreparer.js.map +1 -1
- package/dist/orchestrator/CompositionPlanner.d.ts.map +1 -1
- package/dist/orchestrator/CompositionPlanner.js +4 -2
- package/dist/orchestrator/CompositionPlanner.js.map +1 -1
- package/dist/orchestrator/ExportScheduler.d.ts.map +1 -1
- package/dist/orchestrator/ExportScheduler.js +4 -2
- package/dist/orchestrator/ExportScheduler.js.map +1 -1
- package/dist/orchestrator/Orchestrator.d.ts.map +1 -1
- package/dist/orchestrator/Orchestrator.js +18 -11
- package/dist/orchestrator/Orchestrator.js.map +1 -1
- package/dist/orchestrator/VideoWindowDecodeSession.d.ts +3 -0
- package/dist/orchestrator/VideoWindowDecodeSession.d.ts.map +1 -1
- package/dist/orchestrator/VideoWindowDecodeSession.js +41 -1
- package/dist/orchestrator/VideoWindowDecodeSession.js.map +1 -1
- package/dist/stages/compose/FrameRateConverter.d.ts +2 -1
- package/dist/stages/compose/FrameRateConverter.d.ts.map +1 -1
- package/dist/stages/compose/OfflineAudioMixer.d.ts.map +1 -1
- package/dist/stages/compose/OfflineAudioMixer.js +9 -3
- package/dist/stages/compose/OfflineAudioMixer.js.map +1 -1
- package/dist/stages/load/ResourceLoader.d.ts.map +1 -1
- package/dist/stages/load/ResourceLoader.js +58 -2
- package/dist/stages/load/ResourceLoader.js.map +1 -1
- package/dist/utils/loop-utils.d.ts +2 -0
- package/dist/utils/loop-utils.d.ts.map +1 -1
- package/dist/utils/loop-utils.js +5 -2
- package/dist/utils/loop-utils.js.map +1 -1
- package/dist/workers/stages/export/{export.worker.DCStS1mL.js → export.worker.Cw9iPvkh.js} +27 -17
- package/dist/workers/stages/export/{export.worker.DCStS1mL.js.map → export.worker.Cw9iPvkh.js.map} +1 -1
- package/dist/workers/worker-manifest.json +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"loop-utils.d.ts","sourceRoot":"","sources":["../../src/utils/loop-utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAC;AAE7C,MAAM,WAAW,WAAW;IAC1B,mBAAmB,EAAE,MAAM,CAAC;IAC5B,UAAU,EAAE,MAAM,CAAC;IACnB,eAAe,EAAE,MAAM,CAAC;IACxB,aAAa,EAAE,MAAM,CAAC;CACvB;AAED,wBAAgB,2BAA2B,CAAC,MAAM,EAAE;IAClD,mBAAmB,EAAE,MAAM,CAAC;IAC5B,iBAAiB,EAAE,MAAM,CAAC;IAC1B,WAAW,EAAE,MAAM,CAAC;IACpB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,IAAI,EAAE,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"loop-utils.d.ts","sourceRoot":"","sources":["../../src/utils/loop-utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAC;AAE7C,MAAM,WAAW,WAAW;IAC1B,mBAAmB,EAAE,MAAM,CAAC;IAC5B,UAAU,EAAE,MAAM,CAAC;IACnB,eAAe,EAAE,MAAM,CAAC;IACxB,aAAa,EAAE,MAAM,CAAC;CACvB;AAED,wBAAgB,2BAA2B,CAAC,MAAM,EAAE;IAClD,mBAAmB,EAAE,MAAM,CAAC;IAC5B,iBAAiB,EAAE,MAAM,CAAC;IAC1B,WAAW,EAAE,MAAM,CAAC;IACpB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,IAAI,EAAE,OAAO,CAAC;IACd,wEAAwE;IACxE,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB,GAAG,WAAW,EAAE,CAkDhB"}
|
package/dist/utils/loop-utils.js
CHANGED
|
@@ -6,12 +6,15 @@ function buildLoopedResourceSegments(params) {
|
|
|
6
6
|
return [];
|
|
7
7
|
}
|
|
8
8
|
if (!params.loop) {
|
|
9
|
+
const rawR = params.playbackRate ?? 1;
|
|
10
|
+
const rate = typeof rawR === "number" && Number.isFinite(rawR) && rawR > 0 ? rawR : 1;
|
|
11
|
+
const trim = params.trimStartUs ?? 0;
|
|
9
12
|
return [
|
|
10
13
|
{
|
|
11
14
|
clipRelativeStartUs: rangeStartUs,
|
|
12
15
|
durationUs: requestedDurationUs,
|
|
13
|
-
resourceStartUs:
|
|
14
|
-
resourceEndUs:
|
|
16
|
+
resourceStartUs: trim + rangeStartUs * rate,
|
|
17
|
+
resourceEndUs: trim + rangeEndUs * rate
|
|
15
18
|
}
|
|
16
19
|
];
|
|
17
20
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"loop-utils.js","sources":["../../src/utils/loop-utils.ts"],"sourcesContent":["import type { TimeUs } from '../model/types';\n\nexport interface LoopSegment {\n clipRelativeStartUs: TimeUs;\n durationUs: TimeUs;\n resourceStartUs: TimeUs;\n resourceEndUs: TimeUs;\n}\n\nexport function buildLoopedResourceSegments(params: {\n clipRelativeStartUs: TimeUs;\n clipRelativeEndUs: TimeUs;\n trimStartUs: TimeUs;\n resourceDurationUs: TimeUs;\n loop: boolean;\n}): LoopSegment[] {\n const rangeStartUs = Math.max(0, params.clipRelativeStartUs);\n const rangeEndUs = Math.max(rangeStartUs, params.clipRelativeEndUs);\n\n const requestedDurationUs = rangeEndUs - rangeStartUs;\n if (requestedDurationUs <= 0) {\n return [];\n }\n\n if (!params.loop) {\n return [\n {\n clipRelativeStartUs: rangeStartUs,\n durationUs: requestedDurationUs,\n resourceStartUs:
|
|
1
|
+
{"version":3,"file":"loop-utils.js","sources":["../../src/utils/loop-utils.ts"],"sourcesContent":["import type { TimeUs } from '../model/types';\n\nexport interface LoopSegment {\n clipRelativeStartUs: TimeUs;\n durationUs: TimeUs;\n resourceStartUs: TimeUs;\n resourceEndUs: TimeUs;\n}\n\nexport function buildLoopedResourceSegments(params: {\n clipRelativeStartUs: TimeUs;\n clipRelativeEndUs: TimeUs;\n trimStartUs: TimeUs;\n resourceDurationUs: TimeUs;\n loop: boolean;\n /** Applied only when loop is false (e.g. video clip timeline speed). */\n playbackRate?: number;\n}): LoopSegment[] {\n const rangeStartUs = Math.max(0, params.clipRelativeStartUs);\n const rangeEndUs = Math.max(rangeStartUs, params.clipRelativeEndUs);\n\n const requestedDurationUs = rangeEndUs - rangeStartUs;\n if (requestedDurationUs <= 0) {\n return [];\n }\n\n if (!params.loop) {\n const rawR = params.playbackRate ?? 1;\n const rate = typeof rawR === 'number' && Number.isFinite(rawR) && rawR > 0 ? rawR : 1;\n const trim = params.trimStartUs ?? 0;\n return [\n {\n clipRelativeStartUs: rangeStartUs,\n durationUs: requestedDurationUs,\n resourceStartUs: trim + rangeStartUs * rate,\n resourceEndUs: trim + rangeEndUs * rate,\n },\n ];\n }\n\n const trimStartUs = params.trimStartUs ?? 0;\n const periodUs = params.resourceDurationUs - trimStartUs;\n if (periodUs <= 0) {\n return [];\n }\n\n const segments: LoopSegment[] = [];\n let tUs = rangeStartUs;\n\n while (tUs < rangeEndUs) {\n const offsetInPeriodUs = tUs % periodUs;\n const maxLenUs = periodUs - offsetInPeriodUs;\n const lenUs = Math.min(rangeEndUs - tUs, maxLenUs);\n if (lenUs <= 0) break;\n\n const resourceStartUs = trimStartUs + offsetInPeriodUs;\n segments.push({\n clipRelativeStartUs: tUs,\n durationUs: lenUs,\n resourceStartUs,\n resourceEndUs: resourceStartUs + lenUs,\n });\n\n tUs += lenUs;\n }\n\n return segments;\n}\n"],"names":[],"mappings":"AASO,SAAS,4BAA4B,QAQ1B;AAChB,QAAM,eAAe,KAAK,IAAI,GAAG,OAAO,mBAAmB;AAC3D,QAAM,aAAa,KAAK,IAAI,cAAc,OAAO,iBAAiB;AAElE,QAAM,sBAAsB,aAAa;AACzC,MAAI,uBAAuB,GAAG;AAC5B,WAAO,CAAA;AAAA,EACT;AAEA,MAAI,CAAC,OAAO,MAAM;AAChB,UAAM,OAAO,OAAO,gBAAgB;AACpC,UAAM,OAAO,OAAO,SAAS,YAAY,OAAO,SAAS,IAAI,KAAK,OAAO,IAAI,OAAO;AACpF,UAAM,OAAO,OAAO,eAAe;AACnC,WAAO;AAAA,MACL;AAAA,QACE,qBAAqB;AAAA,QACrB,YAAY;AAAA,QACZ,iBAAiB,OAAO,eAAe;AAAA,QACvC,eAAe,OAAO,aAAa;AAAA,MAAA;AAAA,IACrC;AAAA,EAEJ;AAEA,QAAM,cAAc,OAAO,eAAe;AAC1C,QAAM,WAAW,OAAO,qBAAqB;AAC7C,MAAI,YAAY,GAAG;AACjB,WAAO,CAAA;AAAA,EACT;AAEA,QAAM,WAA0B,CAAA;AAChC,MAAI,MAAM;AAEV,SAAO,MAAM,YAAY;AACvB,UAAM,mBAAmB,MAAM;AAC/B,UAAM,WAAW,WAAW;AAC5B,UAAM,QAAQ,KAAK,IAAI,aAAa,KAAK,QAAQ;AACjD,QAAI,SAAS,EAAG;AAEhB,UAAM,kBAAkB,cAAc;AACtC,aAAS,KAAK;AAAA,MACZ,qBAAqB;AAAA,MACrB,YAAY;AAAA,MACZ;AAAA,MACA,eAAe,kBAAkB;AAAA,IAAA,CAClC;AAED,WAAO;AAAA,EACT;AAEA,SAAO;AACT;"}
|
|
@@ -2633,13 +2633,14 @@ class FrameRateConverter {
|
|
|
2633
2633
|
clipDurationUs;
|
|
2634
2634
|
frameDurationUs;
|
|
2635
2635
|
trimStartUs;
|
|
2636
|
+
playbackRate;
|
|
2636
2637
|
totalFrameCount;
|
|
2637
2638
|
// State for frame processing
|
|
2638
2639
|
targetFrameIndex = 0;
|
|
2639
2640
|
targetFrameTimeUs = 0;
|
|
2640
2641
|
sourceFrameBuffer = [];
|
|
2641
2642
|
maxSourceTimestampUs = null;
|
|
2642
|
-
constructor(targetFps, clipDurationUs, trimStartUs = 0) {
|
|
2643
|
+
constructor(targetFps, clipDurationUs, trimStartUs = 0, playbackRate = 1) {
|
|
2643
2644
|
if (targetFps <= 0) {
|
|
2644
2645
|
throw new Error(`Invalid target fps: ${targetFps}`);
|
|
2645
2646
|
}
|
|
@@ -2649,6 +2650,7 @@ class FrameRateConverter {
|
|
|
2649
2650
|
this.clipDurationUs = clipDurationUs;
|
|
2650
2651
|
this.frameDurationUs = Math.round(1e6 / targetFps);
|
|
2651
2652
|
this.trimStartUs = trimStartUs;
|
|
2653
|
+
this.playbackRate = typeof playbackRate === "number" && Number.isFinite(playbackRate) && playbackRate > 0 ? playbackRate : 1;
|
|
2652
2654
|
this.totalFrameCount = Number.isFinite(clipDurationUs) ? Math.max(1, Math.round(clipDurationUs / this.frameDurationUs)) : null;
|
|
2653
2655
|
}
|
|
2654
2656
|
/**
|
|
@@ -2699,10 +2701,11 @@ class FrameRateConverter {
|
|
|
2699
2701
|
const bufferedTs = frameToBuffer.timestamp ?? 0;
|
|
2700
2702
|
this.maxSourceTimestampUs = this.maxSourceTimestampUs === null ? bufferedTs : Math.max(this.maxSourceTimestampUs, bufferedTs);
|
|
2701
2703
|
while (this.shouldContinueOutput()) {
|
|
2702
|
-
|
|
2704
|
+
const targetSourceUs = this.targetFrameTimeUs * this.playbackRate;
|
|
2705
|
+
if (this.maxSourceTimestampUs !== null && targetSourceUs > this.maxSourceTimestampUs) {
|
|
2703
2706
|
break;
|
|
2704
2707
|
}
|
|
2705
|
-
const closestFrame = this.findClosestFrame(
|
|
2708
|
+
const closestFrame = this.findClosestFrame(targetSourceUs);
|
|
2706
2709
|
if (!closestFrame) {
|
|
2707
2710
|
break;
|
|
2708
2711
|
}
|
|
@@ -2731,10 +2734,11 @@ class FrameRateConverter {
|
|
|
2731
2734
|
*/
|
|
2732
2735
|
flushRemainingFrames(controller) {
|
|
2733
2736
|
while (this.sourceFrameBuffer.length > 0 && this.shouldContinueOutput()) {
|
|
2734
|
-
|
|
2737
|
+
const targetSourceUs = this.targetFrameTimeUs * this.playbackRate;
|
|
2738
|
+
if (this.maxSourceTimestampUs !== null && targetSourceUs > this.maxSourceTimestampUs) {
|
|
2735
2739
|
break;
|
|
2736
2740
|
}
|
|
2737
|
-
const closestFrame = this.findClosestFrame(
|
|
2741
|
+
const closestFrame = this.findClosestFrame(targetSourceUs);
|
|
2738
2742
|
if (!closestFrame) break;
|
|
2739
2743
|
if (!this.outputTargetFrame(closestFrame, controller)) break;
|
|
2740
2744
|
}
|
|
@@ -2830,7 +2834,8 @@ class FrameRateConverter {
|
|
|
2830
2834
|
shouldWaitForNextFrame(closestFrame) {
|
|
2831
2835
|
if (this.sourceFrameBuffer.length <= 1) {
|
|
2832
2836
|
const frameTimestamp = closestFrame.timestamp ?? 0;
|
|
2833
|
-
|
|
2837
|
+
const targetSourceUs = this.targetFrameTimeUs * this.playbackRate;
|
|
2838
|
+
if (frameTimestamp < targetSourceUs) {
|
|
2834
2839
|
return true;
|
|
2835
2840
|
}
|
|
2836
2841
|
}
|
|
@@ -2840,16 +2845,18 @@ class FrameRateConverter {
|
|
|
2840
2845
|
* Clean up source frames that are no longer needed
|
|
2841
2846
|
* Keep frames that might be needed for future target frames
|
|
2842
2847
|
*/
|
|
2843
|
-
cleanupOldFrames(
|
|
2844
|
-
const
|
|
2845
|
-
const
|
|
2848
|
+
cleanupOldFrames(currentTimelineTargetUs) {
|
|
2849
|
+
const nextTimelineUs = currentTimelineTargetUs + this.frameDurationUs;
|
|
2850
|
+
const prevTimelineUs = currentTimelineTargetUs - this.frameDurationUs;
|
|
2851
|
+
const nextSourceUs = nextTimelineUs * this.playbackRate;
|
|
2852
|
+
const prevSourceUs = prevTimelineUs * this.playbackRate;
|
|
2846
2853
|
let removeCount = 0;
|
|
2847
2854
|
for (let i = 0; i < this.sourceFrameBuffer.length; i++) {
|
|
2848
2855
|
const frame = this.sourceFrameBuffer[i];
|
|
2849
2856
|
if (!frame) continue;
|
|
2850
2857
|
const frameTimestamp = frame.timestamp ?? 0;
|
|
2851
|
-
const isNeededForNext = Math.abs(frameTimestamp -
|
|
2852
|
-
if (frameTimestamp <
|
|
2858
|
+
const isNeededForNext = Math.abs(frameTimestamp - nextSourceUs) < Math.abs(frameTimestamp - prevSourceUs);
|
|
2859
|
+
if (frameTimestamp < prevSourceUs && !isNeededForNext) {
|
|
2853
2860
|
try {
|
|
2854
2861
|
frame.close();
|
|
2855
2862
|
} catch {
|
|
@@ -3062,19 +3069,22 @@ class ExportWorker {
|
|
|
3062
3069
|
(l) => l.type === "video" && !l.payload.attachmentId
|
|
3063
3070
|
);
|
|
3064
3071
|
const clipTrimStartUs = mainLayer?.type === "video" ? mainLayer.payload.trimStartUs ?? 0 : 0;
|
|
3072
|
+
const rawRate = mainLayer?.type === "video" ? mainLayer.payload.playbackRate ?? 1 : 1;
|
|
3073
|
+
const playbackRate = typeof rawRate === "number" && Number.isFinite(rawRate) && rawRate > 0 ? rawRate : 1;
|
|
3065
3074
|
const timeline = this.instructions.baseConfig.timeline;
|
|
3066
3075
|
const fps = timeline?.compositionFps ?? 30;
|
|
3067
3076
|
const windowStartUs = metadata?.windowStartUs ?? clipTrimStartUs;
|
|
3068
|
-
const
|
|
3069
|
-
const
|
|
3070
|
-
const
|
|
3071
|
-
const
|
|
3077
|
+
const windowEndResourceUs = metadata?.windowEndUs ?? clipTrimStartUs + (timeline?.clipDurationUs ?? Infinity) * playbackRate;
|
|
3078
|
+
const resourceWindowUs = windowEndResourceUs - windowStartUs;
|
|
3079
|
+
const timelineWindowUs = resourceWindowUs / playbackRate;
|
|
3080
|
+
const windowToClipOffsetUs = (windowStartUs - clipTrimStartUs) / playbackRate;
|
|
3081
|
+
const fpsConverter = new FrameRateConverter(fps, timelineWindowUs, windowStartUs, playbackRate);
|
|
3072
3082
|
const cfrStream = stream.pipeThrough(fpsConverter.createStream());
|
|
3073
3083
|
const composeRequestStream = cfrStream.pipeThrough(
|
|
3074
3084
|
new TransformStream({
|
|
3075
3085
|
transform: (frame, controller) => {
|
|
3076
3086
|
let composeFrame = frame;
|
|
3077
|
-
if (windowToClipOffsetUs
|
|
3087
|
+
if (windowToClipOffsetUs !== 0) {
|
|
3078
3088
|
composeFrame = new VideoFrame(frame, {
|
|
3079
3089
|
timestamp: (frame.timestamp ?? 0) + windowToClipOffsetUs
|
|
3080
3090
|
});
|
|
@@ -3243,4 +3253,4 @@ const export_worker = null;
|
|
|
3243
3253
|
export {
|
|
3244
3254
|
export_worker as default
|
|
3245
3255
|
};
|
|
3246
|
-
//# sourceMappingURL=export.worker.
|
|
3256
|
+
//# sourceMappingURL=export.worker.Cw9iPvkh.js.map
|