内容简介:自从上次在趣讲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。比如:
是的,这一点都不酷。不禁又回想起总工的那句话:这方案太简单了。
以后,我们再做这样的需求的时候,就可以做成跟随音乐频率跳动的动画效果了。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。