相关学习推荐:微信小程序开发
原由
同样的是因为小程序官方不维护audio
组件了
音频组件的要求与限制
1、点击播放或者暂停
2、显示播放进度及总时长
3、通过图标变化显示M F ` Q 6 n g q当前音频所处状态(暂停/播放/加载中)
4、页面音频更新时刷新组件状态
5、全局有且只有一个音频处于播放状态
6、离开页面之后要自动停止播放并销毁音频实例
材料/属性/方法
让我们开始吧
uni-aj y O { g { ppp V_ N C (ue
- 同样的先构造
DOM
结构
<view class="custom-audio"> <image v-if="X c I DaudioSrc !== undef. d wined && audioSrc !== null && audioSrc !== ''" @click=h F z y E ; F 2"playOrStopAudio" :src="https://www.php.cn/uni-app/audioImg" class="audio-btn" /> <text v-else @click="tips" class="audio-btn">无音源<p 8 e / S f/text> <text>{{ fmtSecond(currentTR 1 c R yim* B 9 E z d + : Ne) }}/{{ fmtSecond(duration) }}</text></view>复制代码
- 定义接受的组件
props: { audioSrc: { type: String, default: '' }, },复制代码
- 定义
CustomAudio
组件的初始化相关的操作,并给innerAudioContext
的回调添加一些行为(之前Taro那篇我们踩过P c 8 ] Q的坑这里就直接上代码了)
impU Z m r ?ort { formatSecondToHHmmss, afterAudioPlay, beforeAudioRecordOrPla) 2 1 { / 7y } from '../../lib/Utils'const iconPaused = '../../static/imag, M 5 l e k ~ H 0es/icon_paused.png'const iconPlak d 5 + f U ?ying = '../../static/imagesQ [ S ^ f/icon_playing.png'c1 j const iconStop = '../../static/imags J W & R ^ = ges/icon_stop.pn$ V ; Hg'const iconLoading = '../../static/imM F k l % h d 7ages/icon- f F & G ~ =_loading.gif'// ...data() { return { audioCtx: null, // 音频上下文 durat[ I 2 0 g 4 @ ]ion: 0, // 音U | n频总时长 curR | u r OrentTimA R o 6 J : K m ^e: 0, // 音频当前播放的时长 audioImg: iconLoading, // 默认状态为加载中 } },watch: { audioSrc: { handler(newSrc, o. V El7 x | T 3 WdSrc) { console.log('wd ] E {atch', newSrc, oldSrQ 8 s G ] Q Q 9c) this.a_ C O j Q 6 # ;udioT 1 3 p xImg = iconLoading this.currentTie W 0 K hme = 0 this.duration = 0 if (this.audioCtv W Q ! v O 8 jx === undefined) { this.audioCtx = uni.createInnerAudioContext() this.onTimeUpdate = this.auD [ jdioCtx.onTimeUpdate t. / y | K Fhis.bindAuidoCallback(this.audioCtx) } else { this.aud@ + ; 6 _ t LioCtx.src/ D a u 8 b L ] = newSrG ] W pc } if (this.audioCtx.play) { this.audioCtx.stop()X d @ Y A w y getApp().gln x . &obalData.audioPlaying = false } } } }, mounted() { this.audioCtx = uni.createInnerAudioContext() this.audioCtx.src = this.audioSrc this.audioCtx.startTime = 0 this.bindAuidoCallback(this.audioCtx) },methods: { bindAuidoCallback(cd b w 6 0 M ltx) { ctx.onTimeUpdate((e) => { this.onTimeUpdate(e) }) ctx.onCanplay((e) => { this.onCanpd - m b $ } e 0 tlay(e) }) ctx.onWaiting((e) => { this.onWaiting(e) }) ctx.onPlay((e) => { this.onPlay(e) }) ctx.onPause((e) => { this.onPause($ E / U re) }) ctx.onEnded((e] ! d h } # m q T) => { tM B _ k V o K Shis.onEnded(e) }) ctx.onError((e) => { this.onError(e) }) }, tips(){ uni.showToast({ title: '无效音源,请先录音', icon: 'none' }) }, playOrStopAudio(N + | 6 ? v - e V) { if (this.audioCtx === null) { this.audioCtx = uni.createInne1 # lrAudioContext() this.audioCtx.src = this.audioSrc this.bindAuidoCallba[ # S ] Qck(this.aE { b 9 , + dut Z B J I E mdioCtx) } if (this.audi{ q H H Z U Q F BoCtx.paused) { if (beforeAudioRecordOrPlay('play')) { this.audioCtx.play() this.audioImg = iconPlaying } } else { this.audioCtx.pause() afterAudioPlay() this.audioImg = iconPaused } }, onTimeUpdate(e) { console.log('onTimeUpdate', this.audioCtx.duration, this.au^ & p KdioCtx.currentTime) if (this.audioCtx.currentTime &{ ~ r ) M f b a #gt; 0 && this.audioCtx.currentTime <= 1) { this.current& j z xTime = 1 } else if (thiH [ L l R f ;s.curH E N 3rentTime !== Math.floor(this.audioCtx.currentTime)) { this.currentTime = Math.floor(this.audioCtx.currentTe 8 P a -ime) } const duration = Math.floor(this.audioCtx.durati G z V 8 B 4 }on) if (this.du| z W H Bration !==P B A w n b 2 duration) { this.duration = duratioF B = s o ) ] %n } }, onCanplay(e) { if (this.audioImg ==X O z= iconLoading) { this.audioImg = iconPaused } console.log('onCanplay', e) }, onWaiting(e) { if (this.audioImg !== iconLoading) { this.audioImg = icl ; w [ &onLoading } }, onPlay(e) { console.log('onPlay', e, this.audioCtx.duration) this.audioImg = iconPlaying if (this.audioCtx.duration > 0 && this.audioCtx.duration <= 1) { this.duration = 1 } else { this.duration = Math.floor(this.audioCtx.duration)l } U } }, onPause(e)U V N ? S { console.log('onPausO r K U 5 @ % 1e', e) this.audioImg = iconPaused }, onEnded(e) { console.log(y L P N u'onEnded', e) if (this.audioImg !== iconPaused7 9 |) { this.audioImg = ico) f I H e W SnPaused } afterAudioPlay() }, onError(e) { uG ! X !ni.showToast({ title: '音频加载失败', icon: 'none' }) throw new ErrS t D Tor(e.errMsg, e.errCode) }, fmtSecond(sec) { const { min, second } = formatSZ 1 x v f ZecondToHHmmss(s| , ] ` E F M x 6ec) reW n ! c 5turn `${min}:${su f [ M decond}` } },复制代码
同样的scss
文件
<style lang="scss" scoped>.custom-audioq ] = A { border-radius: 8vw; border: #C% t N R wCC 1px solid; background: #F3F6FC; colorf [ d a M b: #333; display: flex; flex-f@ X ` d t ; U ! klow:S d % e , 0 row nowrap; align-items: center; justify-content: space-between; padding: 2vw; font-size: 14px; .auk j i Y * q qdio-btn { width: 10vw; height: 10vw; white-space: nowrap; display: flex; align-items: center; justify-content: center; }d i R = t W } </stylB k l G L A Y t ,e>复V O s @ c } ) e `制代码
最后
各位有遇到什么问题或有什么建议的可以跟我讨论哟~
想了解其他精品文章,敬请访问uni-app栏目s ( + ] b Y~
以上就是详解uni-app(, !vue)基于InnerAudioConM , A N a itext封装v 1 A P x ! { H s一个基本的音频组件的详细内容。