63 lines
2.0 KiB
TypeScript
63 lines
2.0 KiB
TypeScript
import { ProviderTaskUncertainError } from "./video-task-lifecycle";
|
|
import "server-only";
|
|
import { mkdtemp, readFile, rm } from "node:fs/promises";
|
|
import { tmpdir } from "node:os";
|
|
import path from "node:path";
|
|
import { uploadFile } from "@/lib/storage/service";
|
|
import { videoUpscaleSchema } from "./video-upscale-contract";
|
|
import { remoteUpscale, type UpscaleCheckpoint } from "./video-upscale-remote";
|
|
export async function executeVideoUpscale(
|
|
params: Record<string, unknown>,
|
|
userId: string,
|
|
taskId: string,
|
|
lifecycle: {
|
|
resume?: UpscaleCheckpoint;
|
|
active: () => Promise<void>;
|
|
save: (value: Record<string, unknown>) => Promise<void>;
|
|
}
|
|
) {
|
|
const input = videoUpscaleSchema.parse(params),
|
|
dir = await mkdtemp(path.join(tmpdir(), "upscale-"));
|
|
try {
|
|
const output = await remoteUpscale(input, userId, taskId, dir, {
|
|
resume: lifecycle.resume,
|
|
active: lifecycle.active,
|
|
save: (remote, stage) => lifecycle.save({ upscale: { remote, stage } }),
|
|
});
|
|
await lifecycle.active();
|
|
const file = await readFile(output.file);
|
|
let stored;
|
|
try {
|
|
stored = await uploadFile(
|
|
`video-upscale-${taskId}.mp4`,
|
|
(file.byteOffset === 0 && file.byteLength === file.buffer.byteLength
|
|
? file.buffer
|
|
: file.buffer.slice(
|
|
file.byteOffset,
|
|
file.byteOffset + file.byteLength
|
|
)) as ArrayBuffer
|
|
);
|
|
} catch {
|
|
throw new ProviderTaskUncertainError(
|
|
"高清结果已生成,归档暂时失败,将继续归档同一结果"
|
|
);
|
|
}
|
|
return {
|
|
url: stored.url,
|
|
metadata: {
|
|
width: output.width,
|
|
height: output.height,
|
|
durationSeconds: output.duration,
|
|
fps: output.fps,
|
|
frames: output.frames,
|
|
hasAudio: output.audio,
|
|
engine: "Real-ESRGAN",
|
|
model: "realesr-general-x4v3",
|
|
resolution: input.resolution,
|
|
},
|
|
};
|
|
} finally {
|
|
await rm(dir, { recursive: true, force: true });
|
|
}
|
|
}
|