600字范文,内容丰富有趣,生活中的好帮手!
600字范文 > vue2.x 音频播放器 使用element ui + Audio实现一款完整的音频播放器

vue2.x 音频播放器 使用element ui + Audio实现一款完整的音频播放器

时间:2024-03-02 10:05:02

相关推荐

vue2.x 音频播放器 使用element ui + Audio实现一款完整的音频播放器

项目背景

audio 音频播放在多媒体开发中非常常见,但是实际项目中你就会发现,每个系统的audio音频界面都长的不一样,百花齐放... pw怎么会同意呢[哈哈],马上掏出手机,你改成长这个样子就好了。需要所有的系统显示统一,只能用库了。 本着节约成本的原则,上网搜索了一些,竟然发现支持vue的多媒体组件库少的可怜,下了一个还不支持vue2[二哈惊讶脸],还是撸起袖子自己写一个吧。 这个组件是由element ui + audio + iconfont实现,为什么用了element ,因为不想自己去操心组件风格,而且我们项目的风格也已经定了基调,纯粹是顺手。iconfont 是用阿里的图标库,非常方便,几乎都可以找到满足需求的图标,然后添加到自己的项目,下载包,导入项目即可。 iconfont 地址: /home/index 关于如何在项目中引入iconfont,可以看这里: juejin.im/post/5c1ef2… 简介

编码

1.引入vue elemnt ui

> import Vue from 'vue';import ElementUI from 'element-ui';import 'element-ui/lib/theme-chalk/index.css';import '../../assets/icons/iconfont.css';Vue.use(ElementUI);new Vue({router,store,render: h => h(App),}).$mount('#app');复制代码

2.确定音频ui与功能

ui风格大致如下:

需要支持的功能:

显示音频资源的相关信息,显示音频标题,音频时长等音频播放,暂停音频进度点击拖动音频循环播放加载、出错、结束等状态识别

3.主要交互功能实现

1.如何获取音频的相关信息

this.$refs.audioLoad.addEventListener('loadedmetadata', function cb() {const se = this.duration;const second = formatSecond(se);});function formatSecond(se) {let m = parseInt(se / 60, 10);m = m < 10 ? `0${m}` : m;let s = parseInt(se % 60, 10);s = s < 10 ? `0${s}` : s;return `${m}:${s}`;}复制代码

得到的se是未格式化的视频总时常,格式化后的second即是可以直接显示的总时常

2.音频播放的当前进度从哪里获取?

定义一个变量标识当前播放时间,通过audio api的timeupdate 事件可以监听当前音频播放事件。 得到了当前播放刻度跟总时常,就可以计算当前的播放进度,进度值就可以表示在播放进度条上,定义变量 precent为播放进度

let showPre = '00:00';this.$refs.aduioObj.addEventListener('timeupdate', () => {if (ele.isEnd || !ele.isPlay || parseInt(ele.playPrecent, 10) === 100) return false;const palyTime = ele.$refs.aduioObj.currentTime;const totalTime = ele.play.second;const precent = (Math.floor(palyTime) / Math.floor(totalTime)) * 100;ele.playPrecent = precent;ele.showPre = formatSecond(palyTime);if (parseInt(ele.playPrecent, 10) === 100 && ele.play.loop) {ele.$refs.aduioObj.currentTime = 0;ele.playPrecent = 0;}}, false);复制代码

用户通过滑块拖动了进度,要如何处理? 通过滑块的change事件,但是在滑块这边,能获取的值是当前滑块的占比,跟上面一个步骤是相反的,我们需要通过precent跟总时长去退出拖动后的当前时间:

@change="precentChange"precentChange(val) { // 拖动滑块改变播放进度this.isChange = true;this.playPrecent = val;this.showPre = formatSecond((this.play.second * val) / 100);this.$refs.aduioObj.currentTime = (this.play.second * val) / 100;},复制代码

3.音频的播放、暂停

好了,到目前为止,我们已经可以轻松应对播放进度相关操作了,现在我们来反过来看最左边的播放按钮, 点击按钮、暂停按钮通过其点击事件,再去手动触发audio的播放与暂停事件:

audioPlay() {this.isPlay = true;this.$refs.aduioObj.play();},audioPause() {this.isPlay = false;this.$refs.aduioObj.pause();},复制代码

4.音频的循环播放

我们知道音频的循环播放是通过设置audio 的loop属性,而作为一个组件来说,这个属性是一个从外部可以随时修改的参数,所以如果在音频播放过程中,loop属性发生了改变,那么意味着其播放状态要回到开始,播放进度也要归零,从新开始播放,所以需要重新赋值:

this.$refs.aduioObj.addEventListener('ended', () => {ele.$refs.aduioObj.currentTime = 0;ele.playPrecent = 0;if (!ele.play.loop) {ele.isEnd = true;ele.isPlay = false;ele.showPre = '00:00';}}, false);复制代码

5.交互优化-音频加载状态

音频文件比较大,第一次加载没有那么快出现,需要做一个loading过渡状态,避免播放按钮切换暂停按钮很久都没有音频播放出来 一开始,是在loadedmetadata 事件里面识别,但是后来某天偶然发现在iphone手机上加载一个有一定大小的音频的时候,loading消失后还是迟迟不能播放,但是同样的,其他安卓机却可以正常播放。原因是ios必须要等资源都完全下载完才可以播放,而安卓却可以支持断点续传。所以去考察了audio的几个加载钩子,最后得出终极的解决方案:

this.$refs.aduioObj.addEventListener('waiting', () => {if (this.isLoad) this.isLoad = false;});const u = navigator.userAgent;const isAndroid = u.indexOf('Android') > -1 || u.indexOf('Adr') > -1; // android终端if (isAndroid) {this.$refs.aduioObj.addEventListener('playing', () => {if (!this.isLoad) this.isLoad = true;});this.$refs.aduioObj.addEventListener('canplay', () => {this.isLoad = true;});} else {this.$refs.aduioObj.addEventListener('canplaythrough', () => {this.isLoad = true;});}复制代码

watting 钩子表示的就是音频数据正在等待,还无法播放,不管是起始,还是拖拽引起的。

模版

到此,音频播放器的主要交互功能实现已经介绍完了,贴一下ui

<template><div class="audio-upload-item" :class="[isBorder === '1' ? 'isBorder' : '']"><span class="audio-title">{{play.title}}</span><div class="paly-control"><div class="icons"><el-button class="paly-icon paly" v-if="!isPlay || !play.isUplaod":type="!play.isUplaod ? 'info' : 'primary'" icon="iconfont ed-icon-paly"circle :disabled="!play.isUplaod" plain @click="audioPlay"></el-button><el-button class="paly-icon" v-if="isPlay && play.isUplaod && isLoad" type="primary"icon="iconfont ed-icon-zanting" circle @click="audioPause"></el-button><el-button class="paly-icon" v-if="isPlay && play.isUplaod && !isLoad" type="primary"icon="el-icon-loading" circle @click="audioPause"></el-button></div><div class="paly-precent"><el-slider v-model="playPrecent" :format-tooltip="formatTooltip":disabled="!play.isUplaod" @change="precentChange"></el-slider></div><div class="play-time">{{showPre + '/'+play.duration}}</div></div><audio controls="controls" ref="aduioObj" preload="auto" v-show="false":src="play.url" :loop="play.loop"></audio></div></template>复制代码

组件props,可以isBorder是对于音频播放器ui的设定,而play就是当前音频的一些基本信息

props: {play: Object,isBorder: String,},复制代码

概括下audio的属性与api

audio 属性

只读属性 duration: 媒体时长,数值, 单位s ended: 是否完成播放,布尔值 paused: 是否播放暂停,布尔值 读写属性:

playbackRate: 播放速度,大多数浏览器支持0.5-4, 1表示正常速度,设置该属性可以修改播放速度volume:0.0-1.0之间,设置该属性可以修改声音大小muted: 是否静音, 设置该属性可以静音currentTime:指定播放位置的秒数复制代码

audio 常用api

事件名 何时触发 loadstart 开始加载 progress 正在加载 suspend 用户代理有意无法获取媒体数据,无法获取整个文件 abort 主动终端下载资源并不是由于发生错误 error 获取资源时发生错误 play 开始播放 pause 播放暂停 loadedmetadata 刚获取完元数据 loadeddata 第一次渲染元数据 waiting 等待中 playing 正在播放 canplay 用户代理可以恢复播放媒体数据,但是估计如果现在开始播放,则媒体资源不能以当前播放速率直到其结束呈现,而不必停止进一步缓冲内容。 canplaythrough 用户代理估计,如果现在开始播放,则媒体资源可以以当前播放速率一直呈现到其结束,而不必停止进一步的缓冲。 timeupdate 当前播放位置作为正常播放的一部分而改变,或者以特别有趣的方式,例如不连续地改变。 ended 播放结束 ratechange 媒体播放速度改变 durationchange 媒体时长改变 volumechange 媒体声音大小改变

其他拓展功能,音频如何倍数播放?

let myAudio = $('#wdd');myAudio.playbackRate = 2;复制代码

其他拓展功能,如何隐藏音频的播放按钮?

如果你用audio组件显示

方法1: controlsList="nodownload",这个方法只支持 Chrome 58+, 低于该版本的是没有无法隐藏的

Your browser does not support the audio element.

controlist,可以取值:

nodownload: 不要下载 nofullscreen: 不要全屏 noremoteplayback: 不要远程回放

方法二:通过css隐藏// 这个方式兼容所有版本的谷歌浏览器 audio::-webkit-media-controls { overflow: hidden !important } audio::-webkit-media-controls-enclosure { width: calc(100% + 32px); margin-left: auto; } 但是,浏览器右键还是可以选择下载。。。 所以,还要禁止其右键操作: // 给audio标签禁止右键,来禁止下载

Your browser does not support the audio element.

audio插件解决小烦恼 这波操作太容易忘记了,给你一个插件快速解决: 项目地址: /kolber/aud... 优点: 简单,无依赖 缺点:异步插入的audio标签,每次还是需要重新调用audiojs.createAll()方法来重新实例化

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。