uniapp vue3项目用原生h5 audioContext实现语音文件倍速播放,可适应h5和安卓app

前言

uniapp项目要做类似微信的聊天语音播放功能,可以切换语音,可以点击切换播放/停止播放状态,还可以倍速播放。开始用了uniapp的音频组件uni.createInnerAudioContext(),很好用但就是倍速播放playbackRate属性不起作用,经过研究,决定用原生h5的audioContext。

AudioContext是Web Audio API的一部分,它代表了一个音频处理图,允许开发者在网页上对音频进行精细的控制和处理。通过AudioContext,开发者可以创建和管理多个音频节点(AudioNode),这些节点通过输入输出相互连接,形成一个音频处理流程图。AudioContext控制其所包含节点的创建和音频处理、解码等操作‌。
效果图:
uniapp vue3项目用原生h5 audioContext实现语音文件倍速播放,可适应h5和安卓app_第1张图片

开始

1、通过后端返回的语音url,得到arrayBuffer对象

function getAudioArraybuffer(url){
		return new Promise((resolve,reject)=>{
			let xhr = new XMLHttpRequest(); // 创建XMLHttpRequest对象
			xhr.open('GET', url, true); // 打开HTTP请求
			xhr.responseType = "arraybuffer";
			xhr.send(); // 发送请求
			xhr.onload = function() {
				console.log(xhr)
			 if (xhr.status === 200) {
				const arrayBuffer = xhr.response;
					if (arrayBuffer) {
						resolve(arrayBuffer)
					}
			 } else {
			   uni.showToast({
				title: '音频转换失败',
				icon: 'error',
				duration: 1000
			   });
			   reject('音频转换失败')
			 }
			}
		})
	}

2、播放

let audioContext = null;
let source = null;
function play(param){ // 点击播放语音,并带过来语音参数
			if(audioContext && source){
				// 点击另一条语音,当前有其他语音在播放,停止播放此语音
				source.stop();
				source = null;
				audioContext = null;
			}
			audioPlay(param) // 播放当前语音
	}
async function audioPlay(param){
	    audioContext = new (window.AudioContext || window.webkitAudioContext)();
		source = audioContext.createBufferSource();
		let arrayBuffer = await getAudioArraybuffer(param.url)
		audioContext.decodeAudioData(arrayBuffer).then(audioBuffer => {
		  source.buffer = audioBuffer;
		  source.playbackRate.setValueAtTime(2, audioContext.currentTime); // 设置倍速为2倍速播放
		  source.connect(audioContext.destination);
		  source.onended=(res) => { // 监听播放结束
		  	console.log('自播放结束:', res);				
		  	// 在这里可以更改播放状态切换时的ui,比如小喇叭由动到静
		  		
		  };
		  source.start();
}

3、停止播放

function stopPlay(){ // 点击停止播放
		source.stop();
		source = null;
		audioContext = null;
	}

4、如果当前页面正在播放语音,在切换页面的时候,应该停止播放语音

onHide(()=>{
		if(audioContext){
			stopPlay()
		}
	})
	onUnload(()=>{
		clearInterval(timer)
		if(audioContext){
			stopPlay()
		}
	})

5、需要注意的是,audioContext的创建不能写在全局会报错,这是因为浏览器的自动播放策略是,必须是用户手动触发了事件之后,才能自动播放。所以需要写在点击事件里面。

后记

经过测试,此种方法h5和安卓app可用,其他端未测试。这个uniapp vue3框架下的倍速播放解决用了一段时间,在此记录这个问题的解决方法,并能提供一些思路给正在有此困扰的朋友。有任何问题可以留言一起讨论。

你可能感兴趣的:(uni-app,android,音频倍速播放)