内容简介:自从上次在趣讲CDN一文中讲了一个"传东奶"的故事之后,就再也没有发过博客。或许有些朋友还以为我们被抓了呢,哈哈哈~很久以前,赵忠祥老师就告诉我们,雨季,是个好时节。雨季来了,春暖花开,万物复苏,又到了大草原上程序猿们XX的季节。好吧,扯远了。说到底,就是团队中的小哥哥小姐姐都忙着谈恋爱,都没时间写博客了。有这样的一个需求,上传一个音频文件,同时获取其大小及时长。
自从上次在趣讲CDN一文中讲了一个"传东奶"的故事之后,就再也没有发过博客。或许有些朋友还以为我们被抓了呢,哈哈哈~
很久以前,赵忠祥老师就告诉我们,雨季,是个好时节。雨季来了,春暖花开,万物复苏,又到了大草原上程序猿们XX的季节。好吧,扯远了。说到底,就是团队中的小哥哥小姐姐都忙着谈恋爱,都没时间写博客了。
获取音频的时长
有这样的一个需求,上传一个音频文件,同时获取其大小及时长。
常规方法
这很简单,使用记忆中的那些方法,写出下面的代码:
function getAudioDuration(url) {
const audio = document.createElement('audio');
audio.src = url;
audio.addEventListener("canplay", function () {
console.log(audio.duration);
});
}
const file = document.getElementById('file');
file.addEventListener('change', (e) => {
const file = e.target.files[0];
console.log(file.size);
getAudioDuration(URL.createObjectURL(file));
})
复制代码
当我撸完上面这段代码的时候,回想起总工的批判:这方案太简单了。菊花一紧,吓得我赶紧找找其他的方案。
ArrayBuffer
在电脑中,当我们选中一个MP3文件的时候,通常可以看到一些元信息,比如播放时长、采样速率等。既然如此,我们是否可以通过读取二进制数据来获取对应的信息呢?
在查询相关资料之后,发现了decodeAudioData这个API可以满足我们的需求,于是有了下面的方案。
function getAudioDurationByAudioApi(file) {
const fileReader = new FileReader();
const audioContext = new AudioContext();
fileReader.readAsArrayBuffer(file);
fileReader.onload = () => {
audioContext.decodeAudioData(fileReader.result, (result) => {
console.log(result);
});
}
}
const file = document.getElementById('file');
file.addEventListener('change', (e) => {
const file = e.target.files[0];
console.log(file.size);
getAudioDurationByAudioApi(file);
})
复制代码
被忽略的Web Audio API
通过以上的探索,发现了一直被我忽略的Web Audio API。以往在处理音频相关的需求,大多是通过audio标签,播放一段音频,很简单。所以也就没有关注到早已存在的Audio API。
举个栗子
实际应用一下,举个简单的播放音频栗子:
function playAudio(file) {
const fileReader = new FileReader();
const audioContext = new AudioContext();
fileReader.readAsArrayBuffer(file);
fileReader.onload = () => {
audioContext.decodeAudioData(fileReader.result, (result) => {
//创建播放源
const source = audioContext.createBufferSource();
source.buffer = result;
//连接输出终端
source.connect(audioContext.destination);
//开始播放
source.start();
});
}
};
const file = document.getElementById('file');
file.addEventListener('change', (e) => {
playAudio(e.target.files[0]);
});
复制代码
以上例子简单使用相关的API进行了音频的播放,分析一下关键的代码。
AudioContext
直接翻译,就是"音频上下文"。类似于canvas中的context。其中包含了一系列用来操作音频的API。
上面的代码中,通过const audioContext = new AudioContext();创建了一个AudioContext对象,于是我们就可以进行各种各样的操作。
创建播放源
上面的例子中,我们通过AudioContext.createBufferSource()创建了播放源。除此之外,我们还可以使用其他的数据作为播放源:
- AudioContext.createOscillator()
- AudioContext.createBuffer()
- AudioContext.createMediaElementSource()
- AudioContext.createMediaStreamSource()
具体介绍可点击链接查看。
连接输入输出
我们可以看到,在设置好播放源之后,进行了一个connect操作。这个操作就是将播放源链接到播放终端。
AudioContext的destination属性返回一个AudioDestinationNode表示context中所有音频(节点)的最终目标节点,一般是音频渲染设备,比如扬声器。
有趣的玩法
在学习AudioContext相关API的过程中,发现了createAnalyser这个方法。
createAnalyser方法能创建一个 AnalyserNode ,可以用来获取音频时间和频率数据,以及实现数据可视化。
要看看效果吧,demo
以前,需要标识一个音频正在播放,我们经常会放一个跳动的gif。比如:
是的,这一点都不酷。不禁又回想起总工的那句话:这方案太简单了。
以后,我们再做这样的需求的时候,就可以做成跟随音乐频率跳动的动画效果了。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Automate This
Christopher Steiner / Portfolio / 2013-8-9 / USD 25.95
"The rousing story of the last gasp of human agency and how today's best and brightest minds are endeavoring to put an end to it." It used to be that to diagnose an illness, interpret legal docume......一起来看看 《Automate This》 这本书的介绍吧!