生产级 AI 视频生成集成的工程实践
开发者分享在 SaaS 平台集成 Seedance 2.0 Mini 的完整方案,涵盖异步任务队列、信用系统设计、多 API 评选决策、成本优化等生产工程细节。
完整中文译文
AI 视频生成早已不再是新鲜事物——它正逐渐成为 SaaS 产品的核心功能。但要将其集成到生产环境的应用中,会遇到一些实实在在的工程挑战:异步处理、基于积分的计费、成本管理,以及用户体验设计。
本文将介绍我如何把 Seedance 2.0 Mini 集成到 VEIGO 平台、围绕它构建一套积分系统,以及我对 AI 生成内容定价的一些经验与思考。
我需要为一个 SaaS 平台添加 AI 视频生成功能,并满足以下要求:
- 用户可以通过文本 prompt 或图片生成视频
- 系统需要能够处理耗时较长的生成任务(30 秒到 5 分钟)
- 通过积分系统实现商业化,而不是按视频单独计价
- 提供无缝的用户体验——不能让用户觉得自己一直在等待某个批处理任务完成
为什么选择 Seedance 2.0 Mini
在评估了 Runway、Pika、Kling 和 Stable Video Diffusion 之后,我最终选择了 Seedance 2.0 Mini,原因有以下几点:
- 成本效益:以有竞争力的价格提供高质量输出
- API 可靠性:服务可用性和响应时间都比较稳定
- 分辨率灵活:支持多种输出选项(480p、720p、1080p)
- 图片生成视频能力:对于房产展示和商品展示来说至关重要
- 更契合中国市场:对中文文本 prompt 和文化语境的支持更好
架构:异步任务模式
视频生成并不是瞬间完成的。即便是所谓的“快速”模型,也需要 30 秒以上。下面是我实现的整体架构:
User Request → Task Queue → Seedance API → Polling Service → Result Storage → User Notification
第一步:创建任务
当用户提交生成请求时,我们不会同步等待视频生成完成,而是执行以下流程:
// app/api/studio/generate/route.ts
export async function POST(req: Request) {
const { prompt, imageUrl, resolution, duration } = await req.json();
// Calculate credit cost based on parameters
const creditCost = calculateCredits(resolution, duration);
// Check user balance
const user = await getUserWithBalance(session.userId);
if (user.credits < creditCost) {
return Response.json({ error: "Insufficient credits" }, { status: 402 });
}
// Create task record
const task = await db.videoTask.create({
data: {
userId: session.userId,
status: "PENDING",
prompt,
imageUrl,
resolution,
duration,
creditsCharged: creditCost,
}
});
// Submit to Seedance API (non-blocking)
const seedanceTaskId = await submitToSeedance({
prompt,
imageUrl,
resolution,
duration
});
// Update task with external ID
await db.videoTask.update({
where: { id: task.id },
data: { externalTaskId: seedanceTaskId, status: "PROCESSING" }
});
return Response.json({
taskId: task.id,
creditsCharged: creditCost,
estimatedTime: getEstimate(duration)
});
}
第二步:轮询服务
后台服务会轮询 Seedance API,检查任务是否已经完成:
// lib/services/video-poller.ts
export async function pollTaskCompletion() {
const pendingTasks = await db.videoTask.findMany({
where: { status: "PROCESSING" },
take: 10 // Batch processing
});
for (const task of pendingTasks) {
try {
const result = await seedance.getTaskStatus(task.externalTaskId);
if (result.status === "COMPLETED") {
// Download and store the video
const videoUrl = await downloadAndStore(result.videoUrl, task.id);
await db.videoTask.update({
where: { id: task.id },
data: {
status: "COMPLETED",
videoUrl,
completedAt: new Date()
}
});
// Notify user
await notifyUser(task.userId, {
type: "VIDEO_READY",
taskId: task.id
});
} else if (result.status === "FAILED") {
// Refund credits on failure
await refundCredits(task.userId, task.creditsCharged);
await db.videoTask.update({
where: { id: task.id },
data: { status: "FAILED", failureReason: result.error }
});
}
// If still processing, just wait for next poll cycle
} catch (error) {
console.error(`Poll error for task ${task.id}:`, error);
}
}
}
第三步:向用户展示任务状态
前端通过轮询获取任务状态,并显示进度指示器:
// components/VideoTaskStatus.tsx
export function VideoTaskStatus({ taskId }: { taskId: string }) {
const [status, setStatus] = useState<TaskStatus>("PROCESSING");
const [progress, setProgress] = useState(0);
useEffect(() => {
const interval = setInterval(async () => {
const res = await fetch(`/api/studio/task/${taskId}`);
const data = await res.json();
setStatus(data.status);
setProgress(data.progress);
if (data.status === "COMPLETED" || data.status === "FAILED") {
clearInterval(interval);
}
}, 3000); // Poll every 3 seconds
return () => clearInterval(interval);
}, [taskId]);
return (
<div className="task-status">
<ProgressBar value={progress} />
<StatusBadge status={status} />
{status === "COMPLETED" && <VideoPlayer url={status.videoUrl} />}
</div>
);
}
积分系统设计
相比按视频计价——这种方式容易让用户觉得费用难以预测——我设计了一套积分套餐系统。
每次生成所需的积分
不同参数会消耗不同数量的积分:
function calculateCredits(resolution: string, duration: number): number {
const baseCost = {
"480p": 2,
"720p": 4,
"1080p": 8
};
const durationMultiplier = duration <= 5 ? 1 : duration <= 10 ? 1.5 : 2;
return Math.ceil(baseCost[resolution] * durationMultiplier);
}
为什么积分制比按视频计价更好
- 收入更可预测:用户会预先购买积分套餐
- 使用方式更灵活:积分既可以用于生成一个 480p 片段,也可以累积起来生成一个 1080p 视频
- 减少决策疲劳:用户不需要计算每条视频的成本
- 创造升级销售机会:积分快用完了?可以向用户推荐单价更优惠的大额套餐
- 平滑应对成本变化:如果 API 成本发生变化,可以调整生成任务所需的积分,而不必修改用户看到的套餐价格
定价策略思考
经过 3 个月的运营,我观察到了以下情况:
5 美元套餐是拉新的主力。 大多数用户都会从这个套餐开始。它的试用成本足够低,而 100 积分可以让用户生成约 25 个 480p 视频,或者约 12 个 720p 视频。
30 美元套餐是最理想的价格档位。 那些迅速发现产品价值的用户,通常会升级到这一档。与入门套餐相比,每积分可节省 40%,这种优惠对用户来说非常明显。
企业用户会与我们议价。 50 美元可购买 2,500 积分,但对于需要大规模生成内容的企业来说,他们往往会联系我们洽谈定制定价。
关键洞察:定价的核心其实并不在于积分本身,而在于消除使用阻力。购买积分的用户会生成更多内容,这会增强平台黏性,进而降低用户流失率。
Seedance API 的成本并不低。为了保持健康的利润率,我采取了以下措施:
- 按分辨率分级定价:分辨率越高,消耗的积分越多,与更高的 API 成本保持一致
- 批量处理:将 API 调用分组处理,减少额外开销
- 缓存:对于使用相同 seed 的相似 prompt,直接使用缓存结果
- 失败处理:生成失败后立即退还积分,以维持用户信任
- 使用监控:当用户的生成模式可能存在滥用行为时发出警报
1. 尽早设定预期
用户需要知道视频生成需要时间。我们会提前显示预计等待时间,并使用乐观式 UI 更新。
2. 失败时始终退还积分
没有什么比生成失败后仍然扣除积分更容易摧毁用户信任。我们会立即退还积分,并发送通知说明失败原因。
3. 提供免费套餐
用户注册后,我们会赠送 10 个免费积分。这样一来,用户在付费之前就能先体验产品。从免费用户到付费用户的转化率约为 15%。
4. 监控 API 成本与积分收入
我们每周都会跟踪二者的比例,目标是保持 60% 以上的毛利率。如果 API 成本突然上涨,我们会调整各类生成任务所需的积分,而不是修改套餐价格——后者会破坏用户信任。
5. 内容审核必不可少
AI 生成的视频可能被滥用。提交任务之前,我们会让所有 prompt 先通过内容过滤器,同时为生成的内容提供举报系统。
AI Video Studio 的应用场景
AI Video Studio 已经上线,并集成到了 VEIGO 平台。它尤其适合以下场景:
- 房地产经纪人制作房产导览视频
- 电商卖家生成商品演示视频
- 内容创作者制作短视频内容
- 营销人员制作社交媒体广告
🎬 AI Video Studio:shopveigo.com/studio
💳 积分套餐:shopveigo.com/pricing
🏠 完整平台:shopveigo.com
你是否也在自己的产品中集成过 AI 视频生成功能?遇到了哪些挑战?欢迎在评论区分享你的经验。
如需采取进一步措施,你可以考虑屏蔽此人和/或举报滥用行为。