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

如何将<Dial>音频流传输至WebSocket,实现通话全量实时转录?

Twilio Dial转接场景下双方通话实时转录解决方案
  • 启用被叫方媒体流
    默认<Dial>不会自动转发被叫方的音频流,需要在<Dial>的子元素(如<Number>或<Client>)中添加stream="start"属性,触发Twilio向你的WebSocket端点发送被叫方的媒体流。示例TwiML:

    <Response>
      <!-- 启动主叫方媒体流 -->
      <Start>
        <Stream url="wss://你的WebSocket服务器地址/stream" />
      </Start>
      <!-- 转接并启动被叫方媒体流 -->
      <Dial>
        <Number stream="start">+1234567890</Number>
      </Dial>
    </Response>
    
  • 区分WebSocket中的双方流
    Twilio在发送媒体流的初始start事件时,会携带participant(如caller/callee)和streamSid字段,每个参与者对应唯一的streamSid。你的WebSocket服务需要基于这些标识,为双方分别创建独立的语音识别会话,避免音频混流。

  • 多路流处理示例(Node.js)
    用streamSid作为键维护不同的语音识别实例,确保双方音频被单独处理:

    const { SpeechClient } = require('@google-cloud/speech');
    const speechClient = new SpeechClient();
    const activeStreams = new Map(); // 存储streamSid到识别流的映射
    
    ws.on('message', (rawData) => {
      const message = JSON.parse(rawData);
      switch (message.event) {
        case 'start':
          const { streamSid, participant } = message.start;
          // 配置语音识别参数(匹配Twilio音频格式:8kHz PCMU)
          const request = {
            config: {
              encoding: 'MULAW',
              sampleRateHertz: 8000,
              languageCode: 'zh-CN',
            },
            interimResults: true,
          };
          const recognizeStream = speechClient.streamingRecognize(request)
            .on('data', (res) => {
              const transcript = res.results[0].alternatives[0].transcript;
              console.log(`[${participant}] ${transcript}`);
            });
          activeStreams.set(streamSid, recognizeStream);
          break;
        case 'media':
          const { streamSid: mediaStreamSid, media: { payload } } = message;
          const targetStream = activeStreams.get(mediaStreamSid);
          if (targetStream) {
            targetStream.write(Buffer.from(payload, 'base64'));
          }
          break;
        case 'stop':
          const { streamSid: stopStreamSid } = message.stop;
          const stopStream = activeStreams.get(stopStreamSid);
          if (stopStream) {
            stopStream.end();
            activeStreams.delete(stopStreamSid);
          }
          break;
      }
    });
    
  • 常见问题排查

    • 确认Twilio控制台中媒体流功能已启用,WebSocket端点可正常访问
    • 检查TwiML中stream="start"属性是否正确添加到<Number>/<Client>标签中
    • 通过Twilio调试日志(控制台→监控→事件)验证被叫方的媒体流请求是否已发送
    • 确保WebSocket服务器支持并发连接,能同时处理多个流的音频数据

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.27 07:50:31