MCPcopy Create free account
hub / github.com/TomClive/SeeDance2Stitcher / handleExport

Function handleExport

server.js:754–889  ·  view source on GitHub ↗
(req, res)

Source from the content-addressed store, hash-verified

752}
753
754async function handleExport(req, res) {
755 try {
756 const body = JSON.parse((await readBody(req)).toString() || "{}");
757 const session = sessions.get(body.id);
758 if (!session) throw new Error("Session not found. Analyse videos first.");
759
760 const fps = session.meta1.fps || 24;
761 const trimEnd1 = clampNumber(body.trimEnd1, 0, session.meta1.frames - 1);
762 const trimStart2 = clampNumber(body.trimStart2, 0, session.meta2.frames - 1);
763 const blendFrames = clampNumber(body.blendFrames, 0, 48);
764 const interpolate = Boolean(body.interpolate);
765 const mode = body.mode === "blend" && blendFrames > 0 ? "blend" : "cut";
766 const toneFrames = clampNumber(body.toneFrames, 0, 48);
767 const toneScope = body.toneScope === "full" ? "full" : "join";
768 const toneMatch = Boolean(body.toneMatch) && (toneScope === "full" || toneFrames > 0);
769 const audioMode = ["micro_crossfade", "clean_cut", "hard_cut"].includes(body.audioMode) ? body.audioMode : "micro_crossfade";
770 const output = uniqueOutputPath(outputName(session, {
771 trimEnd1,
772 trimStart2,
773 mode,
774 blendFrames,
775 toneMatch,
776 toneScope,
777 toneFrames,
778 interpolate,
779 audioMode
780 }));
781 const end1 = Math.max(1 / fps, (session.meta1.frames - trimEnd1) / fps);
782 const start2 = trimStart2 / fps;
783 const blendDuration = Math.min(blendFrames / fps, Math.max(0, end1 - 1 / fps));
784 const toneSource = session.analysis.tone;
785 const v2ToneFilter = toneMatch ? toneFilter(toneSource, toneScope === "full" ? 1 : toneFrames, fps, toneScope) : "";
786
787 let filter;
788 if (mode === "blend") {
789 const offset = Math.max(0, end1 - blendDuration);
790 const expr = `A*(1-T/${blendDuration.toFixed(6)})+B*(T/${blendDuration.toFixed(6)})`;
791 filter = [
792 `[0:v]trim=start=0:end=${end1.toFixed(6)},setpts=PTS-STARTPTS,format=yuv420p[v0base]`,
793 `[1:v]trim=start=${start2.toFixed(6)},setpts=PTS-STARTPTS,${v2ToneFilter}format=yuv420p[v1base]`,
794 `[v0base]split=2[v0pre][v0fade]`,
795 `[v1base]split=2[v1fade][v1post]`,
796 `[v0pre]trim=start=0:end=${offset.toFixed(6)},setpts=PTS-STARTPTS[pre]`,
797 `[v0fade]trim=start=${offset.toFixed(6)}:end=${end1.toFixed(6)},setpts=PTS-STARTPTS[v0b]`,
798 `[v1fade]trim=start=0:end=${blendDuration.toFixed(6)},setpts=PTS-STARTPTS[v1b]`,
799 `[v1post]trim=start=${blendDuration.toFixed(6)},setpts=PTS-STARTPTS[post]`,
800 `[v0b][v1b]blend=all_expr='${expr}'[mix]`,
801 `[pre][mix][post]concat=n=3:v=1:a=0[vout]`
802 ].join(";");
803 } else {
804 filter = [
805 `[0:v]trim=start=0:end=${end1.toFixed(6)},setpts=PTS-STARTPTS,format=yuv420p[v0]`,
806 `[1:v]trim=start=${start2.toFixed(6)},setpts=PTS-STARTPTS,${v2ToneFilter}format=yuv420p[v1]`,
807 `[v0][v1]concat=n=2:v=1:a=0[vout]`
808 ].join(";");
809 }
810
811 if (interpolate) {

Callers 1

handleRequestFunction · 0.85

Calls 7

readBodyFunction · 0.85
clampNumberFunction · 0.85
uniqueOutputPathFunction · 0.85
outputNameFunction · 0.85
toneFilterFunction · 0.85
startExportJobFunction · 0.85
jsonFunction · 0.85

Tested by

no test coverage detected