如何在小程序中实现音频播放
需要注意几点
由于现在官方不再维护 audio 组件 ,所以音频播放尽可能采取 wx.createInnerAudioContext() 接口 ( 若需要在后台播放,则采用 wx.getBackgroundAudioManager() )
音频播放,只有在播放时才可以获取到音频长度(参考了多个带音频的小程序 qq音乐,百度网盘等,都是采取自动播放的方式,以获取总时长)
由于 wx.createInnerAudioContext()和wx.getBackgroundAudioManager()接口都差不多,(简单来说,前者只会在当前页面播放,后者可在离开播放页面甚至返回微信界面(需要配置下),继续播放音乐),这里以 背景音乐为例子
wx.getBackgroundAudioManager()这个api返回的是一个对象(BackgroundAudioManager),同时需要注意 背景音频播放是获取的 全局唯一的背景音频管理器,也就是说,你不销毁或者停止,他会一直播放(离开微信和配置了后台播放除外)
BackgroundAudioManager在这个对象上有一些方法,比如:暂停,设置地址,监听播放状态(播放,停止,暂停,错误。。。。等)
?1.获取全局唯一的背景音频管理器
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>