Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

手写一个音频播放器 #139

Closed
Dream4ever opened this issue Mar 25, 2021 · 0 comments
Closed

手写一个音频播放器 #139

Dream4ever opened this issue Mar 25, 2021 · 0 comments
Labels
Front-end Everything you see and experience

Comments

@Dream4ever
Copy link
Owner

Dream4ever commented Mar 25, 2021

需求描述

iOS 和 Android 的 Webview 中自带的音频播放 UI 各不相同,为了在前端页面中呈现统一的效果,所以需要手写一个音频播放器,本质就是监听 audio 的各种事件,并按需调用它的各个方法。

关键代码

加载音频

在 HTML 中,通过 audio 标签来加载音频,同时想办法隐藏该元素。这样既可以展示自己的音乐播放器界面,也方便自己调用 audio 的各种接口,监听各种事件。

<audio id="audio" src=""></audio>

其属性、方法、事件请看 HTMLMediaElement - Web APIs | MDN

监听音频播放/暂停/结束事件

监听音频播放(包括继续播放)、暂停、结束这三个事件,前端 UI 需要根据各事件呈现对应的界面,让用户感知到当前的播放状态。

audio.addEventListener('play', function () {})
audio.addEventListener('pause', function () {})
audio.addEventListener('end', function () {})

监听音频当前播放时间点

音频在播放时,会触发 timeupdate 事件,在该事件中,访问 audio.currentTime 属性可以获取到音频当前所播放到的时间点。

然后前端 UI 就可以根据该属性实时更新音频播放进度,比如显示进度条、当前播放时刻等信息。

audio.addEventListener('timeupdate', function () {
  var currentTime = audio.currentTime
})

监听音频是否正在播放

return audio && audio.currentTime > 0 && !audio.paused && !audio.ended && audio.readyState > 2

参考 HTML5 check if audio is playing?

TODO: 完整浏览上面这个链接,完善该方法。

切换音频播放状态

根据上一条,可以获取到音频是否在播放中,如果正在播放,用户点击播放按钮就应该暂停播放 audio.pause(),如果处于暂停状态,用户点击播放按钮则应该恢复播放 audio.play()

前进/后退指定时长

一个常见的需求,就是将音频前进/后退 5s、10s、15s 等等,这个实现起来很简单:

var timeStep = 15
audio.currentTime += timeStep

拖拽改变播放进度

通过监听指定元素的 touchstarttouchmovetouchend 事件,可以获取到手指在拖拽起点、拖拽过程中、拖拽终点的坐标,然后再结合其它相关元素,便可用来改变音频的播放进度。

这里有一点要注意,就是在拖拽结束时,也就是在 touchend 事件中,再改变音频的 currentTime 属性。在拖拽过程中,也就是在 touchmove 事件里,只需实时更新显示在前端 UI 上的进度即可,音频还按拖拽前的进度正常播放就行。

seeker.addEventListener('touchstart', function(e) {
  var start = e.changedTouches[0].pageX
})
seeker.addEventListener('touchmove', function(e) {
  var diff = e.changedTouches[0].pageX
})
seeker.addEventListener('touchend', function(e) {
  var end = e.changedTouches[0].pageX
})

TODO

以上 JS 代码完善之后,可以封装成一个对象,对外暴露各种方法。再配合一套对应的 HTML + CSS,就是一个 MVP 版本的音频播放器了。

还可以参考 Building a Simple MP3 Audio Player in Vue.js 这篇文章进行重构。

forijk / vue-audio-better 的代码,也可以借鉴一下。

Audio - Vue.js Examples:这里有 Vue.js audio 的各种资源,可以参考。

Vue+ElementUI: 手把手教你做一个audio组件 也可以参考。

@Dream4ever Dream4ever added the Front-end Everything you see and experience label Mar 25, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Front-end Everything you see and experience
Projects
None yet
Development

No branches or pull requests

1 participant