在React或JavaScript中如何获取用户上传MP3文件并调用谷歌语音转文字API
问题解决:MP3上传调用谷歌语音转文字API报错处理
报错根因
- 前端未正确封装上传文件:直接将File对象传给axios,未使用
FormData格式封装,后端无法解析到正确的文件流 - 后端逻辑错误:
fs模块用于读取服务器本地存储的文件,你直接用用户本地的文件名req.body.name作为读取路径,服务器上不存在对应文件,自然触发参数类型错误
修改方案
第一步:修改前端上传逻辑
将文件用FormData封装后再发送,修改onFileUpload方法即可:
onFileUpload = async () => { // 新建FormData对象封装文件 const formData = new FormData(); formData.append('audioFile', this.state.selectedFile); // 发送请求时指定content-type为multipart/form-data let res = await axios.post('/api/backend', formData, { headers: { 'Content-Type': 'multipart/form-data' } }); console.log("response is ",res); }
第二步:修改后端处理逻辑
首先安装formidable用于解析FormData格式的上传请求:npm install formidable
然后替换backend.js的全部代码:
import speech from '@google-cloud/speech' import formidable from 'formidable'; import fs from 'fs'; // 关闭Next.js默认的body解析,否则无法处理FormData export const config = { api: { bodyParser: false, } }; export default async function Speech(req,res) { // 解析上传的文件 const form = new formidable.IncomingForm(); form.parse(req, async (err, fields, files) => { if (err) { return res.status(500).json({error: '文件解析失败'}); } // 拿到上传的音频文件路径(formidable会把上传的文件暂存到服务器临时目录) const audioFilePath = files.audioFile.filepath; // 创建谷歌语音客户端 const client = new speech.SpeechClient(); const encoding = 'MP3'; // 注意:这里的采样率要和你实际MP3文件的采样率一致,否则识别会失败 const sampleRateHertz = 16000; const languageCode = 'az-AZ'; const config = { encoding: encoding, sampleRateHertz: sampleRateHertz, languageCode: languageCode, }; // 直接读取临时文件转base64 const audio = { content: fs.readFileSync(audioFilePath).toString('base64'), }; const request = { config: config, audio: audio, }; try { const [operation] = await client.longRunningRecognize(request); const [response] = await operation.promise(); const transcription = response.results .map(result => result.alternatives[0].transcript) .join('\n'); res.status(200).json(transcription) } catch (apiErr) { res.status(500).json({error: '语音识别失败', detail: apiErr.message}) } }) }
注意事项
- 请确保谷歌云的服务账号密钥已经正确配置到你的项目环境中,否则会触发谷歌API的权限错误
- 如果你的MP3文件采样率不是16000,请修改
sampleRateHertz参数为实际值 - 单文件识别时长限制为60秒,超过1分钟的音频请先上传到谷歌云存储再调用识别接口
内容的提问来源于stack exchange,提问作者Hurrairah Nasir
相关产品推荐
相关产品推荐

