arrayBuffer转audioBuffer实现播放和控制音量

5,553 阅读2分钟

搜索了很久文章,感觉网上很多将audioBuffer实现播放和可视化混在一起
如果只是实现简单的播放那未免太过复杂,audio相关的api又过多很容易搞不清楚

遇到的场景

我们通过ajax的方法,从路径或者后台获取
也可以input的flie中FileReader解析mp3文件获取

哪些是arrayBuffer
  • FileReader获取arrayBuffer
var file = this.files[0];
var fr = new FileReader();

fr.onload = function(e){
	// 这边e.target.result已经是arraybuffer对象类型
	console.log(e.target.result);
}
  • ajax方法获取

ajax获取路径时,需要标识responseType

axios({
	method: 'get',
	url: 'assets/music/test.mp3',
	responseType: 'arraybuffer'
}).then((res) => {
    console.log(res.data) //这个是arraybuffer
})
arrayBuffer转为audioBuffer

通过AudioContext对象方法

const audioContext = new AudioContext();
const audioSource = audioContext.createBufferSource()

audioContext.decodeAudioData(arrayBuffer, (buffer) => {
	audioSource.buffer = buffer;
	audioSource.connect(audioContext.destination);
})
实现播放音频
// 控制播放等操作
const audioSource = audioContext.createBufferSource()

audioContext.decodeAudioData(arrayBuffer, (buffer) => {
	audioSource.buffer = buffer;
	audioSource.connect(audioContext.destination);
	// 播放音乐
	audioSource.start()
})
实现音频时转换过程

image

实现控制音量
const audioContext = new AudioContext();
// 控制音量
const gainNode = audioContext.createGain();
// 控制音频
const audioSource = audioContext.createBufferSource()

audioContext.decodeAudioData(arrayBuffer, (buffer) => {
	audioSource.buffer = buffer;
	// 设置音量为0.5
	gainNode.gain.value = 0.5
	gainNode.connect(audioContext.destination);
	// 播放
	audioSource.start()
})

额外补充

AudioContext

是一个音频上下文,像一个大工厂,所有的音频在这个音频上下文中处理。

let audioContext = new(window.AudioContext || window.webkitAudioContext)();

AudioContext 音频上下文提供了很多属性和方法,用于创建各种音频源和音频处理模块等,这里只介绍一部分,更多属性和方法可到MDN查阅文档。

AudioContext.destination

返回 AudioDestinationNode 对象,表示当前 AudioContext 中所有节点的最终节点,一般表示音频渲染设备。

主要对象和方法
  • AudioContext.createBufferSource()

创建一个 AudioBufferSourceNode 对象, 他可以通过 AudioBuffer 对象来播放和处理包含在内的音频数据。

  • AudioContext.createGain()

创建一个 GainNode,它可以控制音频的总音量。

  • 对象: AudioNode

音频节点接口是一个音频处理模块。包括音频源,音频输出,中间处理模块。

  • AudioNode.connect()

链接两个 AudioNode 节点,把音频从一个 AudioNode 节点输出到另一个 AudioNode 节点,形成一个音频通道。

源码

let audioContext = new AudioContext();
let gainNode = audioContext.createGain();
let audioSource = audioContext.createBufferSource()

function decodeAudioData(audioContext, url) {
	return new Promise((resolve) => {
		axios({
			method: 'get',
			url: url,
			responseType: 'arraybuffer'
		}).then((res) => {
			audioContext.decodeAudioData(res.data, (buffer) => {
				resolve(buffer);
			})
		})
	})
}

let buffer = decodeAudioData(audioContext, 'assets/music/test.mp3');

buffer.then((res) => {
	audioSource.buffer = res;
	
	audioSource.connect(gainNode)
	gainNode.gain.value = 0.5
	gainNode.connect(audioContext.destination);
	
	audioSource.start()
})
参考

HTML5音频API Web Audio

通过Web Audio API可视化输出MP3音乐频率波形