Audio 标签本来想着很简单,直接把音频文件塞入src属性里面就可以了。直到真正使用的时候才发现,没那么简单。
到现在为止已经用了两次这个标签,说起来也是满满的泪。需要注意的细节非常多,而为了不在页面到处都是audio标签,需要做的也是很多,甚至需要单独一个组件来多处引用也是很麻烦。
1、简单认识一下audio标签
常用属性:
autoplay:自动播放
preload:none/metadata只下载元数据(时长、大小等)/auto自动优化下载整个流文件
controls:是否显示控件
loop:是否循环播放
mediagroup:多个音频流是否合并(没用过 == )
src:文件地址
API与事件
load():加载资源
play():播放
pause():暂停
timeupdate():播放时间的改变
ended():播放结束
error():资源加载错误
其他属性
currentTime:指定播放位置的秒数
muted:静音
playbackRate:播放速度(正常为1,可修改为0.5~4)
- 注意:一般不采用默认的标签样式,而是将audio标签隐藏,然后自己写一个样式关联到audio标签上的事件。
2、基本使用方法(以vue为例)
<audio ref="audio" :src="audioIndex.url" :preload="audio.preload" @play="onPlay" @error="onError" @pause="onPause" @timeupdate="onTimeupdate" @ended="onEnded">
</audio> // 添加额外的标签用于操作audio <el-button type="text" @click="startPlayOrPause">{{audio.playing | transPlayPause}}</el-button>
|
js部分:
export default { data () { return { audio: { playing: false } } }, methods: { startPlayOrPause () { return this.audio.playing ? this.pause() : this.play() }, play () { this.$refs.audio.play() }, pause () { this.$refs.audio.pause() }, onPlay () { this.audio.playing = true }, onPause () { this.audio.playing = false } }, filters: { transPlayPause(value) { return value ? '暂停' : '播放' } } }
|
获取音频时长:
onLoadedmetadata(res){ this.audio.maxTime = parseInt(res.target.duration) }
|
更新当前播放时间:
onTimeupdate(res){ this.audio.currentTime = res.target.currentTime }
|
添加进度条:
<el-slider v-model="sliderTime" :format-tooltip="formatProcessToolTip" @change="changeCurrentTime" class="slider"></el-slider>
|
通过进度条控制播放时间:
changeCurrentTime(index) { this.$refs.audio.currentTime = parseInt(index / 100 * this.audio.maxTime) }
|
播放时间改变时进度条跟着改变:
onTimeupdate(res) { this.audio.currentTime = res.target.currentTime this.sliderTime = parseInt(this.audio.currentTime / this.audio.maxTime * 100) }
|
一点附加功能
如果要实现只播放一个音频,其他的暂停,可以用ES6的类数组转化成数组的语法[...audios]
:
onPlay (res) { console.log(res) this.audio.playing = true this.audio.loading = false if(!this.controlList.onlyOnePlaying){ return } let target = res.target let audios = document.getElementsByTagName('audio'); [...audios].forEach((item) => { if(item !== target){ item.pause() } }) }
|