HTML5音乐播放器

HTML5音乐播放器开发

关于HTML5的音乐播放器,总结一下各个模块的程序思路和遇到的蛋疼问题,不完美的地方就是没做歌曲列表和歌词显示,等改天有需求了再做吧,先上DEMO。

查看DEMO

CSS部分

页面的重构不算复杂,使用了常见的几个CSS3属性,主要的是使用@Font-face来制作页面的icon,这样除了歌手头像以外没用其他的图片,不用做蛋疼的css spirit切片了,真的少死几个脑细胞啊,icon的字体在icomoon.io中制作,省时省力。因为IE6-8不支持HTML5,所以没去兼容了,还有个缺点是没做成响应式的。

JS部分

javascript部分其实就是使用HTML5的提供的audio的各种API,用javascript来控制播放器的各个行为,从而替代丑陋的默认控制界面,开发出用户体验和视觉效果更好的播放器控制界面。

DEMO下载

一、使用到的API:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
主要标签
<audio src= "URL" > 你的浏览器不支持HTML5播放器 </audio>
 
方法
audio.play()            //播放当前歌曲
audio.pause()           //暂停当前歌曲
audio.load()            //重新加载歌曲,更改src后用于重新加载歌曲
 
属性
audio.duration          //获取歌曲总时间,用于显示播放时间和制作进度条
audio.currentTime       //获取和设置歌曲时间,用于显示当前播放时间和点击进度条改变播放时间
auido.buffered.length   //获取已缓冲区域的个数,如果还未全部缓冲完成,当用户跳跃播放时,会产生多个缓冲区域
audio.buffered.end()    //获取已缓冲的时间,用于制作缓冲进度条
audio.volume            //设置音量
auido.muted             //设置和判断是否静音
 
事件
timeupdate              //当前歌曲播放时间变化时,播放时间和播放进度条变化得靠这个事件
ended                   //当前歌曲播放结束时
canplay                 //当前歌曲可以播放时

二、程序主要流程

总结下程序思路,代码全贴出来很多,上图好了。

player1

三、显示剩余时间和播放进度条

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
audio.addEventListener( 'timeupdate' , function (){
     if (!isNaN(audio.duration)) {
         //剩余时间
         var surplus = audio.duration-audio.currentTime;
         var surplusMin = parseInt(surplus/60);
         var surplusSecond = parseInt(surplus%60);
         if (surplusSecond < 10 ) {
             surplusSecond = '0' +surplusSecond;
         };
         $( '.time' ).innerHTML = "-" + surplusMin + ":" +surplusSecond;
 
         //播放进度条
         var progressValue = audio.currentTime/audio.duration*324;
         $( '.progress' ).style.width = parseInt(progressValue) + 'px' ;
     };
}, false );

audio.duration获取到的时候是歌曲总的秒数,还带小数,所以要转换成我们熟悉的时间显示格式。

播放进度条制作:判断currentTime占duration的百分比,乘以进度条长度,监听timeupdate事件,每秒改变进度条宽度即可。

四、显示缓冲进度条

一开始我是使用监听progress事件,判断buffered.end()占duration的百分比来做的,后来发现这里那里总有些小问题,于是改用传统的setInterval定时器来做,省得继续伤脑筋。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
function bufferBar(){
         bufferTimer = setInterval( function (){
             var bufferIndex = audio.buffered.length;
             if (bufferIndex > 0 && audio.buffered != undefined) {
                 var bufferValue = audio.buffered.end(bufferIndex-1)/audio.duration*324;
                 $( '.buffer' ).style.width = parseInt(bufferValue)+ 'px' ;
 
                 if (Math.abs(audio.duration - audio.buffered.end(bufferIndex-1)) <1) {
                     $( '.buffer' ).style.width = 324+ 'px' ;
                     clearInterval(bufferTimer);
                 };
             };
         },1000);
     }

注意的是,如果一首歌还没缓冲完的话,用户跳跃播放可能会产生多个缓冲区域,假设出现第二个缓冲区域,auido.buffered.length会变成2,火狐此时只会获取第二段缓冲区域audio.buffered.end(1)的缓冲时间,缓冲进度条的程序中如果只使用audio.buffered.end(0)来获取已缓冲时间的话,程序就会出错,而chrome和IE不会,chrome中auido.buffered.length一直都是1。

player2

五、调整播放进度条改变播放时间

原理很简单,只要知道了点击进度条的位置和进度条长度的百分比,乘以歌曲总时间,就能得到要改变的时间了。要确定点击时进度条的位置,IE可以使用offsetX(鼠标点击时在触发事件元素中的X坐标),可惜不兼容火狐,火狐中有个layerX可以代替,略有区别,就是要算上元素border的宽度。chrome二者通吃,也算上了border的宽度。这三者缠绵的关系搞得我不想写个函数去兼容了,我直接使用了getBoundingClientRect()这个方法来获取。

player3

1
2
3
4
5
function adjustPorgress(dom,ev){
         var event = window.event || ev;
         var progressX = event.clientX - dom.getBoundingClientRect().left;
         audio.currentTime = parseInt(progressX/324*audio.duration);
     }

获取到鼠标点击进度条时的长度和总长度的百分比,乘以总时间,即可得到要改变的歌曲时间,用currentTime直接设置即可,如果进度条有border,要记得减去border宽度。

六、调整音量条

1
2
3
4
5
6
function adjustVolume(dom,ev){
         var event = window.event || ev;
         var volumeY = dom.getBoundingClientRect().bottom - event.clientY;
         audio.volume = (volumeY/80).toFixed(2);
         $( '.volume_now' ).style.height = volumeY + 'px' ;
     };

原理和调整播放进度条一样,得到的百分比用toFixed(2)四舍五入得到两位小数的数字,设置volume即可调整音量。

七、播放模式

代码太多,就不贴了,有兴趣可以下载demo看源码。主要两个方法,一个点击页面的播放模式按钮后,改变播放模式,一个是根据播放模式来计算下一首歌的索引值。

1
2
3
4
5
6
7
function changeMusicMode(dom,mode){
     ......
}
 
function playMusicMode(action){
     ......
}

八、火狐获取duration出错问题

自己测试的时候有时可能因为网络加载慢的问题,火狐获取duration的时候获取不到,得到NaN,这样显示时间和进度条都会出错。所以我监听了canplay事件,当歌曲准备到可以被播放时,才进行获取duration和buffered等相关数据获取操作,貌似火狐没出现上述问题了。

总结完毕,欢迎大家测试下我写的播放器,可以一顿乱点,如果有bug欢迎指点。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值