搜索了很久文章,感觉网上很多将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()
})
实现音频时转换过程
实现控制音量
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()
})