HTML5-Audio-Player在线音乐播放器

在线预览:Demo。。。算了。不值得

github

一个自己玩耍做的在线音乐播放器。功能有音乐播放、进度音量调节、单曲循环随机播放模式、lrc歌词解析同步展示等。只是实现了功能。模块化什么的真的有必要吗?

初想

一日闲来无事。想起了之前A岛有丧失做的一个在线音乐播放器-Kuso。忽然也想自己练练手。于是就模仿着Ta的风格开始制作了。

设计界面

其实我不喜欢kuso的界面。虽然不落俗于普通播放器却感觉有点儿单一。作为一个音乐播放器。封面呀、歌词呀、控制按钮呀什么的总得有吧。歌词显示一定要大。占得内容空间比例高方显大气。顶部一个导航条。左边logo右边设置项。内容区域左边播放功能界面和列表界面。右边一大部分就是歌词显示界面。OK。设计就是这么easy。。。吧?

技术选型

前端真是膨胀了呀。现在做个东西都有了技术选型了。我暗自鄙视了一下自己。css就用个fontawesome字体来显示那些控制暂停播放呀什么的按钮。js就用个zepto绰绰有余了。还想着自己组一套类jQuery的API呢。想想也没那个必要。方便即可。

歌词同步

看过kuso的歌词文件。是json格式。不知道对方是不是自己做的。我还是用lrc歌词吧。以前用千千静听制作过lrc。想来不就是字符串解析嘛。估计问题不大。把lrc歌词解析出来。播放到那个时间就显示哪个时间的歌词就可以了。

资源地址

这个跳过不提

开工

先弄个logo再说。

logo

丑或者不丑的。总算有个logo了。

资源

音乐资源。无非就是封面图、MP3音乐、lrc歌词这三样。巧了很多音乐播放器下载歌曲的时候都会下载下来(虽然有的是封面图直接嵌入到MP3文件里的)。从里面随便选了几首自己喜欢听的。为了方便写成了一个json文件。格式如下

{  
    "id" : "3",  
    "title" : "女人三十",  
    "artist" : "弥与弥歌",  
    "duration" : "04:49",  
    "media" : "mp3/Nvrensanshi/Nvrensanshi.mp3",  
    "cover" : "mp3/Nvrensanshi/Nvrensanshi.jpg",  
    "lrc" : "mp3/Nvrensanshi/Nvrensanshi.lrc",  
    "type" : "geji"  
}  

其中的duration要不要手写我纠结了许久。之后在测试了一下Audio的加载之后果断手写了。百度音乐盒也是手写的。

资源加载

Audio有一个progress事件。现代浏览器都有支持。可以用来做加载进度显示。

function progress(){
      var buffered = this.buffered,
          total = this.duration,
          start = buffered.start(0),
          end = buffered.end(0),
          progress = end/total*100;
      console.log(progress);
  }
  audio.addeventlistener('progress',progress);

加载过程中会一直调用。知道加载进度为100%为止。

lrc歌词解析与同步显示

在动手之前先在网上查了一下。果然。基本大多音乐播放器都实现了解析lrc的功能。关掉那些轮子。自己开始写。通过ajax获取到lrc文本之后。有几点需要注意。

  1. lrc歌词每一句都是一行。可以使用\n来分割。
  2. 负责任的lrc制作者会添加几个属性。例如[ti:女人三十]是歌名。[ar:弥与弥歌]是歌手。[al:2015AC春晚大联欢]是专辑名。[by:nostar]是制作lrc的作者。[offset:-500]是通过一些音乐播放器调整的歌词毫秒数。虽然没有时间戳。但还是要展示出来并且与有时间戳的歌词分开的。尤其是offset。有时间戳的歌词都需与offset相加。才能得到正确的时间戳。
  3. 时间戳分三种。[00:00.00]、[00:00:00]、[00:00]。而一句歌词如果整首歌重复部分比较多(比如副歌部分)会写多个时间戳。比如[00:00.00][01:08.19]最可怕是人的一世青春转眼间消逝。多个就是不确定多少个意思。这些都要匹配。而且会导致时间错乱。最后还需要重新排序。
  4. 时间戳需要计算为具体秒或者毫秒数。并于offset相加。
  5. Audio是没有播放进度的事件的。只能用手动循环监听。因为lrc歌词精确到十毫秒。因此为了显示的准确性。循环间隔也要以毫秒计算。这种时候setTimeout和setInterval的性能缺陷就显现出来了。像做canvas动画一般。使用requestAnimationFrame比较好。但是。requestAnimationFrame也有缺点。当你离开这个标签页面的时候。为了性能考虑。requestAnimationFrame会暂停。而在音乐播放器中的直观感受就是。我不能开着播放器去看其他网页了。利弊看需要吧。

播放模式

一般播放模式可分为单曲循环、列表循环、随机播放。使用js来做其实就是继续播放歌曲数组当前播放下标、当前下标+1。或者是随机生成一个下标。每次更改播放模式后存入localStorage即可。

手机适配

。。。我没有做。为什么没做呢?因为懒得做了。我用手机干嘛还要来听这个?我才不会告诉你我做这个也是为了把自己喜欢听的歌曲整理成一个目录呢!

全屏适配

在web端使用js来做全屏适配还是很酷炫的。我也没有做。或许以后会做吧。其实还是蛮需要的。因为炫酷嘛。

其他

比如动画、背景呀什么的乱七八糟。。。

后记

在线音乐播放器。随便一搜都是一堆。自己亲自做了一下。不禁感慨。html5大法好呀。不然像以前在网页上插音乐还得用flash。做在线播放器直接整站都flash了。啧啧啧。。。