Home>Article>Web Front-end> Detailed explanation of uni-app (vue) encapsulating a basic audio component based on InnerAudioContext

Detailed explanation of uni-app (vue) encapsulating a basic audio component based on InnerAudioContext

coldplay.xixi
coldplay.xixi forward
2020-09-19 16:32:04 4612browse

Detailed explanation of uni-app (vue) encapsulating a basic audio component based on InnerAudioContext

Related learning recommendations:WeChat Mini Program Development

## The reason

is also because the official mini program does not maintain the

audiocomponent

Requirements and restrictions of audio components

1. Click to play or pause

2. Display the playback progress and total duration
3. Display the current audio status (paused/playing/loading) through icon changes
4. Refresh the component status when the page audio is updated
5. Global There is and only one audio in the playing state
6. Automatically stop playing and destroy the audio instance after leaving the page

Materials/Properties/Methods

Let’s get started

uni-app Vue

    Similarly construct
  • DOMstructure
  •   无音源 {{ fmtSecond(currentTime) }}/{{ fmtSecond(duration) }}复制代码
    Define accepted components
  • props: { audioSrc: { type: String, default: '' }, },复制代码
    Define the operations related to the initialization of the
  • CustomAudiocomponent, and add some behaviors to the callback ofinnerAudioContext(the pitfalls we stepped on in the previous Taro article will be directly coded here) )
  • import { formatSecondToHHmmss, afterAudioPlay, beforeAudioRecordOrPlay } from '../../lib/Utils'const iconPaused = '../../static/images/icon_paused.png'const iconPlaying = '../../static/images/icon_playing.png'const iconStop = '../../static/images/icon_stop.png'const iconLoading = '../../static/images/icon_loading.gif'// ...data() { return { audioCtx: null, // 音频上下文 duration: 0, // 音频总时长 currentTime: 0, // 音频当前播放的时长 audioImg: iconLoading, // 默认状态为加载中 } },watch: { audioSrc: { handler(newSrc, oldSrc) { console.log('watch', newSrc, oldSrc) this.audioImg = iconLoading this.currentTime = 0 this.duration = 0 if (this.audioCtx === undefined) { this.audioCtx = uni.createInnerAudioContext() this.onTimeUpdate = this.audioCtx.onTimeUpdate this.bindAuidoCallback(this.audioCtx) } else { this.audioCtx.src = newSrc } if (this.audioCtx.play) { this.audioCtx.stop() getApp().globalData.audioPlaying = false } } } }, mounted() { this.audioCtx = uni.createInnerAudioContext() this.audioCtx.src = this.audioSrc this.audioCtx.startTime = 0 this.bindAuidoCallback(this.audioCtx) },methods: { bindAuidoCallback(ctx) { ctx.onTimeUpdate((e) => { this.onTimeUpdate(e) }) ctx.onCanplay((e) => { this.onCanplay(e) }) ctx.onWaiting((e) => { this.onWaiting(e) }) ctx.onPlay((e) => { this.onPlay(e) }) ctx.onPause((e) => { this.onPause(e) }) ctx.onEnded((e) => { this.onEnded(e) }) ctx.onError((e) => { this.onError(e) }) }, tips(){ uni.showToast({ title: '无效音源,请先录音', icon: 'none' }) }, playOrStopAudio() { if (this.audioCtx === null) { this.audioCtx = uni.createInnerAudioContext() this.audioCtx.src = this.audioSrc this.bindAuidoCallback(this.audioCtx) } if (this.audioCtx.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.audioCtx.currentTime) if (this.audioCtx.currentTime > 0 && this.audioCtx.currentTime <= 1) { this.currentTime = 1 } else if (this.currentTime !== Math.floor(this.audioCtx.currentTime)) { this.currentTime = Math.floor(this.audioCtx.currentTime) } const duration = Math.floor(this.audioCtx.duration) if (this.duration !== duration) { this.duration = duration } }, onCanplay(e) { if (this.audioImg === iconLoading) { this.audioImg = iconPaused } console.log('onCanplay', e) }, onWaiting(e) { if (this.audioImg !== iconLoading) { this.audioImg = iconLoading } }, 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) } }, onPause(e) { console.log('onPause', e) this.audioImg = iconPaused }, onEnded(e) { console.log('onEnded', e) if (this.audioImg !== iconPaused) { this.audioImg = iconPaused } afterAudioPlay() }, onError(e) { uni.showToast({ title: '音频加载失败', icon: 'none' }) throw new Error(e.errMsg, e.errCode) }, fmtSecond(sec) { const { min, second } = formatSecondToHHmmss(sec) return `${min}:${second}` } },复制代码
Same

scssfile
复制代码

Finally

Detailed explanation of uni-app (vue) encapsulating a basic audio component based on InnerAudioContext
If you encounter any problems or have any suggestions, you can discuss them with me~

If you want to know other excellent articles, please visit the

uni-appcolumn~

The above is the detailed content of Detailed explanation of uni-app (vue) encapsulating a basic audio component based on InnerAudioContext. For more information, please follow other related articles on the PHP Chinese website!

Statement:
This article is reproduced at:juejin.im. If there is any infringement, please contact admin@php.cn delete