前一段时间看以了一些关于Web Audio API的东西,震撼于其强大的功能,就想着用他做个新时代的播放器出来(网上也确实有好多了)。正好学校这边举办了一个比赛,要求程序需要运行于firefox for android上,没有主题。那就趁着机会整一个呗。
关于Share Your Music
先简单说下这个app吧,因为比赛的需要,主要适配了firefox for android,还有chrome for android,当然在PC上浏览器开启手机模拟也是可以的。
app从名字上也可以看出来,主要完成音乐分享和播放的功能。最开始没想要做分享,就像网上大多数的demo一样,做一个纯粹的播放器,用户选择自己手机里的歌曲进行播放。问题接着就来了,当时用HTML5的File API,返回音频的data url,firefox不支持!!chrome下可以,上传后返回个url倒是全部支持的。其次这样的播放太单调,虽然可以Web Audio API和Canvas一起制作可视化输出,但歌曲的相关信息还是没有,单调,太单调。还是做个上传吧。
上传也得做的有情怀一点,这里希望大家上传的是一些冷门的好听的歌曲,那些烂大街口水就不要了,同时,用户也可以查看聆听已经上传的歌曲。
布局动画什么的都是CSS3完成,界面还算清新,如果不是浏览器顶部的网址栏,或许会认为这就是个原生的应用。
后端
后端做的比较简单,后面如果有时间会继续完善下。其实就两个PHP文件,一个上传的,一个查询的,而且查询只是返回前十条记录(我承认我偷懒了。。)。如果只是上传就没什么意义了,上传后,后端会对上传的音乐文件进行解析(一个音乐文件,比如MP3,里面包含了很多信息,自行百度之),得到音乐的专辑、歌手、专辑封面还有歌词等信息,存进数据库里,这些解析工作是通过getID3这个PHP库完成的,很强大的库。查询既是将这些信息从库里取出来,返回给用户。
getID3这个库,返回的中文结果会乱码,不过牛人无处不在,看这里:解决GetID3库解析中文ID3v2乱码问题。
UI
先上张图,正在播放的样子:
主要工作都在前端,UI是参照了网上的一张图,经过修改,不过原链接找不到了,谁找到了一定告诉我。。。下面主要说一下实现和参考的相关文章。
-
布局
从布局的图片看,大致从上到下分了3个部分吧,上边一行是header部分,下面是音乐播放的主体部分,再下面是播放列表了。放在以前的话,肯定要设置height的百分比什么的,还有三个播放控制的按钮,肯定要各种设置,现在呢,我们使用CSS3的Flex弹性布局,稳准狠。各种教程也已经遍地开花了:
图解CSS3 Flexbox属性
深入了解 Flexbox 伸缩盒模型
另外CSS-Tricks里有好多CSS3的文章。 -
移动端的一些组件
- 侧边栏(panel)
点击左上角的菜单图标或者左滑都会显示侧边栏,包含了一些操作,这里只有关于和设置信息。
- 模态框(modal)
模态框用的好多,上传会弹,关于信息弹,设置也是弹(弹弹弹,弹掉鱼尾纹。。。)。
- 弹窗(popup)
点击右上角的音乐图标会弹出大家上传的歌曲信息。
好了,这些移动端的知识都是从这一系列的博客学习来的:移动端重构系列。良心出品啊,全是干货,从准备到组件到页面切换全讲到,我无耻的借(kao)鉴(bei)了。。。。
-
其他
还有其他的CSS3特性,背景渐变、动画(歌曲播放的时候专辑封面转啊转)、fontface(使用了阿里的iconfont)、进度条使用的
input range
(之前用的progressbar
)。用CSS创建跨浏览器的range input
[HTML5 progress元素的样式控制、兼容与实例](HTML5 progress元素的样式控制、兼容与实例)
http://www.hongkiat.com/blog/html5-progress-bar/这里说一句,在使用
input range
标签的时候,参照上面的文章,出来的效果还差一点,range的滑动条有一个很大白色背景,还有边框,滑块也有边框,PC下没有这个问题,Chrome for android也没有问题,只有firefox for android有这个问题。还是在MDN里找到了答案:
input有:in-range
和:out-of-range
这样的伪类,只是设置appearance
还不够,还要这样:input[type=range]:in-range,input[type=range]:out-of-range { background-color: transparent; border: none; }
这样讨厌的背景和边框都没了。
-
总结
移动端的布局肯定要大量的的使用CSS3,不过由于手机版本和浏览器的差异,还有许多坑,就像那个Flex,已经三个标准了。。。但是也得上,尤其是动画,用js蛋碎。。一般的动画靠
transform
和transition
都OK,比如页面切换、侧边栏、模态框什么的,tranlate3d
还能开启个硬件加速,流畅度好一些,现在的大部分手机硬件应该都够可以了,包括千元机,像我手里的魅蓝Note,很流畅(除了发热。。。。)
逻辑
JS部分用了许多的HTML5 API,下面分别介绍。
-
上传
肯定要使用XMLHttpRequest Level 2嘛。
这里我们都会用到input file
标签,不过这个标签默认样式奇丑,自定义也不是多简单的事情,所以这个还是直接diaplay:none
完事,然后找个别的元素,可以是美丽的按钮,我这里是专辑封面,点击专辑封面的时候,触发file
标签的click
,就ok了。cover.onclick = function() { file.click(); } file.onchange = function(e) { console.log(e.target.files[0]); }
获取到file对象,就可以上传了,上传的时候用
FormData
包一下。var fd = new FormData(); fd.append('music',fileUrl); xhr.open('POST','upload.PHP',true); xhr.send(fd);
扔给xhr传到后台去,xhr2提供了许多事件,进度
progress
、完成upload
、出错error
,监听这些回调。xhr.onprogress = function() {}; xhr.upload.onprogress = function() { //这里处理进度 if(e.lengthComputable) { var prog = '正在上传....' + (e.loaded / e.total * 100).toFixed(2) + '%'; //..... } else { alert('无法统计进度'); } }; xhr.onload = function() { //在这里处理服务器的响应 }; xhr.onerror = function() { console.log('尼玛,上传出错了...'); }
基本就这些,不过还是有一点问题,xhr2还可以设置
responseType
,你如果使用了,要将xhr.responseType
放到xhr.open
之后,否则firefox会报错。刚才上面说到xhr2的进度事件,代码正常执行,但是进度没有统计出来(看上传的那张图片)。求大神帮解决。。。
后端的话使用PHP的
$_FILE
数组接收即可。$arr = explode('.',$_FILES['music']['name']); $file_path = '../upload/musics/'.time().'.'.$arr[count($arr) - 1]; header('Content-Length: '.$_FILES['music']['size']); if(!move_uploaded_file($_FILES['music']['tmp_name'],$file_path)) { //...... return; } else { $return['url'] = 'http://'.$_SERVER['HTTP_HOST'].'/upload/musics/'.time().'.'.$arr[count($arr) - 1]; }
-
Web Audio API和Canvas
终于说到重点了,这次的音乐播放控制都是通过Web Audio API来做的,Web Audio API提供了很多强大的功能(好多我都看不懂。。。),每个功能都是通过节点连接,这些节点通过音频上下文创建,首先创建源节点
source
,如果要进行其余的操作,比如音量、分析等,就需要创建gainNode
、analyserNode
等,然后通过connect
方法连接,一直连接到结尾节点destination
。其中创建源节点有很多方法,这里通过audio
标签获取,这样就可以充分利用audio
提供的方法了:播放、暂停、时间还有时间更新、播放停止、以及出错的事件监听等等。
Web Audio API里可以创建分析节点,得到音乐的频谱,然后通过canvas绘制出来,把图再贴一遍:背景里的竖条就是,随着音乐跳动。
还是送上参考文章吧:
Getting Started with Web Audio API - HTML5 Rocks
开大你的音响,感受HTML5 Audio API带来的视听盛宴
通过Web Audio API可视化输出MP3音乐频率波形 - OurJS
Exploring the HTML5 Web Audio: visualizing sound | Smartjava.org
网:HTML5音乐可视化问题依然是有的,firefox for android 下
audio
监听canplay
没自动播放,需要设置src后load一下:audio.src = url; audio.load();
chrome下,一个audio不支持多个source,所以个人觉得稳妥的做法是全部置为null重新new一个(参见下面的库)。
为了方便使用,搞了个简单的库:Github地址。
-
其他API
还尝试了其他的新API。
Web Notification API,先上图。
手机状态栏上方,提示正在播放的歌曲。这个功能应该是很给力的,后端完善下,推送一些好的歌曲给用户,更接近原生应用了。
重力感应 API,实现了摇一摇切歌。
可以在这里查看firefox提供的所有API。
写到后面
大致的把其中的点和遇到的问题写了一下,虽然只是注意适配了firefox for android,所以好多兼容都没有考虑,但是还是学到了许多移动端开发的知识,之前一直没怎么接触。
移动端的Web前端是一个大趋势,值得我们努力探索。
访问地址:http://202.114.114.212:8888/mp
也可以在我的独立博客访问这篇文章。