uniapp小程序语音转文字功能实现与优化指南

一、uniapp语音转文字技术基础

在uniapp框架中实现语音转文字功能,需结合微信小程序原生API与uniapp的跨平台能力。核心实现依赖微信小程序的wx.getRecorderManager(录音管理)和wx.onVoiceProcessEnd(语音处理回调)接口,同时需处理不同平台(iOS/Android)的兼容性问题。

1.1 录音权限配置

manifest.json中需声明录音权限:

  1. {
  2. "mp-weixin": {
  3. "appid": "your_appid",
  4. "requiredPrivateInfos": ["getRecorderManager"]
  5. }
  6. }

iOS端需在project.config.json中添加"description"字段说明录音用途,否则可能被拒审。

1.2 核心API调用流程

  1. // 1. 创建录音管理器
  2. const recorderManager = uni.getRecorderManager();
  3. // 2. 配置录音参数
  4. const config = {
  5. format: 'mp3', // 推荐格式
  6. sampleRate: 16000, // 采样率影响识别精度
  7. numberOfChannels: 1,
  8. encodeBitRate: 96000,
  9. frameSize: 50 // 帧大小(ms)
  10. };
  11. // 3. 启动录音
  12. recorderManager.start(config);
  13. // 4. 监听录音完成
  14. recorderManager.onStop((res) => {
  15. const tempFilePath = res.tempFilePath;
  16. // 调用语音识别服务
  17. convertVoiceToText(tempFilePath);
  18. });

二、语音识别服务集成方案

uniapp本身不提供语音识别能力,需通过以下三种方式实现:

2.1 微信小程序原生识别(推荐)

微信提供wx.getFileSystemManager().readFile+后端API的组合方案:

  1. async function convertVoiceToText(filePath) {
  2. try {
  3. // 读取音频文件
  4. const fs = uni.getFileSystemManager();
  5. const fileData = await fs.readFile({
  6. filePath: filePath,
  7. encoding: 'base64'
  8. });
  9. // 调用微信语音识别接口(需后端配合)
  10. const result = await uni.request({
  11. url: 'https://your-server.com/api/asr',
  12. method: 'POST',
  13. data: {
  14. audio: fileData,
  15. format: 'mp3',
  16. rate: 16000
  17. }
  18. });
  19. return result.data.text;
  20. } catch (e) {
  21. console.error('识别失败:', e);
  22. }
  23. }

2.2 第三方SDK集成

以科大讯飞为例,需在pages.json中配置插件:

  1. {
  2. "plugins": {
  3. "iflytek-plugin": {
  4. "version": "1.0.0",
  5. "provider": "wxd......"
  6. }
  7. }
  8. }

调用示例:

  1. const plugin = requirePlugin('iflytek-plugin');
  2. plugin.recognize({
  3. engineType: 'cloud', // 云端识别
  4. language: 'zh_cn',
  5. onResult: (res) => {
  6. console.log('识别结果:', res.text);
  7. }
  8. });

2.3 自建识别服务

对于高并发场景,建议自建ASR服务:

  • 技术栈:Kaldi(开源)+ WebSocket
  • 部署方案
    • 容器化部署:Docker + Kubernetes
    • 负载均衡:Nginx配置
    • 音频预处理:FFmpeg转码

三、性能优化实战

3.1 实时性优化

  • 分片传输:将长音频切割为30s片段
    ```javascript
    let offset = 0;
    const chunkSize = 30 * 1000; // 30秒

function sendChunk(filePath) {
const fs = uni.getFileSystemManager();
fs.stat({
filePath: filePath,
success: (stat) => {
const duration = stat.size / (config.encodeBitRate/8);
while(offset < duration) {
const end = Math.min(offset + chunkSize, duration);
// 提取音频片段…
offset = end;
}
}
});
}

  1. #### 3.2 准确率提升
  2. - **噪声抑制**:使用WebRTCNS模块
  3. - **端点检测**:通过能量阈值判断有效语音
  4. ```javascript
  5. function detectSpeech(audioBuffer) {
  6. const frameSize = 256;
  7. const threshold = 0.3;
  8. let energy = 0;
  9. for(let i=0; i<audioBuffer.length; i+=frameSize) {
  10. const frame = audioBuffer.slice(i, i+frameSize);
  11. energy = frame.reduce((sum, val) => sum + Math.abs(val), 0) / frameSize;
  12. if(energy > threshold) return true;
  13. }
  14. return false;
  15. }

四、跨平台兼容处理

4.1 iOS特殊处理

  • 需在Info.plist中添加:
    1. <key>NSMicrophoneUsageDescription</key>
    2. <string>需要麦克风权限进行语音转文字</string>
  • 采样率限制:iOS仅支持8000/16000/44100Hz

4.2 Android兼容方案

  • 权限动态申请:
    1. uni.authorize({
    2. scope: 'scope.record',
    3. success: () => startRecord()
    4. });
  • 厂商差异处理:华为设备需额外配置audioSourceType

五、完整实现示例

  1. // pages/asr/asr.vue
  2. export default {
  3. data() {
  4. return {
  5. isRecording: false,
  6. resultText: ''
  7. };
  8. },
  9. methods: {
  10. startRecord() {
  11. this.isRecording = true;
  12. const recorder = uni.getRecorderManager();
  13. recorder.onStart(() => {
  14. console.log('录音开始');
  15. });
  16. recorder.onStop((res) => {
  17. this.isRecording = false;
  18. this.processAudio(res.tempFilePath);
  19. });
  20. recorder.start({
  21. format: 'mp3',
  22. sampleRate: 16000
  23. });
  24. },
  25. async processAudio(path) {
  26. try {
  27. const fs = uni.getFileSystemManager();
  28. const file = await fs.readFile({
  29. filePath: path,
  30. encoding: 'base64'
  31. });
  32. const res = await uni.request({
  33. url: 'https://api.example.com/asr',
  34. method: 'POST',
  35. data: {
  36. audio: file,
  37. format: 'base64'
  38. }
  39. });
  40. this.resultText = res.data.result;
  41. } catch (e) {
  42. uni.showToast({
  43. title: '识别失败',
  44. icon: 'none'
  45. });
  46. }
  47. }
  48. }
  49. };

六、常见问题解决方案

  1. 录音失败:检查权限配置,确保manifest.json中声明正确
  2. 识别延迟高:优化音频分片大小(建议20-30s/片)
  3. 准确率低
    • 增加语言模型适配
    • 添加行业术语词典
  4. 内存泄漏:及时释放RecorderManager实例
    1. // 正确释放方式
    2. onUnload() {
    3. if(this.recorder) {
    4. this.recorder.stop();
    5. this.recorder = null;
    6. }
    7. }

七、进阶功能扩展

  1. 实时显示识别结果:使用WebSocket实现流式识别
  2. 多语言支持:动态切换识别引擎语言参数
  3. 标点预测:通过NLP模型后处理
  4. 说话人分离:集成DIARIZATION算法

八、部署与监控

  1. 服务监控
    • 识别成功率统计
    • 平均响应时间(ART)
    • 错误率(Error Rate)
  2. 日志收集
    1. // 错误日志上报
    2. function reportError(e) {
    3. uni.request({
    4. url: 'https://api.example.com/log',
    5. method: 'POST',
    6. data: {
    7. error: JSON.stringify(e),
    8. timestamp: new Date().getTime()
    9. }
    10. });
    11. }

通过以上技术方案,开发者可在uniapp中构建稳定、高效的语音转文字功能。实际开发中需根据具体业务场景选择合适的技术路线,建议从微信原生API入手,逐步扩展至第三方服务或自建方案。对于高并发商业应用,推荐采用”客户端预处理+云端识别”的混合架构,既能保证识别质量,又能控制服务成本。