You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何将浏览器录制的音频流发送至Node.js服务器适配IBM Watson

解决音频流直接传输到Node.js并适配IBM Watson的方案

嘿,这事儿我熟!我来帮你把音频流直接传到Node.js后端,完美适配IBM Watson的需求,完全不用碰文件存储那一套~

一、前端改造:实现录制启停与流发送

首先咱们得给前端添上录制控制逻辑,用MediaRecorder来处理音频录制,停止后直接把流发给后端:

<!DOCTYPE html>
<html lang='fr'>
<head>
<script>
let mediaRecorder = null;
let mediaStream = null;
let isRecording = false;

function startRecording() {
  if (isRecording) {
    // 停止录制
    mediaRecorder.stop();
    return;
  }
  
  navigator.mediaDevices.getUserMedia({ audio: true })
    .then(stream => {
      mediaStream = stream;
      // 选择IBM Watson支持的音频格式,这里用audio/wav(也可选更高效的audio/ogg; codecs=opus)
      const mimeType = 'audio/wav';
      if (!MediaRecorder.isTypeSupported(mimeType)) {
        console.warn(`${mimeType} 不被浏览器支持,将使用默认格式`);
      }
      mediaRecorder = new MediaRecorder(stream, { mimeType });
      
      const audioChunks = [];
      mediaRecorder.ondataavailable = (e) => {
        if (e.data.size > 0) audioChunks.push(e.data);
      };
      
      mediaRecorder.onstop = () => {
        // 将录制的音频块转为Blob,再转成ReadableStream发送给后端
        const audioBlob = new Blob(audioChunks, { type: mimeType });
        sendAudioStream(audioBlob.stream());
        // 关闭媒体流,释放资源
        mediaStream.getTracks().forEach(track => track.stop());
        isRecording = false;
        document.getElementById('recordBtn').textContent = 'Lancer l\'audio';
      };
      
      mediaRecorder.start();
      isRecording = true;
      document.getElementById('recordBtn').textContent = 'Arrêter l\'enregistrement';
    })
    .catch(err => {
      console.error('获取音频权限失败:', err);
    });
}

function sendAudioStream(audioStream) {
  fetch('/api/audio-stream', {
    method: 'POST',
    body: audioStream,
    headers: {
      'Content-Type': 'audio/wav' // 和录制格式保持一致
    }
  })
  .then(response => {
    if (!response.ok) throw new Error(`请求失败: ${response.status}`);
    return response.json();
  })
  .then(watsonResponse => {
    console.log('IBM Watson 返回结果:', watsonResponse);
    // 这里可以把Watson的响应展示给用户,比如语音播报或者文字显示
  })
  .catch(err => {
    console.error('发送音频流失败:', err);
  });
}
</script>
<title>Enregistreur audio pour Watson</title>
</head>
<body>
<button id='recordBtn' onclick='startRecording()'>Lancer l'audio</button>
</body>
</html>

二、后端Express实现:接收流并传给IBM Watson

接下来配置Node.js后端,直接把前端传来的流转发给IBM Watson,全程不落地文件:

1. 先安装依赖

npm install express ibm-watson @ibm-cloud/platform-sdk

2. 后端代码

const express = require('express');
const { SpeechToTextV1 } = require('ibm-watson');
const { IamAuthenticator } = require('ibm-cloud-sdk-core');

const app = express();
const PORT = process.env.PORT || 3000;

// 初始化IBM Watson语音转文本客户端
const speechToText = new SpeechToTextV1({
  authenticator: new IamAuthenticator({
    apikey: '你的Watson API密钥', // 替换成你的密钥
  }),
  serviceUrl: '你的Watson服务URL', // 替换成你的服务地址
});

// 托管前端静态文件(把上面的HTML放到项目根目录的public文件夹里)
app.use(express.static('public'));

// 处理音频流的POST请求
app.post('/api/audio-stream', async (req, res) => {
  try {
    const recognizeParams = {
      audio: req, // 直接将请求流传给Watson
      contentType: 'audio/wav', // 和前端发送的格式一致
      model: 'fr-FR_BroadbandModel', // 法语模型,根据你的需求调整
    };

    // 调用Watson语音识别API
    const watsonResult = await speechToText.recognize(recognizeParams);
    res.json(watsonResult.result);
  } catch (error) {
    console.error('Watson处理出错:', error);
    res.status(500).json({ error: error.message });
  }
});

app.listen(PORT, () => {
  console.log(`服务器运行在 http://localhost:${PORT}`);
});

三、关键细节说明

  • 流式传输核心:前端把Blob转为ReadableStream发送,后端直接将req(本身就是流对象)传给Watson,全程没有文件的读写删除操作,完全符合你的需求。
  • 音频格式适配:要确保前端录制的格式和Watson支持的一致,Watson支持audio/wavaudio/ogg; codecs=opus等格式,选哪个都可以,只要前后端和Watson配置统一。
  • 资源释放:停止录制后记得关闭媒体流的track,避免浏览器持续占用麦克风资源。

对了,顺便说个小趣事:我的Imgur ID以"NUL"开头,在法语里这可是“菜鸟”的意思,哈哈!

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

火山引擎 最新活动