logo

UniApp语音输入全攻略:微信小程序与H5跨端实现指南

作者:沙与沫2025.10.10 19:01浏览量:1

简介:本文详细讲解如何在UniApp中实现语音输入功能,覆盖微信小程序和H5双端适配,提供从基础API调用到完整功能封装的完整解决方案。

一、语音输入技术选型与跨端适配原理

UniApp作为跨端开发框架,在语音输入实现上需同时考虑微信小程序和H5的技术差异。微信小程序端可使用wx.getRecorderManagerwx.startRecord等原生API,而H5端则依赖浏览器提供的Web Speech API中的SpeechRecognition接口。这种技术差异要求开发者采用条件编译和平台判断实现统一封装。

1.1 平台判断机制

通过uni.getSystemInfoSync().platform可获取当前运行平台,返回值为iosandroidmp-weixin等。在语音输入场景中,建议采用如下判断逻辑:

  1. const isMpWeixin = uni.getSystemInfoSync().platform === 'mp-weixin';
  2. const isH5 = uni.getSystemInfoSync().platform === 'h5';

1.2 跨端兼容策略

推荐采用适配器模式实现功能统一:

  • 基础层:分别实现小程序录音管理器和H5语音识别
  • 适配层:封装统一的方法调用接口
  • 应用层:通过配置参数控制不同平台行为

二、微信小程序端实现方案

2.1 录音管理器配置

微信小程序提供完整的录音生命周期管理:

  1. // 初始化录音管理器
  2. const recorderManager = uni.getRecorderManager();
  3. // 配置录音参数
  4. const recordOptions = {
  5. duration: 60000, // 最大录音时长(ms)
  6. sampleRate: 16000, // 采样率
  7. numberOfChannels: 1, // 单声道
  8. encodeBitRate: 96000, // 编码码率
  9. format: 'mp3', // 音频格式
  10. frameSize: 50 // 指定帧大小(KB)
  11. };
  12. // 事件监听
  13. recorderManager.onStart(() => {
  14. console.log('录音开始');
  15. });
  16. recorderManager.onStop((res) => {
  17. console.log('录音文件路径', res.tempFilePath);
  18. // 此处可调用语音转文字API
  19. });

2.2 语音转文字实现

需调用后端语音识别服务(如腾讯云、阿里云等),示例流程:

  1. 上传录音文件到服务器
  2. 调用语音识别API
  3. 返回识别结果
  1. async function transcribeSpeech(filePath) {
  2. try {
  3. const cloudRes = await uniCloud.uploadFile({
  4. filePath,
  5. cloudPath: `audio/${Date.now()}.mp3`
  6. });
  7. const recognizeRes = await uni.request({
  8. url: 'YOUR_ASR_API_ENDPOINT',
  9. method: 'POST',
  10. data: {
  11. audio_url: cloudRes.fileID
  12. }
  13. });
  14. return recognizeRes.data.result;
  15. } catch (e) {
  16. console.error('语音识别失败', e);
  17. return '';
  18. }
  19. }

三、H5端实现方案

3.1 Web Speech API使用

现代浏览器支持的语音识别API:

  1. // 创建识别器实例
  2. const recognition = new (window.SpeechRecognition ||
  3. window.webkitSpeechRecognition ||
  4. window.mozSpeechRecognition)();
  5. // 配置参数
  6. recognition.continuous = false; // 非连续识别
  7. recognition.interimResults = false; // 只要最终结果
  8. recognition.lang = 'zh-CN'; // 中文识别
  9. // 事件处理
  10. recognition.onresult = (event) => {
  11. const transcript = event.results[0][0].transcript;
  12. console.log('识别结果:', transcript);
  13. };
  14. recognition.onerror = (event) => {
  15. console.error('识别错误', event.error);
  16. };
  17. // 开始识别
  18. function startRecognition() {
  19. try {
  20. recognition.start();
  21. } catch (e) {
  22. uni.showToast({
  23. title: '浏览器不支持语音识别',
  24. icon: 'none'
  25. });
  26. }
  27. }

3.2 兼容性处理

针对不同浏览器的兼容方案:

  1. Chrome:完整支持
  2. Safari:需iOS 14+
  3. 微信内置浏览器:部分版本受限

建议添加用户提示:

  1. function checkBrowserSupport() {
  2. if (!window.SpeechRecognition &&
  3. !window.webkitSpeechRecognition &&
  4. !window.mozSpeechRecognition) {
  5. uni.showModal({
  6. title: '提示',
  7. content: '当前浏览器不支持语音输入,建议使用Chrome或Safari最新版',
  8. showCancel: false
  9. });
  10. return false;
  11. }
  12. return true;
  13. }

四、跨端组件封装实践

4.1 组件设计思路

  1. props设计

    • autoStart: 是否自动开始
    • maxDuration: 最大录音时长
    • language: 识别语言
  2. events设计

4.2 完整组件实现

  1. // components/voice-input/voice-input.vue
  2. export default {
  3. props: {
  4. autoStart: Boolean,
  5. maxDuration: {
  6. type: Number,
  7. default: 60000
  8. },
  9. language: {
  10. type: String,
  11. default: 'zh-CN'
  12. }
  13. },
  14. data() {
  15. return {
  16. isRecording: false,
  17. recorder: null,
  18. recognition: null
  19. };
  20. },
  21. mounted() {
  22. this.initPlatform();
  23. },
  24. methods: {
  25. initPlatform() {
  26. if (uni.getSystemInfoSync().platform === 'mp-weixin') {
  27. this.initWeixinRecorder();
  28. } else if (uni.getSystemInfoSync().platform === 'h5') {
  29. this.initH5Recognition();
  30. }
  31. },
  32. initWeixinRecorder() {
  33. this.recorder = uni.getRecorderManager();
  34. this.recorder.onStart(() => {
  35. this.isRecording = true;
  36. this.$emit('start');
  37. });
  38. this.recorder.onStop((res) => {
  39. this.isRecording = false;
  40. this.$emit('end', res.tempFilePath);
  41. // 此处可调用转文字方法
  42. });
  43. },
  44. initH5Recognition() {
  45. this.recognition = new (window.SpeechRecognition ||
  46. window.webkitSpeechRecognition)();
  47. this.recognition.continuous = false;
  48. this.recognition.lang = this.language;
  49. this.recognition.onresult = (event) => {
  50. const transcript = event.results[0][0].transcript;
  51. this.$emit('result', transcript);
  52. };
  53. this.recognition.onerror = (event) => {
  54. this.$emit('error', event.error);
  55. };
  56. },
  57. start() {
  58. if (this.isRecording) return;
  59. if (uni.getSystemInfoSync().platform === 'mp-weixin') {
  60. this.recorder.start({
  61. duration: this.maxDuration,
  62. format: 'mp3'
  63. });
  64. } else {
  65. try {
  66. this.recognition.start();
  67. this.$emit('start');
  68. } catch (e) {
  69. this.$emit('error', '浏览器不支持');
  70. }
  71. }
  72. },
  73. stop() {
  74. if (!this.isRecording) return;
  75. if (uni.getSystemInfoSync().platform === 'mp-weixin') {
  76. this.recorder.stop();
  77. } else {
  78. this.recognition.stop();
  79. this.$emit('end');
  80. }
  81. }
  82. }
  83. };

五、性能优化与最佳实践

5.1 录音参数调优

  • 采样率选择:16kHz适合语音识别,8kHz可节省存储
  • 码率控制:96kbps平衡音质与流量
  • 帧大小设置:50KB帧适合网络传输

5.2 错误处理机制

  1. 权限处理

    1. async function checkPermission() {
    2. if (uni.getSystemInfoSync().platform === 'mp-weixin') {
    3. const res = await uni.authorize({
    4. scope: 'scope.record'
    5. });
    6. if (res.errMsg !== 'authorize:ok') {
    7. uni.showModal({
    8. content: '需要录音权限',
    9. success: (res) => {
    10. if (res.confirm) {
    11. uni.openSetting();
    12. }
    13. }
    14. });
    15. }
    16. }
    17. }
  2. 超时控制

    1. let timer = null;
    2. function startRecording() {
    3. timer = setTimeout(() => {
    4. stopRecording();
    5. uni.showToast({ title: '录音超时', icon: 'none' });
    6. }, MAX_DURATION);
    7. // 实际录音开始代码...
    8. }

5.3 用户体验设计

  1. 视觉反馈

    • 录音时显示声波动画
    • 倒计时提示剩余时间
  2. 交互优化

    1. // 长按录音实现
    2. let pressTimer = null;
    3. methods: {
    4. handleTouchStart() {
    5. pressTimer = setTimeout(() => {
    6. this.startRecording();
    7. }, 300); // 300ms防误触
    8. },
    9. handleTouchEnd() {
    10. clearTimeout(pressTimer);
    11. this.stopRecording();
    12. }
    13. }

六、常见问题解决方案

6.1 微信小程序问题

  1. 真机调试无权限:需在微信公众平台配置录音权限
  2. 录音文件过大:降低采样率和码率
  3. iOS静音模式失效:需引导用户关闭静音

6.2 H5端问题

  1. Safari无法识别:检查iOS版本是否≥14
  2. 中文识别不准:设置正确的lang参数
  3. 多次调用失效:每次使用前需重新创建识别器

6.3 跨端一致性问题

  1. 结果返回时机差异:小程序在onStop后返回,H5实时返回
  2. 中断处理差异:小程序需监听onInterruptionBegin,H5需监听onend事件

七、进阶功能扩展

7.1 语音指令识别

通过关键词匹配实现简单指令:

  1. function checkCommand(transcript) {
  2. const commands = ['拍照', '返回', '搜索'];
  3. return commands.some(cmd => transcript.includes(cmd));
  4. }

7.2 实时语音转写

使用WebSocket实现流式识别:

  1. async function startStreamRecognition() {
  2. const socket = new WebSocket('wss://asr-api/stream');
  3. socket.onmessage = (event) => {
  4. const data = JSON.parse(event.data);
  5. this.partialResult = data.result;
  6. };
  7. // 通过MediaRecorder获取音频流并发送
  8. }

7.3 多语言支持

动态切换识别语言:

  1. methods: {
  2. changeLanguage(lang) {
  3. if (uni.getSystemInfoSync().platform === 'h5') {
  4. this.recognition.lang = lang;
  5. }
  6. // 小程序端需重新初始化录音管理器
  7. }
  8. }

八、部署与测试要点

8.1 微信小程序配置

  1. app.json中声明录音权限:

    1. {
    2. "permission": {
    3. "scope.record": {
    4. "desc": "需要录音权限"
    5. }
    6. }
    7. }
  2. 域名白名单配置:

    • 语音识别API域名需加入request合法域名
    • WebSocket接口需加入uploadFile合法域名

8.2 H5端配置

  1. HTTPS要求:语音识别API必须使用HTTPS
  2. 浏览器特征检测
    1. const isSupported = 'SpeechRecognition' in window ||
    2. 'webkitSpeechRecognition' in window ||
    3. 'mozSpeechRecognition' in window;

8.3 测试用例设计

  1. 功能测试

    • 正常录音流程
    • 权限拒绝场景
    • 超时中断测试
  2. 兼容性测试

    • 微信不同版本
    • Chrome/Firefox/Safari
    • Android/iOS不同系统版本
  3. 性能测试

    • 长时间录音稳定性
    • 大文件上传测试
    • 弱网环境测试

通过本文的完整方案,开发者可以快速实现UniApp跨端语音输入功能。实际开发中建议先完成基础功能,再逐步添加错误处理和性能优化。对于商业项目,可考虑集成成熟的语音识别SDK以获得更稳定的识别效果和更高的准确率。

相关文章推荐

发表评论

活动