Files

78 lines
2.4 KiB
TypeScript

import "dotenv/config";
import { writeFile } from "node:fs/promises";
import { setTimeout as sleep } from "node:timers/promises";
import { prisma } from "../lib/prisma";
import { prepareAudio } from "../lib/stt/audio";
import {
downloadTranscript,
getAsrConfig,
queryTranscription,
submitTranscription,
} from "../lib/stt/dashscope";
async function main() {
const videoId = process.argv[2];
if (!videoId || !/^[A-Za-z0-9_-]+$/.test(videoId))
throw new Error("用法:npx tsx scripts/stt-smoke.ts <视频 ID>");
getAsrConfig();
const video = await prisma.video.findUniqueOrThrow({
where: { aweme_id: videoId },
select: { duration_ms: true },
});
console.log(
JSON.stringify({
videoId,
durationSeconds: video.duration_ms / 1000,
phase: "extracting_audio",
}),
);
const audioURL = await prepareAudio(videoId);
const resultPath = `/tmp/douyin-asr-${videoId}.json`;
if (!audioURL) {
await writeFile(
resultPath,
JSON.stringify({ videoId, transcript: [] }, null, 2),
);
console.log(
JSON.stringify({ phase: "complete", transcript: [], resultPath }),
);
return;
}
const taskId = await submitTranscription(audioURL);
await writeFile(
resultPath,
JSON.stringify({ videoId, taskId, status: "submitted" }, null, 2),
);
console.log(JSON.stringify({ phase: "submitted", taskId }));
for (let attempt = 0; attempt < 90; attempt++) {
await sleep(10_000);
const task = await queryTranscription(taskId);
if (task.status === "SUCCEEDED") {
const transcript = await downloadTranscript(task.resultURL);
await writeFile(
resultPath,
JSON.stringify({ videoId, taskId, transcript }, null, 2),
);
console.log(
JSON.stringify({ phase: "complete", transcript, resultPath }),
);
return;
}
if (attempt % 6 === 0) console.log(JSON.stringify({ phase: task.status }));
}
throw new Error(
`15 分钟内未完成,任务 ID 已保存在 ${resultPath},请查询原任务而非重复提交`,
);
}
main()
.catch((error) => {
// Do not print arbitrary SDK/network errors: they may contain signed URLs.
console.error(
error instanceof Error && !error.name.startsWith("Prisma")
? error.message
: "读取视频或转写失败",
);
process.exitCode = 1;
})
.finally(() => prisma.$disconnect());