| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402 | 
							- <template>
 
- 	<view class="audio_container">
 
- 		<view class="title-box">
 
- 			{{ title }}
 
- 		</view>
 
- 		<view>
 
- 			<slider :backgroundColor='backgroundColor' :activeColor='activeColor' @change="handleSliderChange"
 
- 				:value="sliderIndex" :max="maxSliderIndex" block-color="#C30D23" block-size="16" />
 
- 		</view>
 
- 		<view style="padding: 0px 7.5px 0px 7.5px ; display: block; ">
 
- 			<view style="float: left; font-size: 10px;color:#848484;">
 
- 				{{ currentTimeText }}
 
- 			</view>
 
- 			<view style="float: right;font-size: 10px;color:#848484;">
 
- 				{{ totalTimeText }}
 
- 			</view>
 
- 		</view>
 
- 		<view style="margin-top: 35px;">
 
- 			<view class="control">
 
- 				<view class="uni-grid-icon">
 
- 					<image @tap="handleFastRewind" src="../static/images/get-back.svg"
 
- 						style="width: 24px;height: 24px;top:3px;">
 
- 					</image>
 
- 				</view>
 
- 				<view class="uni-grid-icon">
 
- 					<image @tap="handleChangeAudioState" v-show="!isPlaying" src="../static/images/play.svg"
 
- 						style="width: 24px;height: 24px;top:3px;">
 
- 					</image>
 
- 					<image @tap="handleChangeAudioState" v-show="isPlaying" src="../static/images/pause.svg"
 
- 						style="width: 24px;height: 24px;top:3px;">
 
- 					</image>
 
- 				</view>
 
- 				<view class="uni-grid-icon">
 
- 					<image @tap="handleFastForward" src="../static/images/fast-forward.svg"
 
- 						style="width: 24px;height: 24px;top:3px;">
 
- 					</image>
 
- 				</view>
 
- 				<!-- <view class="uni-grid-icon">
 
- 					<image @tap="handleLoopPlay" src="../static/images/Loop.svg"
 
- 						style="width: 24px;height: 24px; top:3px; ">
 
- 					</image>
 
- 				</view> -->
 
- 			</view>
 
- 		</view>
 
- 	</view>
 
- </template>
 
- <script>
 
- export default {
 
- 	name: 'my-audio',
 
- 	//audioPlay开始播放
 
- 	//audioPause停止播放
 
- 	//audioEnd音频自然播放结束事件
 
- 	//audioCanplay音频进入可以播放状态,但不保证后面可以流畅播放
 
- 	//change播放状态改变 返回值false停止播放 true开始播放
 
- 	//audioError 播放器错误
 
- 	emits: ['audioPlay', 'audioPause', 'audioEnd', 'audioCanplay', 'change', 'audioError'],
 
- 	props: {
 
- 		title: {
 
- 			type: String
 
- 		},
 
- 		//是否自动播放
 
- 		autoplay: {
 
- 			type: Boolean,
 
- 			default: false
 
- 		},
 
- 		//滑块左侧已选择部分的线条颜色
 
- 		activeColor: {
 
- 			type: String,
 
- 			default: '#C30D23'
 
- 		},
 
- 		//滑块右侧背景条的颜色
 
- 		backgroundColor: {
 
- 			type: String,
 
- 			default: '#E5E5E5'
 
- 		},
 
- 		//音频地址
 
- 		src: {
 
- 			type: [String, Array],
 
- 			default: ''
 
- 		},
 
- 		//是否倒计时
 
- 		isCountDown: {
 
- 			type: Boolean,
 
- 			default: false
 
- 		},
 
- 		//音乐封面
 
- 		audioCover: {
 
- 			type: String,
 
- 			default: ''
 
- 		},
 
- 		//是否显示收藏按钮
 
- 		isCollectBtn: {
 
- 			type: Boolean,
 
- 			default: false
 
- 		},
 
- 		//是否显示分享按钮
 
- 		isShareBtn: {
 
- 			type: Boolean,
 
- 			default: false
 
- 		},
 
- 	},
 
- 	data() {
 
- 		return {
 
- 			totalTimeText: '00:00', //视频总长度文字
 
- 			currentTimeText: '00:00:00', //视频已播放长度文字
 
- 			isPlaying: false, //播放状态
 
- 			sliderIndex: 0, //滑块当前值
 
- 			maxSliderIndex: 100, //滑块最大值
 
- 			IsReadyPlay: false, //是否已经准备好可以播放了
 
- 			isLoop: false, //是否循环播放
 
- 			speedValue: [0.5, 0.8, 1.0, 1.25, 1.5, 2.0],
 
- 			speedValueIndex: 2,
 
- 			playSpeed: '1.0', //播放倍速 可取值:0.5/0.8/1.0/1.25/1.5/2.0
 
- 			stringObject: (data) => {
 
- 				return typeof (data)
 
- 			},
 
- 			innerAudioContext: uni.createInnerAudioContext()
 
- 		}
 
- 	},
 
- 	async mounted() {
 
- 		this.innerAudioContext.src = typeof (this.src) == 'string' ? this.src : this.src[0];
 
- 		if (this.autoplay) {
 
- 			if (!this.src) return console.error('src cannot be empty,The target value is string or array')
 
- 			// #ifdef H5
 
- 			var ua = window.navigator.userAgent.toLowerCase();
 
- 			if (ua.match(/MicroMessenger/i) == 'micromessenger') {
 
- 				const jweixin = require('../utils/jweixin');
 
- 				jweixin.config({});
 
- 				jweixin.ready(() => {
 
- 					WeixinJSBridge.invoke('getNetworkType', {}, (e) => {
 
- 						this.innerAudioContext.play();
 
- 					})
 
- 				})
 
- 			}
 
- 			// #endif
 
- 			// #ifndef H5
 
- 			this.innerAudioContext.autoplay = true;
 
- 			// #endif
 
- 		}
 
- 		//音频播放事件
 
- 		this.innerAudioContext.onPlay(() => {
 
- 			this.isPlaying = true;
 
- 			this.$emit('audioPlay')
 
- 			this.$emit('change', {
 
- 				state: true
 
- 			});
 
- 			setTimeout(() => {
 
- 				this.maxSliderIndex = parseFloat(this.innerAudioContext.duration).toFixed(2);
 
- 			}, 100)
 
- 		});
 
- 		//音频暂停事件
 
- 		this.innerAudioContext.onPause(() => {
 
- 			this.$emit('audioPause');
 
- 			this.$emit('change', {
 
- 				state: false
 
- 			});
 
- 		});
 
- 		//音频自然播放结束事件
 
- 		this.innerAudioContext.onEnded(() => {
 
- 			this.isPlaying = !this.isPlaying;
 
- 			this.$emit('audioEnd');
 
- 			if (this.isLoop) {
 
- 				this.changePlayProgress(0);
 
- 				this.innerAudioContext.play();
 
- 			}
 
- 		});
 
- 		//音频进入可以播放状态,但不保证后面可以流畅播放
 
- 		this.innerAudioContext.onCanplay((event) => {
 
- 			this.IsReadyPlay = true;
 
- 			this.$emit('audioCanplay');
 
- 			let duration = this.innerAudioContext.duration;
 
- 			//console.log('总时长', duration)
 
- 			//将当前音频长度秒转换为00:00:00格式
 
- 			this.totalTimeText = this.getFormateTime(duration);
 
- 			this.maxSliderIndex = parseFloat(duration).toFixed(2);
 
- 			//console.log(this.getFormateTime(duration))
 
- 			//console.log('总时长1', this.totalTimeText)
 
- 			//防止视频无法正确获取时长
 
- 			setTimeout(() => {
 
- 				duration = this.innerAudioContext.duration;
 
- 				//将当前音频长度秒转换为00:00:00格式
 
- 				this.totalTimeText = this.getFormateTime(duration);
 
- 				this.maxSliderIndex = parseFloat(duration).toFixed(2);
 
- 				//console.log('总时长2', this.totalTimeText)
 
- 			}, 300)
 
- 		});
 
- 		//音频播放错误事件
 
- 		this.innerAudioContext.onTimeUpdate((res) => {
 
- 			this.sliderIndex = parseFloat(this.innerAudioContext.currentTime).toFixed(2);
 
- 			this.currentTimeText = this.getFormateTime(this.innerAudioContext.currentTime);
 
- 		});
 
- 		//音频播放错误事件
 
- 		this.innerAudioContext.onError((res) => {
 
- 			console.log(res.errMsg);
 
- 			console.log(res.errCode);
 
- 			this.$emit('change', {
 
- 				state: false
 
- 			});
 
- 			this.audioPause();
 
- 			this.$emit('audioError', res);
 
- 		});
 
- 	},
 
- 	methods: {
 
- 		//销毁innerAudioContext()实例
 
- 		audioDestroy() {
 
- 			if (this.innerAudioContext) {
 
- 				this.innerAudioContext.destroy();
 
- 				this.isPlaying = false;
 
- 			}
 
- 		},
 
- 		//点击变更播放状态
 
- 		handleChangeAudioState() {
 
- 			if (this.isPlaying && !this.innerAudioContext.paused) {
 
- 				this.audioPause();
 
- 			} else {
 
- 				this.audioPlay();
 
- 			}
 
- 		},
 
- 		//开始播放
 
- 		audioPlay() {
 
- 			this.innerAudioContext.play();
 
- 			this.isPlaying = true;
 
- 		},
 
- 		//暂停播放
 
- 		audioPause() {
 
- 			this.innerAudioContext.pause();
 
- 			this.isPlaying = false;
 
- 		},
 
- 		//变更滑块位置
 
- 		handleSliderChange(e) {
 
- 			this.changePlayProgress(e.detail ? e.detail.value : e)
 
- 		},
 
- 		//更改播放倍速
 
- 		handleChageSpeed() {
 
- 			//获取播放倍速列表长度
 
- 			let speedCount = this.speedValue.length;
 
- 			//如果当前是最大倍速,从-1开始
 
- 			if (this.speedValueIndex == (speedCount - 1)) {
 
- 				this.speedValueIndex = -1;
 
- 			}
 
- 			//最新倍速序号
 
- 			this.speedValueIndex += 1;
 
- 			//获取最新倍速文字
 
- 			this.playSpeed = this.speedValue[this.speedValueIndex].toFixed(1);
 
- 			//暂停播放
 
- 			this.audioPause();
 
- 			//变更播放倍速
 
- 			this.innerAudioContext.playbackRate(this.speedValue[this.speedValueIndex]);
 
- 			//开始播放
 
- 			this.audioPlay();
 
- 		},
 
- 		//快退15秒
 
- 		handleFastRewind() {
 
- 			if (this.IsReadyPlay) {
 
- 				let value = parseInt(this.sliderIndex) - 15;
 
- 				this.changePlayProgress(value >= 0 ? value : 0);
 
- 			}
 
- 		},
 
- 		//快进15秒
 
- 		handleFastForward() {
 
- 			if (this.IsReadyPlay) {
 
- 				let value = parseInt(this.sliderIndex) + 15;
 
- 				this.changePlayProgress(value <= this.innerAudioContext.duration ? value : this.innerAudioContext
 
- 					.duration);
 
- 			}
 
- 		},
 
- 		//开启循环播放
 
- 		handleLoopPlay() {
 
- 			this.isLoop = !this.isLoop;
 
- 			if (this.isLoop) {
 
- 				uni.showToast({
 
- 					title: '已开启循环播放',
 
- 					duration: 1000
 
- 				});
 
- 			} else {
 
- 				uni.showToast({
 
- 					title: '取消循环播放',
 
- 					duration: 1000
 
- 				});
 
- 			}
 
- 		},
 
- 		//更改播放进度
 
- 		changePlayProgress(value) {
 
- 			this.innerAudioContext.seek(value);
 
- 			this.sliderIndex = value;
 
- 			this.currentTimeText = this.getFormateTime(value);
 
- 		},
 
- 		//秒转换为00:00:00
 
- 		getFormateTime(time) {
 
- 			let ms = time * 1000; // 1485000毫秒
 
- 			let date = new Date(ms);
 
- 			// 注意这里是使用的getUTCHours()方法,转换成UTC(协调世界时)时间的小时
 
- 			let hour = date.getUTCHours();
 
- 			// let hour = date.getHours(); 如果直接使用getHours()方法,则得到的时分秒格式会多出来8个小时(在国内开发基本都是使用的是东八区时间),getHours()方法会把当前的时区给加上。
 
- 			let minute = date.getMinutes();
 
- 			let second = date.getSeconds();
 
- 			let formatTime =
 
- 				`${hour.toString().padStart(2, '0')}:${minute.toString().padStart(2, '0')}:${second.toString().padStart(2, '0')}`;
 
- 			return formatTime;
 
- 		},
 
- 		handleCollec() {
 
- 			this.$emit('audioCollec');
 
- 		},
 
- 		handleShare() {
 
- 			this.$emit('audioShare');
 
- 		},
 
- 	},
 
- 	onUnload() {
 
- 		this.audioDestroy()
 
- 	},
 
- 	onHide() {
 
- 		this.audioDestroy()
 
- 	},
 
- 	beforeDestroy() {
 
- 		this.audioDestroy()
 
- 	}
 
- }
 
- </script>
 
- <style lang="scss" scoped>
 
- .control {
 
- 	display: flex;
 
- 	justify-content: space-around;
 
- 	padding: 0 30px;
 
- 	box-sizing: border-box;
 
- }
 
- .audio_container {
 
- 	box-shadow: 0 0 5px #c3c3c3;
 
- 	padding: 15px 10px 15px 10px;
 
- 	.audio-title {
 
- 		font-size: 14px;
 
- 	}
 
- 	.uni-noticebar {
 
- 		padding: 0px;
 
- 		padding-right: 25px;
 
- 		margin-bottom: 0px;
 
- 		display: inline-block;
 
- 	}
 
- 	.audio-subTitle {
 
- 		width: 100%;
 
- 		text-align: left;
 
- 		font-size: 20px;
 
- 		color: blue;
 
- 	}
 
- 	.speed-text {
 
- 		position: absolute;
 
- 		top: 0px;
 
- 		left: 15px;
 
- 		right: 0;
 
- 		color: #475266;
 
- 		font-size: 8px;
 
- 		font-weight: 600;
 
- 	}
 
- 	.uni-grid-icon {
 
- 		text-align: center;
 
- 	}
 
- }
 
- </style>
 
 
  |