简介:本文详解uniapp框架下实现微信小程序与H5双端语音输入功能的完整方案,涵盖API调用、平台差异处理、性能优化等核心要点,提供可直接复用的代码示例与调试技巧。
微信小程序原生提供wx.getRecorderManager()和wx.startRecord()两种录音方案,前者支持更精细的音频控制(采样率、码率、声道数),后者为兼容旧版API的过渡方案。开发者需注意:
app.json中声明record权限H5端语音输入依赖浏览器原生API组合:
navigator.mediaDevices.getUserMedia({audio:true})获取麦克风权限Web Audio API或MediaRecorder API处理音频流采用条件编译+平台判断的组合方案:
// 平台判断工具函数function isWeixinMiniProgram() {return typeof wx !== 'undefined' && wx.getRecorderManager}function isH5() {return process.env.VUE_APP_PLATFORM === 'h5'}
// 录音管理器初始化const recorderManager = wx.getRecorderManager()const options = {format: 'aac',sampleRate: 16000,numberOfChannels: 1,encodeBitRate: 96000}// 录音开始function startRecord() {recorderManager.start(options)recorderManager.onStart(() => {console.log('录音开始')})recorderManager.onError((err) => {console.error('录音错误', err)})}// 录音结束处理function stopRecord() {recorderManager.stop()recorderManager.onStop((res) => {const tempFilePath = res.tempFilePath// 上传或处理音频文件uploadAudio(tempFilePath)})}
// 媒体设备获取async function initMediaRecorder() {try {const stream = await navigator.mediaDevices.getUserMedia({ audio: true })const mediaRecorder = new MediaRecorder(stream, {mimeType: 'audio/webm',audioBitsPerSecond: 96000})let audioChunks = []mediaRecorder.ondataavailable = (event) => {audioChunks.push(event.data)}mediaRecorder.onstop = async () => {const audioBlob = new Blob(audioChunks, { type: 'audio/webm' })const audioUrl = URL.createObjectURL(audioBlob)// 处理音频数据processAudio(audioBlob)}return { mediaRecorder, stream }} catch (err) {console.error('媒体设备获取失败', err)}}// 录音控制let recorderInstance = nulllet audioStream = nullfunction startH5Record() {initMediaRecorder().then(({ mediaRecorder, stream }) => {recorderInstance = mediaRecorderaudioStream = streammediaRecorder.start(1000) // 每1秒收集一次数据})}function stopH5Record() {if (recorderInstance) {recorderInstance.stop()audioStream.getTracks().forEach(track => track.stop())}}
// 语音服务封装const VoiceService = {start() {if (isWeixinMiniProgram()) {startRecord()} else if (isH5()) {startH5Record()}},stop() {if (isWeixinMiniProgram()) {stopRecord()} else if (isH5()) {stopH5Record()}},// 其他统一方法...}
推荐使用ffmpeg.js在H5端进行格式转换:
async function convertAudioFormat(blob, targetFormat = 'mp3') {const worker = new Worker('/ffmpeg-worker.js')worker.postMessage({type: 'transcode',arguments: ['-i', 'input.webm', '-f', targetFormat, 'output.' + targetFormat],files: [{data: blob,name: 'input.webm'}]})return new Promise((resolve) => {worker.onmessage = (e) => {const { data } = eif (data.type === 'done') {const convertedBlob = data.files[0].dataresolve(convertedBlob)}}})}
wx.downloadFile预加载录音配置文件enableAgc和enableNoiseSuppression提升音质AudioContext进行实时音频处理实现录音音量可视化反馈
// 音量检测示例function setupVolumeMeter(stream) {const audioContext = new AudioContext()const analyser = audioContext.createAnalyser()const source = audioContext.createMediaStreamSource(stream)source.connect(analyser)analyser.fftSize = 32const bufferLength = analyser.frequencyBinCountconst dataArray = new Uint8Array(bufferLength)function draw() {requestAnimationFrame(draw)analyser.getByteFrequencyData(dataArray)const volume = Math.max(...dataArray)// 更新UI显示音量updateVolumeMeter(volume)}draw()}
uni.getSystemInfo()获取设备信息辅助调试
/plugins/voice-recorderindex.js # 主入口文件weixin.js # 微信实现h5.js # H5实现utils.js # 工具函数/components/voice-inputvoice-input.vue # 封装组件/staticffmpeg-worker.js # 格式转换worker
微信小程序录音权限被拒:
app.json权限声明H5端Safari无法录音:
音频上传失败:
lamejs)多端音量不一致:
通过以上方案,开发者可以在uniapp框架下高效实现跨平台的语音输入功能,兼顾微信小程序和H5端的用户体验。实际开发中需根据具体业务需求调整录音参数和错误处理策略,建议通过AB测试确定最优配置。