如果您想线上观看此 demo 请戳这里 -> 线上demo
综述 :
以上是在实现这个播放器之前自己的设想以及准备工作
此功能借助了 web video API 中的 paly()、pause() 方法来进行控制, 在播放的同时更改下图标即可。【但 play() 这个方法有个坑, 后面的踩坑攻略中详述 ~ 】
实时进度条
web video API 中有个 duration 属性可以获取当前播放音频的总时长由上图得知, 我们要想求 offset 偏移量就必须理清一个比例关系 : offset/width = currentTime/duration 所以可推出 offset =(currentTime * width ) / duration 。所以根据这个公式往里套值就可以得出进度条应该走的真实的距离【offset】, 然后修改对应样式即可。实时播放计时
播放计时用到了 web video API 中的 currentTime 属性, 每次当歌曲播放位置改变的时候 currentTime 都会刷新, 利用这一点我们可以实现这个功能。首先点击这个很好实现, 利用上面的公式推导出点击后应该为 video 设置的 currentTime 属性值然后给 video 赋回去即可。currentTime = (offset * duration) / width 。
移动滑块来控制与点击差不多但是多了几点
利用 mousedown、mousemove、mouseup 来实现拖拽
在 mousedown 的时候调用 pause() 暂停播放, 然后在 mouseup 时调用 play() 开启播放
音量图标的静音与非静音的判断是借助 web video API 中的 muted 属性进行判断的,静音返回 true, 反之 false。
修改 video 的音量大小是通过 web video API 中的 volume 属性来实现的 0代表静音 1 代表最大音量
点击图标调节音量比较简单, 稍微复杂的就是进度条控制静音, 和上面一样也是一个比例关系 : 当前音量/1 = offset / width 可推出 当前音量 = (1 * offset) / width。
在当前歌曲播放完毕再次点击播放的时候报错 Uncaught (in promise) DOMException: The play() request was interrupted by a call to pause(). 意思是说这个播放的请求被 pause 拦截掉了。并且这个 play() 执行返回的是一个 Promise 实例。
想想上面哪个环节可能有问题, 最终定位到了实现拖拽控制进度播放的时候可能埋下隐患了, 因为 pause 是在 mousedown 的回调中执行的, play 是在 mouseup 的回调中执行的, 同时 mouseup 就在 mousedown 的回调里, 嵌套层级比 mousedown 更深了一层, 所以问题就出在了这个异步任务队列中。既然知道问题那就在mouseup 里面加了一层 setTimeout 。
在歌词同步的时候, 由于有的歌曲中间会有一段旋律没有歌声那种情况, 那种情况恰恰是没有歌词的而我们生成的 li 结构中就会产生一些空内容的 li, 这些 li 的高度没法被撑开但是在歌词同步的时候又把这个 li 计算在内了, 就会导致同步不精确, 这个时候在生成结构的时候加层判断, 如果内容为空则给一个占位。
在拖拽控制进度条播放 mouseup 是绑在 window 上了, 在歌曲第一次在涉及到移动滑块的情况下播放完了, 在 window 上就挂载了一个 up 事件, 以后点击随便一个地方 up 事件回调都会执行, 造成了一些副作用。这个可以基于事件源来搞定, 事先声明一个全局变量 target, 并在 window 上绑定一个 mousedown 事件, 事件回调里面将事件源对象赋给全局变量 target。在滑块的 mousedown 的时候也做同样的操作, 这样只需要在 mouseup 事件回调里面加层事件源的判断即可解决该问题。
还有一些就是一些细小的细节问题但是总体上比较突出的问题是以上这几个。
由于播放链接请求的是 QQ 音乐的, 所以音乐版权属于 QQ 音乐官方。
QQ 音乐的播放链接大概有效期是 24 个小时, 过了就不能使用了, 但是每天早上 6:30 我会更新 git 仓库的 json 文件, 届时只需要将里面的数据拿过来覆盖掉原始的 json 即可。
请求 QQ 音乐的服务器距离较远, 如果网速不好的话可能出现偶尔的缓冲级别的卡顿, 但是第一遍过后浏览器缓存后第二遍在听是非常的流畅的。因为笔者的这边网不好所以这样, 大家网好的可能不会出现这种情况。
如果出现这种情况, 耐心一下初次加载给他点时间 ~
这个 demo 首先的比较粗糙, 有很多功能来不及实现 :
更加细致的歌曲切换。音质调节。频谱功能。以及一些 UI 方面的细节问题…看到这里了, 说明您对这个 demo 题材是比较感兴趣的, 不知道以上所述是否对您产生了帮助。
如果您有更好的 demo、更好的想法、更好的建议, 欢迎加我微信交流 : 【17803218829】
参考文档 : web video API - 菜鸟教程
如果您想线上观看此 demo 请戳这里 -> 线上demo
项目地址 : git