feat: bootstrap commercial AI drama platform
This commit is contained in:
@@ -0,0 +1,50 @@
|
||||
import assert from "node:assert/strict";
|
||||
import { execFileSync } from "node:child_process";
|
||||
import { mkdir, rm, stat } from "node:fs/promises";
|
||||
import { resolve } from "node:path";
|
||||
import { dbGet, dbRun, withTransaction } from "../server/db.mjs";
|
||||
import { registerJobArtifacts } from "../server/media-artifacts.mjs";
|
||||
|
||||
const projectRoot = resolve(import.meta.dirname, "..");
|
||||
const orgId = "org-studio-lab";
|
||||
const workspaceId = "ws-local-aidrama";
|
||||
const projectId = "thunder-mouth";
|
||||
const shotId = "shot-01";
|
||||
const shot = dbGet("SELECT * FROM shots WHERE id = ?", [shotId]);
|
||||
assert.ok(shot, "smoke shot must exist");
|
||||
const nextShot = dbGet("SELECT id, first_frame_path FROM shots WHERE episode_id = ? AND shot_number = ?", [shot.episode_id, Number(shot.shot_number) + 1]);
|
||||
const originalLastFrame = shot.last_frame_path;
|
||||
const originalNextFirstFrame = nextShot?.first_frame_path || "";
|
||||
const jobId = `smoke-media-${Date.now()}`;
|
||||
const relative = `storage/jobs/${jobId}/output.mp4`;
|
||||
const absolute = resolve(projectRoot, relative);
|
||||
const context = {
|
||||
organization: { id: orgId },
|
||||
workspace: { id: workspaceId },
|
||||
project: { id: projectId },
|
||||
user: { id: "u-owner" }
|
||||
};
|
||||
|
||||
try {
|
||||
await mkdir(resolve(projectRoot, `storage/jobs/${jobId}`), { recursive: true });
|
||||
execFileSync("ffmpeg", ["-y", "-v", "error", "-f", "lavfi", "-i", "color=c=0x1f5f8b:s=320x568:d=1", "-c:v", "libx264", "-pix_fmt", "yuv420p", absolute], { stdio: "pipe" });
|
||||
const timestamp = new Date().toISOString();
|
||||
dbRun("INSERT INTO generation_jobs(id, organization_id, workspace_id, project_id, episode_id, shot_id, kind, adapter_id, status, output_path, qa_status, created_by, created_at, updated_at) VALUES (?, ?, ?, ?, ?, ?, '视频片段', 'owned-i2v', 'completed', ?, 'wait', 'u-owner', ?, ?)", [jobId, orgId, workspaceId, projectId, shot.episode_id, shotId, relative, timestamp, timestamp]);
|
||||
const artifacts = await registerJobArtifacts(context, { id: jobId, episode_id: shot.episode_id, shot_id: shotId, kind: "视频片段", output_path: relative, created_by: "u-owner" }, { outputPath: relative });
|
||||
const artifact = artifacts.find((item) => item.kind === "video");
|
||||
assert.equal(artifact?.status, "inspected", "视频文件必须通过 FFprobe 检查");
|
||||
assert.equal((artifact.sha256 || "").length, 64, "视频证据必须登记 SHA-256");
|
||||
assert.ok(artifact.last_frame_path, "视频证据必须提取实际末帧路径");
|
||||
await stat(resolve(projectRoot, artifact.last_frame_path));
|
||||
assert.equal(dbGet("SELECT last_frame_path FROM shots WHERE id = ?", [shotId]).last_frame_path, artifact.last_frame_path, "镜头必须继承实际末帧");
|
||||
if (nextShot) assert.equal(dbGet("SELECT first_frame_path FROM shots WHERE id = ?", [nextShot.id]).first_frame_path, artifact.last_frame_path, "下一镜头必须继承上一镜头实际末帧");
|
||||
console.log(`media evidence smoke passed: ${artifact.path} -> ${artifact.last_frame_path}`);
|
||||
} finally {
|
||||
withTransaction(() => {
|
||||
dbRun("DELETE FROM media_artifacts WHERE job_id = ?", [jobId]);
|
||||
dbRun("DELETE FROM generation_jobs WHERE id = ?", [jobId]);
|
||||
dbRun("UPDATE shots SET last_frame_path = ?, updated_at = ? WHERE id = ?", [originalLastFrame, new Date().toISOString(), shotId]);
|
||||
if (nextShot) dbRun("UPDATE shots SET first_frame_path = ?, updated_at = ? WHERE id = ?", [originalNextFirstFrame, new Date().toISOString(), nextShot.id]);
|
||||
});
|
||||
await rm(resolve(projectRoot, `storage/jobs/${jobId}`), { recursive: true, force: true });
|
||||
}
|
||||
Reference in New Issue
Block a user