You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在NextJS中实现视频上传后的字幕自动生成与翻译?

视频语音转文字翻译及NextJS集成解决方案

一、工具选型:优先选用OpenAI Whisper

Whisper完全匹配你的需求:

  • 支持99种语言的语音识别,内置英文翻译能力,通过task="translate"参数可一键生成英文翻译字幕
  • 支持输出SRT、VTT等主流字幕格式,能直接被视频播放器的字幕菜单识别
  • 提供不同量级的模型(tiny/base/small/medium/large),可根据精度和性能需求灵活选择

二、NextJS调用Python Whisper的两种可行方案

NextJS是JavaScript/TypeScript环境,无法直接运行Python库,需通过以下方式集成:

方案1:自建Python API服务(推荐,性能更稳定)

用FastAPI或Flask搭建独立的Python服务,专门处理视频转字幕逻辑,NextJS通过HTTP请求调用该服务。

Python API示例(FastAPI)

from fastapi import FastAPI, File, UploadFile
import whisper
import os
from typing import Optional

app = FastAPI()
# 预加载模型,避免每次请求重新加载
model = whisper.load_model("base")  # 可根据需求替换为small/medium/large

def format_timestamp(seconds: float) -> str:
    """将秒数转换为VTT格式的时间戳"""
    hours = int(seconds // 3600)
    minutes = int((seconds % 3600) // 60)
    secs = seconds % 60
    return f"{hours:02d}:{minutes:02d}:{secs:06.3f}".replace(".", ",")

@app.post("/process-video")
async def process_video(
    video_path: Optional[str] = None,  # 云端视频文件路径(如对象存储键)
    file: Optional[UploadFile] = None  # 直接上传的视频文件
):
    temp_video_path = "temp_video.mp4"
    
    # 处理视频来源
    if file:
        # 保存上传的临时文件
        with open(temp_video_path, "wb") as f:
            f.write(await file.read())
    elif video_path:
        # 从云端下载视频到本地(替换为你的对象存储SDK逻辑)
        # 示例:import boto3; s3 = boto3.client('s3'); s3.download_file("your-bucket", video_path, temp_video_path)
        pass
    else:
        return {"error": "请提供视频路径或上传视频文件"}
    
    # 执行语音转文字并翻译为英文
    result = model.transcribe(temp_video_path, task="translate")
    
    # 生成VTT字幕内容
    vtt_content = "WEBVTT\n\n"
    for idx, segment in enumerate(result["segments"], 1):
        start_ts = format_timestamp(segment["start"])
        end_ts = format_timestamp(segment["end"])
        vtt_content += f"{idx}\n{start_ts} --> {end_ts}\n{segment['text'].strip()}\n\n"
    
    # 清理临时文件
    os.remove(temp_video_path)
    
    return {
        "subtitle_content": vtt_content,
        "format": "vtt",
        "language": result["language"]
    }

NextJS调用示例(客户端/服务端)

// 服务端组件或API路由中调用
async function processVideoForSubtitle(videoCloudPath: string) {
  try {
    const res = await fetch("http://your-python-api-domain/process-video", {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
      },
      body: JSON.stringify({ video_path: videoCloudPath }),
    });
    
    if (!res.ok) throw new Error("字幕处理失败");
    
    const data = await res.json();
    // 将字幕内容上传到对象存储,并关联到用户的视频记录
    // 示例:await uploadToCloudStorage(data.subtitle_content, `${videoId}.vtt`)
    return data;
  } catch (err) {
    console.error(err);
    throw err;
  }
}

方案2:使用Pyodide在NextJS Edge Runtime中运行Whisper(无需独立服务)

借助Pyodide将Python代码编译为WASM,直接在NextJS的Edge函数中运行Whisper,适合轻量场景。

NextJS Edge API路由示例

// app/api/generate-subtitle/route.ts
import { NextResponse } from 'next/server';
import pyodide from 'pyodide';

export const runtime = 'edge';

export async function POST(request: Request) {
  try {
    const { videoBuffer } = await request.json();
    // 初始化Pyodide环境
    const py = await pyodide.loadPyodide({
      indexURL: "https://cdn.jsdelivr.net/pyodide/v0.25.0/full/"
    });
    
    // 安装Whisper的WASM兼容包
    await py.installPackage("whisper-cpp-pyodide");
    
    // 将视频写入Pyodide文件系统
    py.FS.writeFile("temp_video.mp4", new Uint8Array(videoBuffer));
    
    // 执行Whisper转写翻译逻辑
    const subtitleContent = await py.runPythonAsync(`
      import whisper_cpp
      model = whisper_cpp.WhisperModel("base")
      result = model.transcribe("temp_video.mp4", task="translate")
      
      # 生成VTT字幕
      vtt = "WEBVTT\\n\\n"
      def format_ts(seconds):
          hours = int(seconds // 3600)
          minutes = int((seconds % 3600) // 60)
          secs = seconds % 60
          return f"{hours:02d}:{minutes:02d}:{secs:06.3f}".replace(".", ",")
      
      for idx, seg in enumerate(result["segments"], 1):
          vtt += f"{idx}\\n{format_ts(seg['start'])} --> {format_ts(seg['end'])}\\n{seg['text'].strip()}\\n\\n"
      
      vtt
    `);
    
    // 清理临时文件
    py.FS.unlink("temp_video.mp4");
    
    return NextResponse.json({ subtitle: subtitleContent, format: "vtt" });
  } catch (err) {
    return NextResponse.json({ error: (err as Error).message }, { status: 500 });
  }
}

三、关键注意事项

  • 模型选择:追求速度用base模型,追求高精度用large模型;部署时可根据服务器资源调整
  • 视频存储:用户上传的视频建议先存到对象存储(如S3、阿里云OSS),再将路径传给处理服务,避免直接传输大文件
  • 跨域配置:如果Python服务和NextJS前端域名不同,需在Python服务中配置CORS,或在NextJS中设置反向代理
  • 字幕格式:优先选择VTT格式,兼容性更好;如需SRT可修改时间戳格式化逻辑

内容的提问来源于stack exchange,提问作者Merger

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.05 20:50:01