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

Flutter集成Azure Speech-to-Text WebSocket连续语音识别方法咨询

Flutter集成Azure Speech-to-Text WebSocket连续识别方案

一、正确的WebSocket连接配置

Azure Speech-to-Text的WebSocket端点和参数有严格要求,你之前尝试的URL格式存在问题,正确配置如下:

  • 端点URL:基于你的服务区域,格式为 wss://<region>.stt.speech.microsoft.com/speech/recognition/conversation/cognitiveservices/v1,比如wss://eastus.stt.speech.microsoft.com/...
  • 必填参数:URL需携带language参数(如zh-CN),无需在URL中传subscription-key,改用Bearer Token认证更安全
  • 认证方式:先调用token接口获取有效期10分钟的Bearer Token,接口地址为https://<region>.api.cognitive.microsoft.com/sts/v1.0/issueToken,POST请求头部携带Ocp-Apim-Subscription-Key: <你的订阅密钥>,返回的响应体即为Token
  • 请求头:建立WebSocket连接时必须携带两个头部:
    • Authorization: Bearer <获取到的Token>
    • Content-Type: audio/wav; codecs=audio/pcm; samplerate=16000(需与实际音频格式匹配,推荐16kHz、16位、单声道PCM)

二、Flutter中实现WebSocket连接与识别流程

Flutter无官方Azure Speech SDK,需手动基于WebSocket客户端实现,推荐使用web_socket_channel包简化操作,核心步骤如下:

1. 获取Bearer Token

import 'package:http/http.dart' as http;

Future<String> getAzureSpeechToken(String subscriptionKey, String region) async {
  final tokenUrl = Uri.parse('https://$region.api.cognitive.microsoft.com/sts/v1.0/issueToken');
  final response = await http.post(
    tokenUrl,
    headers: {'Ocp-Apim-Subscription-Key': subscriptionKey},
  );
  if (response.statusCode == 200) {
    return response.body;
  }
  throw Exception('Token获取失败,状态码: ${response.statusCode}');
}

2. 建立WebSocket连接并处理识别结果

import 'package:web_socket_channel/web_socket_channel.dart';
import 'dart:convert';

void initSpeechRecognition(String token, String region, String language) async {
  final wsUrl = Uri.parse(
    'wss://$region.stt.speech.microsoft.com/speech/recognition/conversation/cognitiveservices/v1?language=$language'
  );
  final channel = IOWebSocketChannel.connect(
    wsUrl,
    headers: {
      'Authorization': 'Bearer $token',
      'Content-Type': 'audio/wav; codecs=audio/pcm; samplerate=16000',
    },
  );

  // 监听识别结果
  channel.stream.listen((message) {
    final resultJson = jsonDecode(message);
    final status = resultJson['RecognitionStatus'];
    final text = resultJson['DisplayText'];
    
    switch (status) {
      case 'Interim':
        print('临时识别文本: $text');
        break;
      case 'Success':
        print('最终识别文本: $text');
        break;
      case 'NoMatch':
        print('未检测到有效语音');
        break;
      case 'Error':
        print('识别错误: ${resultJson['ErrorMessage']}');
        break;
    }
  }, onError: (error) {
    print('WebSocket连接错误: $error');
  }, onDone: () {
    print('WebSocket连接已关闭');
  });

  // 后续需添加音频采集与发送逻辑
  // startAudioCaptureAndSend(channel);
}

3. 音频采集与分块发送

使用flutter_sound或audio_recorder包采集符合要求的PCM音频,分块发送(推荐每20ms发送一次,对应640字节的16kHz/16位单声道数据):

void sendAudioChunk(IOWebSocketChannel channel, List<int> pcmChunk) {
  channel.sink.add(pcmChunk);
}

// 示例:从音频流中拆分块发送
void splitAndSendAudio(IOWebSocketChannel channel, List<int> fullPcmData) {
  const chunkSize = 640; // 20ms音频数据量
  for (int i = 0; i < fullPcmData.length; i += chunkSize) {
    final end = i + chunkSize < fullPcmData.length ? i + chunkSize : fullPcmData.length;
    sendAudioChunk(channel, fullPcmData.sublist(i, end));
  }
}

三、关键注意事项

  • 音频格式必须严格匹配:Azure仅支持指定格式的音频,若格式不匹配会直接导致识别失败
  • 处理连接重连:WebSocket连接可能因超时或网络问题断开,需监听连接关闭事件,重新获取Token并建立连接
  • 错误处理:及时捕获并处理认证失败、音频格式错误等返回信息,优化用户体验

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 13:01:11