Skip to content

语音转写

MootingAPP 的实时语音转写功能说明。

技术方案

使用腾讯云 ASR (Automatic Speech Recognition) 服务:

┌─────────────────────────────────────────────────────────────┐
│                      语音转写流程                            │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  麦克风 ──→ PCM 音频 ──→ WebSocket ──→ 腾讯云 ASR          │
│                                              │              │
│                                              ▼              │
│                                         转写结果            │
│                                              │              │
│                                              ▼              │
│                                         显示字幕            │
│                                                             │
└─────────────────────────────────────────────────────────────┘

WebSocket 连接

腾讯云 ASR 配置

javascript
// services/tencentCloud.js
import CryptoJS from 'crypto-js';

const config = {
  SecretId: 'your-secret-id',
  SecretKey: 'your-secret-key',
  AppId: 'your-app-id',
};

export const getAsrWebSocketUrl = (voiceId) => {
  const timestamp = Math.floor(Date.now() / 1000);
  const expireTime = timestamp + 86400; // 24小时

  const params = {
    secretid: config.SecretId,
    timestamp,
    expired: expireTime,
    nonce: Math.floor(Math.random() * 100000),
    engine_model_type: '16k_zh',
    voice_id: voiceId,
    voice_format: 1, // PCM
  };

  // 生成签名
  const queryString = Object.entries(params)
    .map(([k, v]) => `${k}=${v}`)
    .join('&');

  const signature = CryptoJS.HmacSHA1(queryString, config.SecretKey);
  const signatureBase64 = CryptoJS.enc.Base64.stringify(signature);

  return `wss://asr.cloud.tencent.com/asr/v2/${config.AppId}?${queryString}&signature=${encodeURIComponent(signatureBase64)}`;
};

RecordingScreen 实现

jsx
const RecordingScreen = () => {
  const [transcripts, setTranscripts] = useState([]);
  const [activeText, setActiveText] = useState('');
  const wsRef = useRef(null);

  useEffect(() => {
    // 建立 WebSocket 连接
    const wsUrl = getAsrWebSocketUrl(Date.now().toString());
    wsRef.current = new WebSocket(wsUrl);

    wsRef.current.onopen = () => {
      console.log('ASR WebSocket connected');
    };

    wsRef.current.onmessage = (event) => {
      const data = JSON.parse(event.data);
      handleAsrResult(data);
    };

    return () => {
      wsRef.current?.close();
    };
  }, []);

  const handleAsrResult = (data) => {
    if (data.result) {
      if (data.result.slice_type === 2) {
        // 最终结果
        setTranscripts((prev) => [
          ...prev,
          { id: Date.now(), text: data.result.voice_text_str },
        ]);
        setActiveText('');
      } else {
        // 中间结果
        setActiveText(data.result.voice_text_str);
      }
    }
  };

  return (
    <View>
      <FlatList
        data={transcripts}
        renderItem={({ item }) => <Text>{item.text}</Text>}
      />
      {activeText && (
        <Text style={{ color: 'gray' }}>{activeText}</Text>
      )}
    </View>
  );
};

音频格式

参数
格式PCM
采样率16000 Hz
位深16 bit
声道单声道

支持的语言

引擎模型语言
16k_zh中文普通话
16k_en英语
16k_zh_en中英混合
16k_ja日语
16k_ko韩语

安全注意

WARNING

腾讯云密钥不应硬编码在客户端代码中。生产环境应:

  1. 通过后端 API 获取临时凭证
  2. 使用腾讯云 STS 临时密钥
  3. 设置密钥过期时间

Mooting 开发者文档