前段时间比较闲,顺便就开发了自己的音乐主页👉https://music.jw1.dev (已下线),开发过程中遇到不少问题,一度以为解决不了,但是最后看来,其实实现都非常简单。
首先看看html吧
|
这时候打开页面你会发现…什么都没有。
|
加上controls
这个属性,浏览器才会显示原生的音频组件。至于浏览器兼容性我就不讲了,还是老样子扔个MDN链接在这里😁:https://developer.mozilla.org/en-US/docs/Web/HTML/Element/audio#Browser_compatibility
所以,搞定了?
不!像我这种有强迫症的人,怎么可能让每个浏览器的显示都不一致!
要做的第一件事情就是,隐藏audio
的原生控制组件:
|
(👆三遍了🤣
然后用CSS将audio
移出文档流:
|
为什么要这么做?
—— 为了避免一些非主流的浏览器会让audio
在没有controls
属性的情况下出现在不应该出现的地方。(好累
接下来看JS的部分
|
原生JavaScript在log下只能看到标签,而jQuery则会把所有和这个元素有关的东西都列出来,不论是有用的还是没有用的。但是知道有那么多属性/事件可以用是件好事,在这里说几样比较重要的。
接下来js区域中的
audio
都是以原生js获取的对象,如果你使用jQuery,audio赋值应该为
let audio = $($('audio')[0])
audio.play()
可以调用此方法来播放音频。因为市面上大多数浏览器不允许直接用js触发音乐播放,必须要由用户来触发该事件(‘click’, ‘scroll’, ‘focus’, etc.),所以我们可以加一个播放按钮来触发事件:
|
|
audio.pause() & audio.paused
调用audio.pause()
来暂停音频。
调用audio.paused
来获取音频暂停状态,true
为暂停状态,false
则为播放状态。
比如我现在需要再点击一次play button来暂停音频,我们可以这样做:
|
audio.currentTime
调用此属性获取音频当前已播放时间。
修改此属性可以达到切换音频当前播放位置的功能:
|
audio.duration
调用此属性获取音频的长度,单位为秒。
已知问题:
- 在
Firefox
上会出现读不到duration的情况,可能和修改audio.src
有关,我在自己项目中的做法是使用了ffmpeg
读取出duration,直接当作变量使用,没有使用浏览器给的这个属性。
audio.ontimeupdate
此方法在音频播放期间会循环调用,经测试,调用间隔大约为200ms一次。
此方法可以用在更新音频进度条上。有了上面的audio.currentTime
和audio.duration
,我们可以算出当前音频播放进度的百分比:
|
这个时候如果你打开页面开始播放音频,就会看到控制台一直在更新进度百分比了,至于这个数值怎么用,不用我教大家了吧。😁
audio.buffered
调用此属性可以获取当前音频的缓冲进度和区间:
|
控制台输出:
|
输出的含义为:
这一次读取audio.buffered
得到了两个区间,所以循环了两次。
第一次获得的区间是[0,17.64]
,代表第0秒到第17.64秒之间的音频已经缓冲好了,可以直接播放。
第二次获得的区间是[56.45,78.90]
,代表这两个数字之间的音频已经缓冲好了,可以直接播放。
audio.onwaiting & audio.onplay
audio.onwaiting
会在音频开始缓冲的时候被激活;
audio.onplay
会在音频开始播放的时候被激活;
这时候我们可以做一个loading的动画,告诉用户音频正在加载了:
|
audio.ended & audio.src
audio.ended
顾名思义,会在音频结束后被激活;
audio.src
是音频文件的位置,可修改;
当你有一个播放列表,且想在音频结束后播放下一首歌,你就可以:
|
哦还有!
audio.volume
调用获取音频的音量,可修改;
可以做点fade in / fade out的效果,使用jQuery可以很简单的做出来,原文中也有原生js的实现方法(太长没看
$audio.animate({volume: newVolume}, 1000)
原文链接:https://stackoverflow.com/questions/7451508/html5-audio-playback-with-fade-in-and-fade-out
好了,以上就是我开发音乐主页之后想和大家分享的。
至于题中的问题,我的答案是:真的很简单。
只是js有一些性能上的限制,不能什么功能都往网页上搬…
在我的音乐主页中有一个砍掉的功能
—— 节拍器
为啥砍掉了呢…
因为js的处理效率真的不高(或者只是我太辣鸡),中低端手机做出来的节拍器根本不准,至于实现原理,很简单:
歌曲的bpm(beat per minute)是已知的:
|
希望有一天js能有开发Digital Audio Workstation的能力!
✌