如何在Next.js(Node.js)中从视频提取音频并转录?
实现视频文件转录的解决方案
要实现从视频文件中提取音频并转录的需求,我们可以使用FFmpeg在内存中直接处理视频文件,无需第三方API或云存储。以下是具体步骤:
1. 安装依赖包
首先安装用于处理音视频的工具库:
npm install fluent-ffmpeg ffmpeg-static
fluent-ffmpeg:Node.js环境下的FFmpeg封装库ffmpeg-static:预编译的FFmpeg二进制文件,确保服务器环境中存在FFmpeg
2. 修改API路由代码
替换原有的API路由代码为以下内容:
import { NextRequest, NextResponse } from 'next/server'; import { SpeechClient } from '@google-cloud/speech'; import { Buffer } from 'buffer'; import ffmpeg from 'fluent-ffmpeg'; import ffmpegPath from 'ffmpeg-static'; import { Readable } from 'stream'; // 设置FFmpeg二进制文件路径 ffmpeg.setFfmpegPath(ffmpegPath); // 解码环境变量中的Base64格式Google凭据 const base64EncodedCredentials = process.env.GOOGLE_APPLICATION_CREDENTIALS_BASE64; if (!base64EncodedCredentials) { throw new Error('Google Cloud服务账号凭据未提供'); } const credentialsBuffer = Buffer.from(base64EncodedCredentials, 'base64'); const credentials = JSON.parse(credentialsBuffer.toString('utf8')); // 初始化Google Speech客户端 const client = new SpeechClient({ credentials: { client_email: credentials.client_email, private_key: credentials.private_key, }, projectId: credentials.project_id, }); export async function POST(req: NextRequest) { try { const formData = await req.formData(); const file = formData.get('file') as File | null; if (!file) { return new NextResponse(JSON.stringify({ error: '未提供视频文件' }), { status: 400 }); } // 将视频文件转换为Buffer const videoBuffer = Buffer.from(await file.arrayBuffer()); // 创建可读流供FFmpeg处理 const videoStream = Readable.from(videoBuffer); // 使用FFmpeg提取音频并转换为MP3格式 const audioBuffer = await new Promise<Buffer>((resolve, reject) => { const audioChunks: Buffer[] = []; ffmpeg(videoStream) .noVideo() // 仅处理音频 .audioCodec('libmp3lame') // 使用MP3编码器 .format('mp3') // 输出格式为MP3 .on('error', (err) => { console.error('[ERROR_EXTRACTING_AUDIO]', err); reject(new Error('音频提取失败')); }) .on('data', (chunk) => audioChunks.push(chunk)) .on('end', () => resolve(Buffer.concat(audioChunks))) .pipe(); // 启动处理流程 }); // 将音频Buffer转换为Base64字符串 const audioBytes = audioBuffer.toString('base64'); // 调用Google Speech-to-Text API进行转录 const [response] = await client.recognize({ audio: { content: audioBytes, }, config: { encoding: 'MP3', sampleRateHertz: 16000, languageCode: 'en-US', model: 'default', useEnhanced: true, speechContexts: [ { phrases: ['google cloud'], boost: 20.0, }, ], enableWordTimeOffsets: true, }, }); if (!response.results || response.results.length === 0) { throw new Error('未获取到转录结果'); } // 提取转录文本 const transcription = response.results .map(result => { if (!result.alternatives || result.alternatives.length === 0) { return ''; } return result.alternatives[0].transcript; }) .join('\n'); return new NextResponse(JSON.stringify({ transcription }), { status: 200 }); } catch (error) { console.error('[ERROR_TRANSCRIBING]', error); return new NextResponse('内部服务器错误', { status: 500 }); } }
关键代码说明
- FFmpeg音频提取:通过
ffmpeg(videoStream)读取视频流,使用.noVideo()禁用视频处理,指定MP3编码格式,将输出的音频数据收集为Buffer。 - 内存处理:整个过程无需写入磁盘,所有数据都在内存中流转,符合不使用云存储或本地文件的要求。
- 错误处理:新增了音频提取阶段的错误捕获,确保异常情况能被正确处理并返回对应错误信息。
注意事项
- 运行环境兼容性:
ffmpeg-static会根据当前操作系统和架构自动下载对应的FFmpeg二进制文件,确保部署环境(如Vercel、AWS等)支持该依赖。 - 视频大小限制:过大的视频文件可能导致内存占用过高或请求超时,建议在前端添加文件大小限制,或在服务器端配置更长的超时时间。
- 音频格式适配:如果需要支持其他音频输出格式(如WAV),可修改FFmpeg的
format和audioCodec参数,并同步更新Google Speech配置中的encoding字段。
内容的提问来源于stack exchange,提问作者Mohammed Bekele
相关产品推荐
相关产品推荐

