vue2录音插件可实时监控音量大小(H5和PC端都可使用)

直接上源码,注意由于浏览器权限问题,只可在HTTPS下录音

一、封装录音插件

<template>
	<div class="recorder">
	</div>
</template>

<script>
	export default {
		data() {
			return {
				isUserMedia: false,
				stream: null,
				audio: null,
				recorder: null,
				chunks: [],
				startTime: 0,
				isRecord: false, //是否在录音
				volume: 0, //当前音量
			}
		},
		mounted() {
			/**
			 * 	error 事件的返回状态
			 * 	100: 请在HTTPS环境中使用
			 * 	101: 浏览器不支持
			 *  201: 用户拒绝授权
			 *  500: 未知错误
			 * */
			if (origin.indexOf('https') === -1) {
				this.$emit('error', '100')
				throw '请在 https 环境中使用本插件。'
			}
			if (!navigator.mediaDevices || !window.MediaRecorder) {
				this.$emit('error', '101')
				throw '当前浏览器不支持'
			}

			this.getRecorderManager()
		},
		methods: {
			getRecorderManager() {
				this.audio = document.createElement('audio')
				navigator.mediaDevices.getUserMedia({
					audio: true
				}).then(stream => {
					this.isUserMedia = true
					stream.getTracks().forEach((track) => {
						track.stop()
					})
				}).catch(err => {
					this.onErrorHandler(err)
				})
			},
			start() {
				if (!this.isUserMedia) return console.log('设备不支持')
				navigator.mediaDevices.getUserMedia({
					audio: true
				}).then(stream => {
					this.isRecord = true
					this.beginDetect(stream)
					console.log(stream, '52');
					this.startTime = new Date().getTime()
					this.stream = stream
					this.recorder = new MediaRecorder(stream)

					this.recorder.ondataavailable = this.getRecordingData
					this.recorder.onstop = this.saveRecordingData
					this.recorder.start()
				}).catch(err => {
					this.onErrorHandler(err)
				})
			},
			// 麦克风音量检测
			beginDetect(stream) {
				let audioContext = new(window.AudioContext || window.webkitAudioContext)()
				let mediaStreamSource = null
				let scriptProcessor = null
				if (navigator.mediaDevices && navigator.mediaDevices.getUserMedia) {
					// 将麦克风的声音输入这个对象
					mediaStreamSource = audioContext.createMediaStreamSource(stream)
					// 创建一个音频分析对象,采样的缓冲区大小为4096,输入和输出都是单声道
					scriptProcessor = audioContext.createScriptProcessor(4096, 1, 1)
					// 将该分析对象与麦克风音频进行连接
					mediaStreamSource.connect(scriptProcessor)
					// 此举无甚效果,仅仅是因为解决 Chrome 自身的 bug
					scriptProcessor.connect(audioContext.destination)
					// 开始处理音频
					scriptProcessor.onaudioprocess = (e) => {
						// 获得缓冲区的输入音频,转换为包含了PCM通道数据的32位浮点数组
						let buffer = e.inputBuffer.getChannelData(0)
						// 获取缓冲区中最大的音量值
						let maxVal = Math.max.apply(Math, buffer)
						// 显示音量值
						if (this.isRecord) {
							this.$emit('getVolume', Math.round(maxVal * 10))
						};
					}
				} else {
					console.log('不支持获取媒体接口');
				}
			},
			stop() {
				this.recorder.stop()
				this.stream.getTracks().forEach((track) => {
					console.log(track, '66');
					track.stop()
				})
			},
			getRecordingData(e) {
				console.log(e, '71');
				this.chunks.push(e.data)
			},
			saveRecordingData() {
				const blob = new Blob(this.chunks, {
						'type': 'audio/mpeg'
					}),
					localUrl = URL.createObjectURL(blob)
				const endTime = new Date().getTime()
				let duration = (endTime - this.startTime).toString().split('')
				duration.splice(duration.length - 2)
				duration.splice(duration.length - 1, 0, '.')
				duration = parseFloat(duration.join(''))
				const recorder = {
					data: blob,
					duration: duration,
					localUrl: localUrl
				}
				this.$emit('success', recorder)
				this.isRecord = false
			},
			onErrorHandler(err) {
				console.log(err)
				if (err.name === 'NotAllowedError') {
					this.$emit('error', '201')
					// throw '用户拒绝了当前的浏览器实例的访问请求'
				}

				if (err.name === 'NotReadableError') {
					this.$emit('error', '101')
					// throw '当前浏览器不支持'
				}

				this.$emit('error', '500')
				// throw '调用失败,原因不详'

			}
		},
		destroyed() {
			this.stop()
		}
	}
</script>
<style>
</style>

二、调用插件

<template>
	<!-- HTML -->
	<div>
		<audio :src='recorder.localUrl' v-if='recorder' name='本地录音' controls="true"></audio>
		<button @click='handlerOnCahnger'>{{!status?'开始录音':'结束录音'}}</button>
		当前音量:{{volume}}
		<mumu-recorder ref='recorder' @success='handlerSuccess' @error='handlerError' @getVolume="getVolume"></mumu-recorder>
	</div>
</template>

<script>
	import MumuRecorder from '@/uni_modules/recorder/components/mumu-recorder/mumu-recorder.vue'
	export default {
		components: {
			MumuRecorder
		},
		data() {
			return {
				status: false,
				recorder: null,
				volume:0,//实时音量大小
			}
		},
		onLoad() {

		},
		methods: {
			getVolume(volume){//获取实时音量大小
				this.volume = volume
			},
			handlerSave() {
				let tag = document.createElement('a')
				tag.href = this.recorder.localUrl
				tag.download = '录音'
				tag.click()
			},
			handlerOnCahnger() {
				if (this.status) {
					this.$refs.recorder.stop()
				} else {
					this.$refs.recorder.start()
				}
				this.status = !this.status
			},
			handlerSuccess(res) {//返回的音频
				this.recorder = res
				console.log(res, '48');
			},
			handlerError(code) {
				switch (code) {
					case '101':
						uni.showModal({
							content: '当前浏览器版本较低,请更换浏览器使用,推荐在微信中打开。'
						})
						break;
					case '201':
						uni.showModal({
							content: '麦克风权限被拒绝,请刷新页面后授权麦克风权限。'
						})
						break
					default:
						uni.showModal({
							content: '未知错误,请刷新页面重试'
						})
						break
				}
			}
		}
	}
</script>

<style lang="less">

</style>

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

前端程序猿i

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值