Videosays 编辑团队·更新于 2026-08-29·约 10 分钟

视频文案提取 API Node.js 教程:提交、轮询和读取文字结果

Videosays API 使用异步任务模型:POST 创建任务,保存 taskId,再通过 GET 查询,直到 completed、failed 或 cancelled。客户端不应把一次 HTTP 请求保持到视频处理完成,也不应在超时后盲目重复创建任务。下面示例只使用公开契约中的 X-API-Key、Idempotency-Key、input 和 duplicatePolicy。

操作步骤

1

创建并妥善保存 API Key

在开发者控制台创建带标签的 API Key,并通过环境变量 VIDEOSAYS_API_KEY 注入后端进程。密钥只展示一次,可能过期或被撤销;不要写进浏览器代码、仓库、日志或教程截图。

2

使用幂等键创建任务

向 https://api.videosays.com/api/v1/transcribe 发送 POST,请求头包含 X-API-Key、Content-Type 和一个 UUID 格式的 Idempotency-Key。相同业务请求重试时复用相同键,不同请求必须使用新键。

3

保存 taskId 并按间隔轮询

接口可能返回 200 或 202。保存 taskId,通过 GET /api/v1/transcribe/{taskId} 查询;优先使用响应中的 retryAfterSeconds,避免高频轮询和 429。

4

处理完成、失败和复用状态

completed 时读取 result.text 和 result.segments;failed 或 cancelled 时停止轮询并记录 error;awaiting_reuse 时按产品策略处理复用决定。不要将失败响应包装成空白成功结果。

生产环境最小数据记录

创建时保存

业务请求 ID、Idempotency-Key、taskId、输入来源和创建时间;不要保存明文 API Key。

完成时保存

终态、result.text、segments、video 上下文、计费状态、完成时间和安全的错误码。

本地轮询超时应记录为“等待超时”,不能擅自把服务端任务写成 failed。

为什么异步任务更适合视频转写

视频解析、音轨准备、队列和语音识别时间不稳定,单个长 HTTP 请求容易被代理或客户端超时。异步模型让创建请求快速返回,业务系统可以保存 taskId、恢复轮询,并独立处理完成和失败。

Idempotency-Key 与同用户复用不是一回事

幂等键保护同一创建请求的网络重放;duplicatePolicy 控制同一用户是否复用自己已有的转写结果。不要为每次网络重试生成新幂等键,否则可能创建重复资源。Videosays 不跨用户共享转写结果。

常见状态和停止条件

pending、analyzing、submitting、processing 表示仍在运行;awaiting_reuse 需要调用方做复用选择;completed、failed 和 cancelled 是终态。客户端应该为总等待时间设置上限,但本地超时不等于服务端任务失败。

HTTP 错误应如何处理

401 表示鉴权失败;402 可能表示明确的新转写请求额度不足;409 可能是幂等键冲突;422 表示输入不支持;429 表示限流。记录状态码和安全的错误字段,不记录完整密钥。

批量处理使用专门的 batches 接口

需要提交 1–100 个普通视频输入时,使用 POST /api/v1/batches,并通过 GET /api/v1/batches/{batchId}?view=status 轻量轮询。不要在客户端瞬间并发 100 个单条创建请求。

可运行示例

创建并等待一条转写任务

Node.js 22 内置 fetch。示例保留服务端返回的 taskId,并按 retryAfterSeconds 轮询。

const API_BASE = 'https://api.videosays.com';
const apiKey = process.env.VIDEOSAYS_API_KEY;

if (!apiKey) throw new Error('VIDEOSAYS_API_KEY is required');

const createResponse = await fetch(API_BASE + '/api/v1/transcribe', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'X-API-Key': apiKey,
    'Idempotency-Key': crypto.randomUUID(),
  },
  body: JSON.stringify({
    input: 'https://www.douyin.com/video/REPLACE_WITH_PUBLIC_ID',
    options: { language: 'auto', sourceMode: 'auto', duplicatePolicy: 'reuse' },
  }),
});

if (![200, 202].includes(createResponse.status)) {
  throw new Error('Create failed: ' + createResponse.status);
}

let task = await createResponse.json();

while (!['completed', 'failed', 'cancelled'].includes(task.status)) {
  const waitSeconds = task.retryAfterSeconds ?? 5;
  await new Promise((resolve) => setTimeout(resolve, waitSeconds * 1000));

  const pollResponse = await fetch(
    API_BASE + '/api/v1/transcribe/' + task.taskId,
    { headers: { 'X-API-Key': apiKey } },
  );
  if (!pollResponse.ok) throw new Error('Poll failed: ' + pollResponse.status);
  task = await pollResponse.json();
}

if (task.status !== 'completed') {
  throw new Error(task.error?.message ?? 'Transcription did not complete');
}

console.log(task.result.text);

批量接口的最小请求

批量接口接受 1–100 个输入,并返回可独立轮询的 batchId。

const response = await fetch('https://api.videosays.com/api/v1/batches', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'X-API-Key': process.env.VIDEOSAYS_API_KEY,
    'Idempotency-Key': crypto.randomUUID(),
  },
  body: JSON.stringify({
    items: publicVideoLinks,
    options: { language: 'auto', sourceMode: 'auto', duplicatePolicy: 'reuse' },
  }),
});

if (response.status !== 202) {
  throw new Error('Batch create failed: ' + response.status);
}

const batch = await response.json();
console.log(batch.batchId);

核对来源

先完成最小异步闭环

创建 API Key,用一个公开样本跑通创建、轮询、终态和错误处理,再扩展到批量。

常见问题

Node.js 需要安装额外的 HTTP 库吗?

Node.js 22 已内置 fetch 和 crypto.randomUUID,基础示例不需要额外 HTTP 依赖。

为什么创建任务可能返回 200,也可能返回 202?

202 表示新任务已接受;200 可能表示幂等重放或按同用户复用策略返回已有终态任务。客户端应同时接受并读取响应体。

可以每秒轮询一次吗?

不建议。优先读取 retryAfterSeconds,并为 429 和网络错误设置退避。

怎样导出 SRT 或 VTT?

任务响应包含文字和时间轴 segments;网页和 CLI 提供 TXT、SRT、VTT 工作流。具体公开字段与格式应以 OpenAPI 和文档为准。

API Key 可以放在 Next.js 的 NEXT_PUBLIC 变量里吗?

不可以。NEXT_PUBLIC 会进入浏览器公开包。API Key 应只保存在服务端环境变量或安全密钥系统。