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

如何在Node.js服务端将OpenAI TTS输出流式传输至WHIP端点?

如何在Node.js服务端将OpenAI TTS输出流式传输至WHIP端点?

我完全懂你现在的困扰——浏览器里借助Media Capture API把音视频推到WHIP端点简直手到擒来,但到了Node.js环境,没有浏览器自带的WebRTC和Audio API加持,想把OpenAI TTS的响应(不管是HTTP流式输出还是本地音频文件)转成能推送给WHIP的MediaStreamTrack,确实卡壳。我之前做类似项目时踩过不少坑,给你分享几个实用的解决方案:

方案一:用werift-webrtc构建流式推送

werift是Node.js生态里比较成熟的WebRTC实现,对WHIP协议的支持也比较友好,适合快速搭建服务端推流逻辑:

  • 获取OpenAI TTS的流式音频:调用OpenAI TTS接口时,指定输出格式为opus或者pcm16(WebRTC原生支持的格式),这样能减少后续转码的工作量。
  • 创建AudioStreamTrack:用werift提供的AudioStreamTrack类,把从OpenAI接收到的音频数据分片喂进去。要注意匹配音频参数:比如采样率48kHz、单声道(WebRTC常用配置)。
  • 建立WHIP推流连接:构建PeerConnection,生成SDP Offer,通过HTTP POST发送到WHIP端点,接收并设置远端Answer,最后把AudioTrack添加到连接里开始推流。

给你一段简化的代码示例:

import { PeerConnection, AudioStreamTrack } from 'werift-webrtc';
import fetch from 'node-fetch';

async function pushTtsToWhip() {
  // 1. 获取OpenAI TTS流式输出
  const ttsResponse = await fetch('https://api.openai.com/v1/audio/speech', {
    method: 'POST',
    headers: {
      'Authorization': 'Bearer YOUR_API_KEY',
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      model: 'tts-1',
      input: '你好,这是来自OpenAI的TTS测试音频',
      voice: 'alloy',
      response_format: 'opus',
      speed: 1.0
    })
  });

  // 2. 创建AudioStreamTrack,处理流式音频数据
  const track = new AudioStreamTrack({
    kind: 'audio',
    sampleRate: 48000,
    channels: 1,
  });

  // 3. 把TTS的流式数据喂给Track
  const reader = ttsResponse.body.getReader();
  async function feedTrack() {
    const { done, value } = await reader.read();
    if (!done) {
      track.write(value);
      await feedTrack();
    } else {
      track.end();
    }
  }
  feedTrack();

  // 4. 建立WHIP连接
  const pc = new PeerConnection({});
  pc.addTrack(track);

  const offer = await pc.createOffer();
  await pc.setLocalDescription(offer);

  // 发送Offer到WHIP端点
  const whipResponse = await fetch('YOUR_WHIP_ENDPOINT_URL', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/sdp',
    },
    body: pc.localDescription.sdp,
  });

  const answerSdp = await whipResponse.text();
  await pc.setRemoteDescription({ type: 'answer', sdp: answerSdp });

  console.log('推流已启动');
}

pushTtsToWhip();

方案二:用Gstreamer处理转码与推流

如果你的服务端环境能安装Gstreamer,那它绝对是处理音频转码、流式传输的利器,尤其是应对不同格式的音频时:

  • 本地音频文件推流:可以直接用Gstreamer管道读取音频文件,转码成WebRTC兼容格式后推送到WHIP端点,比如:
    gst-launch-1.0 filesrc location=tts_output.wav ! audioconvert ! opusenc ! webrtcbin name=whip whip::endpoint=YOUR_WHIP_URL whip::direction=sendonly
    
  • 流式TTS输出推流:如果不想保存成文件,可以把OpenAI TTS的流式输出直接通过标准输入传给Gstreamer,用fdsrc读取:
    curl -X POST -H "Authorization: Bearer YOUR_API_KEY" -H "Content-Type: application/json" -d '{"model":"tts-1","input":"测试流式音频","voice":"alloy","response_format":"wav"}' https://api.openai.com/v1/audio/speech | gst-launch-1.0 fdsrc fd=0 ! wavparse ! audioconvert ! opusenc ! webrtcbin name=whip whip::endpoint=YOUR_WHIP_URL whip::direction=sendonly
    
    这种方式不需要写太多Node.js代码,借助Gstreamer的WHIP插件就能完成大部分工作。

方案三:用node-webrtc实现(注意维护状态)

node-webrtc是Node.js对原生WebRTC的绑定,功能和浏览器API更接近,但要注意它的维护状态(最近更新不算频繁)。核心思路和werift类似:

  1. 把OpenAI TTS的音频数据转成MediaStreamTrack(需要手动处理音频的编码格式、采样率匹配)
  2. 构建RTCPeerConnection,处理WHIP的SDP Offer/Answer流程
  3. 添加Track并启动推流

关键注意事项

  • 音频格式匹配:WebRTC优先支持Opus和16bit PCM,调用OpenAI TTS时尽量指定这两种格式,避免额外转码带来的延迟
  • 流式处理优先:尽量采用边接收TTS数据边推流的方式,不要等整个音频文件下载完成再推送,这样才能保证实时性
  • WHIP协议细节:WHIP本质上是基于HTTP的WebRTC信令,要确保正确处理SDP的交换、ICE候选的收集(大部分WebRTC库会自动处理,但要留意日志排查问题)

备注:内容来源于stack exchange,提问作者matthew

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.17 11:17:58