uniapp使用音频录音功能

录音功能

主要根据uniapp官网提供的uni.getRecorderManager() API来实现路由功能,官网地址:https://uniapp.dcloud.net.cn/api/media/record-manager.html

注意:uniapp提供的uni.getRecorderManager()在h5上面不支持,如果h5想实现录音功能使用navigator.mediaDevices.getUserMedia({ audio: true })API来实现

使用全局管理状态管理录音功能

uniapp就支持全局状态管理功能只要文件下创建store文件

index.js

javascript 复制代码
import { createStore } from 'vuex'

import audio from './modules/audio'
import user from './modules/user'

const store = createStore({
	modules: {
		audio,
		user
	}
})

export default store

audio.js文件

javascript 复制代码
export default {
	state: {
		// 存放全局事件
		events: [],
		// 录音管理器
		RECORD: null,
		RecordTime: 0,
		RECORDTIMER: null,
		sendVoice: null
	},
	mutations: {
		initRECORD(state) {
			state.RECORD = uni.getRecorderManager()
			
			// 监听录音开始
			state.RECORD.onStart(() => {
				state.RecordTime = 0
				state.RECORDTIMER = setInterval(() => {
					state.RecordTime++
				}, 1000)
			})
			
			// 监听录音结束
			state.RECORD.onStop(e => {
				if(state.RECORDTIMER) {
					clearInterval(state.RECORDTIMER)
					state.RECORDTIMER = null
				}
				// 执行发送
				if(typeof state.sendVoice === 'function') {
					state.sendVoice(e.tempFilePath)
				}
			})
		},
		// 注册发送音频事件
		regSendVoiceEvent(state, event) {
			state.sendVoice = event
		},
		// 注册全局事件
		regEvent(state, event) {
			state.events.push(event)
		},
		// 执行全局事件
		doEvent(state, params) {
			state.events.forEach(e => {
				e(params)
			})
		},
		// 注销事件
		removeEvent(state, event) {
			let index = state.events.findIndex(item => {
				return item === event
			})
			if(index !== -1) {
				state.events.splice(index, 1)
			}
		}
	},
	actions: {
		// 分发注册全局时间
		$onAudio({ commit }, event) {
			commit('regEvent', event)
		},
		// 分发执行全局事件
		$emitAduio({commit}, params) {
			commit('doEvent', params)
		},
		//  分发注销全局事件
		$offAudio({commit}, event) {
			commit('removeEvent', event)
		}
	}
}

App.vue文件初始化录音功能initRECORD方法

javascript 复制代码
import store from './store';
export default {
  onLaunch() {
    // 初始化录音管理器
    store.commit('initRECORD')
  }
}

点击录音按钮进行录音

  • 页面按钮
javascript 复制代码
<view v-if="mode === 'audio'" class="rounded flex align-center justify-center" 
  :class="isRecording ? 'bg-hover-light':'bg-white'"
  style="height: 80rpx;" 
  @touchstart="voiceTouchStart" 
  @touchend="voiceTouchEnd"
  @touchcancel="voiceTouchCancel"
  @touchmove="voiceTouchMove"
>
	<text class="font">{{ isRecording ? '松开 结束' : '按住 说话' }}</text>
</view>
  • 逻辑
javascript 复制代码
import { mapState, mapMutations } from 'vuex'
export default {
  data() {
    return {
        // 音频录制状态
		  isRecording: false,
		  // 取消录音
		  unRecord: false,
    }
  },
  computed: {
    ...mapState({
      RECORD: state => state.audio.RECORD
    })
  },
  methods: {
		// 录音相关
		voiceTouchStart(e) {
			this.isRecording = true
			this.recordingStartY = e.changedTouches[0].clientY
			this.unRecord = false
			// 开始录音
			this.RECORD.start({
				format: 'mp3'
			})
		},
		// 录音结束
		voiceTouchEnd() {
			this.isRecording = false
			// 停止录音
			this.RECORD.stop()
		},
		// 录音被打断
		voiceTouchCancel() {
			this.isRecording = false
			this.unRecord = true
			// 停止录音
			this.RECORD.stop()
		},
		voiceTouchMove(e) {
			let Y = Math.abs(e.changedTouches[0].clientY - this.recordingStartY)
			this.unRecord = (Y >= 50)
		},
  }
}

播放音频功能

javascript 复制代码
  <view v-else-if="item.type === 'audio'" class="flex align-center" @click="openAudio">
		  <image v-if="isself" :src="!audioPlaying ? '/static/audio/audio3.png':'/static/audio/play.gif'" style="width: 50rpx;height: 50rpx;" 
		  class="mx-1"></image>
		  <text class="font">{{item.options.time}}</text>
		  <image v-if="!isself" :src="!audioPlaying ? '/static/audio/audio3.png':'/static/audio/play.gif'" style="width: 50rpx;height: 50rpx;"
		  class="mx-1"></image>
	  </view>
javascript 复制代码
import { mapState, mapActions } from 'vuex'
export default {
  data() {
    return {
      innerAudioContext: null,
    }
  },
	mounted() {
		// 注册全局事件
		if(this.item.type === 'audio') {
			this.$onAudio(this.onPlayAudio)
		}
	},
  methods: {
    ...mapActions(['$onAudio', '$emitAduio', '$offAudio']),
    	// 播放音频
		openAudio() {
			// 通知其他音频
			this.$emitAduio(this.index)
			if(!this.innerAudioContext) {
				this.innerAudioContext = uni.createInnerAudioContext()
				this.innerAudioContext.src = this.item.data
				this.innerAudioContext.play()
				
				// 监听播放
				this.innerAudioContext.onPlay(() => {
					this.audioPlaying = true
				})
				// 监听暂停
				this.innerAudioContext.onPause(() => {
					this.audioPlaying = false
				})
				// 监听停止
				this.innerAudioContext.onStop(() => {
					this.audioPlaying = false
				})
				// 监听错误
				this.innerAudioContext.onError(() => {
					this.audioPlaying = false
				})
			} else {
				this.innerAudioContext.stop()
				this.innerAudioContext.play()
			}
		},
		// 监听音频全局事件
		onPlayAudio(index) {
			if(this.innerAudioContext) {
				if(this.index !== index) {
					this.innerAudioContext.pause()
				}
			}
		},
		// 关闭音频
		closeAudio() {
			if(this.item.type === 'audio') {
				this.$offAudio(this.onPlayAudio)
			}
			// 销毁音频
			if(this.innerAudioContext) {
				this.innerAudioContext.destroy()
				this.innerAudioContext = null
			}
		},
  }
}

H5录音功能

javascript 复制代码
// H5 录音示例
let mediaRecorder;
let audioChunks = [];

// 开始录音
export const startRecord = () => {
  navigator.mediaDevices.getUserMedia({ audio: true })
    .then(stream => {
      mediaRecorder = new MediaRecorder(stream);
      audioChunks = [];
      mediaRecorder.addEventListener("dataavailable", event => {
        audioChunks.push(event.data);
      });
      mediaRecorder.start();
    })
    .catch(error => {
      console.error("无法访问麦克风:", error);
    });
}

// 停止录音
export const stopRecord = () => {
  return new Promise(resolve => {
    mediaRecorder.stop();
    mediaRecorder.addEventListener("stop", () => {
      const audioBlob = new Blob(audioChunks, { type: "audio/wav" });
      const audioUrl = URL.createObjectURL(audioBlob);
      resolve(audioUrl); // 返回录音的临时 URL
    });
  });
}
相关推荐
ai产品老杨8 小时前
NVIDIA GPU部署AI视频分析项目实战记录
人工智能·音视频
霸道流氓气质15 小时前
Kiro 中反编译 JAR 包并分析字节码的流程指南
chrome·python·jar
REDcker16 小时前
远程实时操控技术详解
音视频·实时音视频·数据采集·遥控·遥操作·数据闭环·远程操控
AI_Video_Editing17 小时前
长视频转短视频应用怎么选:从成本公式、处理链路到场景适配的判断逻辑
音视频
耍酷的魔镜17 小时前
用虚拟机实际体验Google Chromium OS (Chrome OS) Pre-Built
前端·chrome
莫生灬灬18 小时前
DY联系人聊天Web面板支持获取联系人/聊天记录/发送消息
前端·chrome·websocket·c#
气泡音人声分离18 小时前
技术解析|音频可视化:从波形图到声谱图,把“听觉”变成“视觉”
音视频·音频剪辑·音频可视化
阿拉斯攀登19 小时前
售货柜实战:IPC 拉流 → 抽帧 → YOLO 识别完整流水线
yolo·ffmpeg·音视频·webrtc·视频编解码
2501_9159090619 小时前
IPA 深度混淆是什么意思?从混淆强度到实际效果的解读
android·ios·小程序·https·uni-app·iphone·webview
Auv开心19 小时前
Ubuntu 20.04 默认视频播放器(Totem)无法播放 MP4 文件,通常是因为缺少多媒体编解码器。以下是几种解决方法:
linux·ubuntu·音视频