如何在小程序中实现音频播放
需要注意几点
由于现在官方不再维护 audio 组件 ,所以音频播放尽可能采取 wx.createInnerAudioContext() 接口 ( 若需要在后台播放,则采用 wx.getBackgroundAudioManager() )
音频播放,只有在播放时才可以获取到音频长度(参考了多个带音频的小程序 qq音乐,百度网盘等,都是采取自动播放的方式,以获取总时长)
由于 wx.createInnerAudioContext()和wx.getBackgroundAudioManager()接口都差不多,(简单来说,前者只会在当前页面播放,后者可在离开播放页面甚至返回微信界面(需要配置下),继续播放音乐),这里以 背景音乐为例子
wx.getBackgroundAudioManager()这个api返回的是一个对象(BackgroundAudioManager),同时需要注意 背景音频播放是获取的 全局唯一的背景音频管理器,也就是说,你不销毁或者停止,他会一直播放(离开微信和配置了后台播放除外)
BackgroundAudioManager在这个对象上有一些方法,比如:暂停,设置地址,监听播放状态(播放,停止,暂停,错误。。。。等)
- 获取全局唯一的背景音频管理器
const InnerAudioContext = uni.getBackgroundAudioManager();
具体代码如下(此处是封装为播放组件,可直接复制)
<template> <view class=""> <view class="audio-wrapper"> <view class="audio-number">{{forNowTime}}</view> <slider class="audio-slider" :activeColor="color" block-size="16" :value="current" :max="duration" @changing="seek=true,current=$event.detail.value" @change="change"></slider> <!-- 时长 --> <view class="audio-number">{{forAllTime}}</view> </view> <view class="audio-control-wrapper" :style="{color:color}"> <!-- 随机播放 --> <view class="audio-control audio-more iconfont music_icon_random" hover-class="btn-bg-m"></view> <!-- 上一首 --> <view class="audio-control iconfont music_icon_previous" hover-class="btn-bg-m" v-if="control" @click="prev"></view> <!-- 播放 --> <view class="audio-control audio-control-switch iconfont" hover-class="btn-bg" :class="{'music_icon_play':paused,'music_icon_pause':!paused}" @click="operation"> </view> <!-- 下一首 --> <view class="audio-control iconfont music_icon_next" v-if="control" hover-class="btn-bg-m" @click="next"></view> <!-- 列表 --> <view class="audio-control audio-more iconfont music_icon_list" hover-class="btn-bg-m" ></view> </view> </view> </template> <script> const InnerAudioContext = uni.getBackgroundAudioManager(); //createInnerAudioContext export default { data() { return { forNowTime:'00:00', //当前播放时间 4:30 格式 forAllTime:'', //总时长 格式化 duration:0,//总时间 秒 current:0, //slider当前进度 seek: false, //是否处于拖动状态 paused: true, //是否处于暂停状态 } }, props: { audioSrc: { //音频链接 type:String, default:'' }, audioName:{ //歌曲名称 type:String, default:'' }, control: { //是否需要上一曲/下一曲按钮 type:Boolean, default:true }, nextAudio:{ //播放完成后是否继续播放下一首,需定义@next事件 type:Boolean, default:false, }, color: { //主色调 type:String, default:'#5189FF' } }, created() { // 是否遵循系统静音开关 InnerAudioContext.obeyMuteSwitch = false // 监听播放 InnerAudioContext.onPlay(()=>{ this.paused=false console.log('播放中。。。') }) // 监听暂停 InnerAudioContext.onPause(()=>{ this.paused=true }) // 监听播放结束 InnerAudioContext.onEnded(()=>{ // 是否需要 自动播放下一首 if(this.nextAudio) { this.next() }else{ // 暂停 this.paused=true } }) // 监听 进度更新 InnerAudioContext.onTimeUpdate(()=>{ // 获取总进度 this.duration = InnerAudioContext.duration // 当前进度 非拖动时 if (!this.seek) { this.current= InnerAudioContext.currentTime } }) //监听 进度更改完成 InnerAudioContext.onSeeked(() => { this.seek = false }) // 音频播放失败 this.errMsg() }, mounted(){ }, beforeDestroy(){ // InnerAudioContext.pause() }, computed:{ }, watch: { // 音频地址 audioSrc(value){ if(InnerAudioContext.src==value)return InnerAudioContext.src= value this.current=0 // 设置自动播放 以获取总时长 InnerAudioContext.autoplay=true }, // 音频名字 audioName(value,o){ InnerAudioContext.title =value }, // 音频总时长--格式化 duration(value){ this.forAllTime = this.format(value) }, // 当前播放位置 current(now){ this.forNowTime = this.format(now) if(!InnerAudioContext.paused){ this.paused=false } } }, methods: { //返回prev事件 prev() { this.$emit('prev') }, //返回next事件 next() { this.$emit('next') }, //时间格式化 format(num) { return '0'.repeat(2 - String(Math.floor(num / 60)).length) + Math.floor(num / 60) + ':' + '0'.repeat(2 - String( Math.floor(num % 60)).length) + Math.floor(num % 60) }, //播放/暂停操作 operation() { // 停止播放状态 InnerAudioContext.paused?InnerAudioContext.play():InnerAudioContext.pause() }, //快进 change(e) { InnerAudioContext.seek(e.detail.value) }, // 播放失败 errMsg(){ InnerAudioContext.onError((res)=>{ let ErrMsg=res.errMsg wx.showModal({ title: '播放失败', content:ErrMsg, showCancel:false, success: function(res) { } }) }) } }, } </script> <style> .audio-wrapper { display: flex; align-items: center; padding-bottom: 90rpx; } .audio-number { font-size: 24upx; line-height: 1; color: #333; } .audio-slider { flex: 1; margin: 0 30upx; } .audio-control-wrapper { margin-top: 20upx; display: flex; align-items: center; justify-content: space-around; } .audio-control { font-size: 32rpx; width:80rpx; height:80rpx; border:1rpx solid rgba(168,196,255,1); border-radius:50%; text-align: center; line-height: 80rpx; } .audio-more{ border:none; font-size: 32rpx; border-radius: 50%; } .audio-control-switch { color: #FFFFFF; font-size: 42rpx; margin: 0 60rpx; width:120rpx; height:120rpx; line-height: 120rpx; background:rgba(81,137,255,1); border-radius:50%; border: none; } .audioLoading { animation: loading 2s; animation-iteration-count: infinite; animation-timing-function: linear; } @keyframes loading { to { transform: rotate(360deg); } } </style>