uniapp 制作音频播放列表

总体是使用uniapp的uni.createInnerAudioContext()来制作的,所以如果官方的api所支持的平台,那么这个也支持

贴出的代码不是组件的形式,可自行封装

全部代码如下:

<template>
	<view class="contentBox">
		<view class="audio-item" v-for="(item,k) in audList" :key="k">
			<view class="item-left"><!-- :style="{backgroundImage: 'url(' + item.pic + ')'}" -->
				<view @click="toPlayAudio(k,item.src)" class="play-btn">
					<image style="width: 50rpx;height: 50rpx;" v-if="!item.isPlay"
						src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAAXNSR0IArs4c6QAAAbFJREFUWEfFl4ttQjEMRe1NyiQtkxQmaZmkbFI6SdnE6FZO6hfysaNILxICicQ+ufEnYdp58M7+KQQgIi9EdCKiVyLCb3zuugl8/xDRjZlv3o25AETkjYi+1KHHNmAuzHwdTe4C6I7hGAAzAyBHZk4qPdloAuiuv2e8Fmvg/Nw6lirAQueJpQnxBKCy/y7YeWmiehw1AMjeO3MYQvTPDGTI0S7cAIgIUgxB1xzMzCYdPyYoEJQ5TUuA4e6Z+ZCcisgnEUUh7tZGBnAG3mYxQFQNgEeOJatgAYbyo+pZeqNEqpBeNVCkoN5/KRaRkfyYXwWYOJIcjFYBpN5Ixi5A4EiyneUACoE07lXRKoA4UmqogAIMswPpvDwG1HkoluwRhBaWagU755WZz6UCQ9k6aehJYcuM7vh3V7AKIANGTahWiFC6ARAZh3RHmC7FQcktXL0UO9MH0y5qzVv1SmXazSgQxRG57dx+Ow5UshkA34XEQIwCMgqxkT4t7l1KkRXRNluDil9Kiza7z7XcbkWvau+B98Gah0mj3KanGf5G1yufZiizzYdIadP1NItGW2T+7gAPZz/cIRYk1noAAAAASUVORK5CYII=">
					</image>
					<image style="width: 50rpx;height: 50rpx;" v-else
						src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAAXNSR0IArs4c6QAAAadJREFUWEfNVwtOwzAMfT4J7CTQk8BOAjsJ5SSUk1BOYvaieEq7tHGqdCNStUmJ7ZfnT2xBxVLVRwCvAJ4A8D+/MargL79PERm8aqV0MDH6Vjqb7AcgZ4C9iBjArPgqAFV9B1BjeG7EGKEeP4B46w8AzxW3XjtKIF2OjSsGovGv6N9G9oOaLIgJgB2N20WuQMwB8OataF9ibxSRg21eADQIuBp3MTuOFEgBqEODpddDrAepSA/gF8CLI34urggAVJURzwJTWkcRoSHKTNwlIqaLLuReaQUWTMhzeypsCSDEgqgqb04GPKslANrrCMBLf2sGqO9EADWp15qBgQB+HFFr7mkNYCQAbwDu4YK7A8C/cMHdg7Cm6WgdhD1d4C2dewRhKERsLJmKntWUAb4ftY/R6SwS+rt5/Uh0eUv75DHysmDPMTHMm1W24t/O55jyB/aIaT/gRe5xVenMhckUAFlo2QkvgRhEpLPNmzelaT9IELduy5lFk7EtOxntMJhMaE99sziabZwJ537fNpqlWjYCKRrOBuFa7kQgzBRru3PjOesA6XaP53+/FzDLAjxB3gAAAABJRU5ErkJggg==">
					</image>
				</view>
			</view>
			<view class="item-right">
				<text class="title-text">{{item.title}}</text>
				<text class="sub-text">{{item.subtitle}}</text>
				<view class="progress-bar">
					<view class="slider-item">
						<slider @change="change($event,k)" :value="item.playDuration" :max="item.duration"
							activeColor="#3DD95F" backgroundColor="#E6E6E6" block-size="8" block-color="#fff"></slider>
					</view>
					<text class="time-text">{{item.playDuration,item.duration|formatPlayDate}}</text>
				</view>
			</view>
		</view>
	</view>
</template>

<script>
	export default {
		props: ['audios'],
		data() {
			return {
				audIndex: -1, //当前播放列表下标
				innerAudioContext: null, //音频播放实例
				/**
				 * title	音频名称
				 * subtitle	副标题
				 * duration	音频时长(s)
				 * src		音频播放地址
				 * pic		音频封面图
				 * isPlay	播放状态(true 播放中)
				 * playDuration	播放时长(用来记录该音频播放位置,或者通过滑动slide改变播放位置)
				 */
				audList: [
					{
						title: '音频1',
						subtitle:'2024-08-16',
						duration:"107.970583",
						src: 'http://music.163.com/song/media/outer/url?id=2616685129.mp3',
						pic: 'http://p2.music.126.net/0vdbPw8RHhsDidc4Odp4gw==/109951166620193623.jpg',
						isPlay:false,
						playDuration:0
					},{
						title: '音频1',
						subtitle:'2024-08-16',
						duration:"107.970583",
						src: 'http://music.163.com/song/media/outer/url?id=2616685129.mp3',
						pic: 'http://p2.music.126.net/0vdbPw8RHhsDidc4Odp4gw==/109951166620193623.jpg',
						isPlay:false,
						playDuration:0
					},{
						title: '音频1',
						subtitle:'2024-08-16',
						duration:"107.970583",
						src: 'http://music.163.com/song/media/outer/url?id=2616685129.mp3',
						pic: 'http://p2.music.126.net/0vdbPw8RHhsDidc4Odp4gw==/109951166620193623.jpg',
						isPlay:false,
						playDuration:0
					},{
						title: '音频1',
						subtitle:'2024-08-16',
						duration:"107.970583",
						src: 'http://music.163.com/song/media/outer/url?id=2616685129.mp3',
						pic: 'http://p2.music.126.net/0vdbPw8RHhsDidc4Odp4gw==/109951166620193623.jpg',
						isPlay:false,
						playDuration:0
					},
				] //音频播放列表
			}
		},
		//页面销毁事件
		beforeDestroy() {
			//组件销毁时将音频播放器也销毁
			if (this.innerAudioContext != null) {
				this.innerAudioContext.pause()
				this.innerAudioContext.destroy()
				this.innerAudioContext = null
			}
		},
		methods: {
			//播放音频
			toPlayAudio(i, src) {
				//判断是否为首次播放
				if (this.innerAudioContext != null) {
					//判断改音频是否播放中,播放中则暂停
					if (this.audList[i].isPlay == true) {
						this.innerAudioContext.pause()
						this.audList[i].isPlay = false
						return
					} else {
						//播放新的音频文件,提前销毁实例,避免-99错误(官网建议的https://uniapp.dcloud.net.cn/api/media/audio-context.html#createinneraudiocontext)
						this.innerAudioContext.pause()
						this.innerAudioContext.destroy()
						this.innerAudioContext = null
						//将音频列表的状态都改为未播放
						this.audList.map(item => {
							item.isPlay = false
						})
					}
				}
				//存储播放下标
				this.audIndex = i
				//创建实例
				this.innerAudioContext = uni.createInnerAudioContext();
				//播放
				this.innerAudioContext.src = src
				//设置开始播放位置
				this.innerAudioContext.startTime = this.audList[i].playDuration
				this.innerAudioContext.play()
				//更改播放状态
				this.audList[i].isPlay = true

				//监听报错信息
				this.innerAudioContext.onError((res) => {
					console.log(res.errMsg);
					console.log(res.errCode);
				});
				//监听自然播放结束事件,并改变播放状态
				this.innerAudioContext.onEnded((res) => {
					this.audList[this.audIndex].isPlay = false
					this.audList[this.audIndex].playDuration = 0
				})
				//监听播放进度事件
				this.innerAudioContext.onTimeUpdate(() => {
					this.audList[this.audIndex].playDuration = this.innerAudioContext.currentTime
				})
			},
			//slide滑动事件
			change(e,index) {
				//将滑动后的值赋值给对应音频列表下标的playDuration
				this.audList[index].playDuration = e.detail.value
				//判断innerAudioContext是否有实例
				if (this.innerAudioContext != null) {
					//如果是正在播放的就改变播放位置
					if(index == this.audIndex){
						this.innerAudioContext.seek(e.detail.value)
					}
				}
			},
		},
		filters: {
			//将秒数格式化为类似 02:23/05:02 前面是当前播放位置,后面是总时长
			//可根据自己需求随意更改
			formatPlayDate(pDate, duration) {
				let time = Math.floor(parseInt(pDate))
				let total = Math.floor(parseInt(duration))
				//格式化已播放时长
				let timeMin = Math.floor(time / 60) > 9 ? Math.floor(time / 60) : '0' + Math.floor(time / 60)
				let timeSec = (time % 60) > 9 ? (time % 60) : '0' + (time % 60)
				//格式化总时长
				let totalMin = Math.floor(total / 60) > 9 ? Math.floor(total / 60) : '0' + Math.floor(total / 60)
				let totalSec = (total % 60) > 9 ? (total % 60) : '0' + (total % 60)
				return `${timeMin} : ${timeSec} / ${totalMin} : ${totalSec}`
			}
		}

	}
</script>

<style lang="scss" scoped>
	//更改slider样式,如果是微信小程序记得加
	//options: {
    //   styleIsolation: 'shared', // 解除样式隔离
   //}
	/deep/ uni-slider {
		margin: 0 !important;
	}

	/deep/ uni-slider .uni-slider-thumb {
		margin-left: 0 !important;
		border: 1px solid #3DD95F;
	}

	.audio-item {
		margin-bottom: 20rpx;
		box-shadow: 0 0 6rpx 1rpx rgba(0, 0, 0, 0.1);
		background: #fff;
		display: flex;
		flex-direction: row;
	}

	.title-text {
		font-size: 24rpx;
		font-weight: bold;
	}

	.sub-text {
		font-size: 20rpx;
		color: #9E9E9E;
	}

	.time-text {
		font-size: 18rpx;
		color: #BEBEBE;
		display: flex;
		margin: 0 20rpx;
	}

	.item-left {
		width: 128rpx;
		height: 128rpx;
		background: url('/static/pic.png');
		background-repeat: no-repeat;
		background-size: 100% 100%;
		display: flex;
		align-items: center;
		justify-content: center;
		margin-right: 12rpx;
	}

	.item-right {
		flex-grow: 1;
		padding: 10rpx 0;
		display: flex;
		flex-direction: column;
		justify-content: space-between;

		.progress-bar {
			display: flex;
			align-items: center;

			.slider-item {
				flex-grow: 1;
			}
		}
	}
</style>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值