微信小程序中音频播放

发布时间:2024年01月05日

如何在小程序中实现音频播放
需要注意几点
由于现在官方不再维护 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>

文章来源:https://blog.csdn.net/2401_82373036/article/details/135351402
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。