uniapp:仿微信发送音频,录制音频。

在这里插入图片描述
在这里插入图片描述
uni.getRecorderManager()音频管理

1.创建子组件chatAudio.vue

<template>
	<view class="chatAudio">
		<view class="audioPlay" v-if="show">
			<view class="content">
				<!-- 录制中动图,底色变化 -->
				<view class="gif" :class="{
     
     'red':closeShow}">
					<image src="../../static/img/33.gif" mode=""></image>
				</view>
				<view class="close">
					<!-- ×号 颜色变化-->
					<image src="../../static/img/32.png" mode="" v-if="!closeShow"></image>
					<image src="../../static/img/28.png" mode="" v-if="closeShow"></image>
				</view>
				<view class="bom">
					<text v-if="!closeShow">松开 发送</text>
					<text v-if="closeShow">松开 取消</text>
					
					<!-- 底图颜色变化 -->
					<image src="../../static/img/30.png" mode="" v-if="!closeShow"></image>
					<image src="../../static/img/31.png" mode="" v-if="closeShow"></image>
					
					<!-- 计时器 -->
					<view class="times">
						<u-circle-progress active-color="#6C9FEB" :percent="times" bg-color="" width="140" border-width="7"></u-circle-progress>
					</view>
				</view>
			</view>
		</view>
	</view>
</template>
<script>
	const recorderManager = uni.getRecorderManager();
	const innerAudioContext = uni.createInnerAudioContext();
	innerAudioContext.autoplay = true;
	export default {
      
      
		name: 'chatAudio',
		props: {
      
      
			audioShow: {
      
      
				type: Boolean,
				default: false
			},
			audioXY: {
      
      
				type: Object,
			},
			audioTouchendShow: {
      
      
				type: Boolean,
				default: false
			},
		},
		watch: {
      
      
			// audioShow:true录制界面显示,开始录音,false关闭。
			audioShow(e, oldVal) {
      
      
				if(e){
      
      
					console.log('开始录音')
					this.status = 0;
					this.audioSrc = '';
					this.number = 1;
					this.show = true;
					
					// 计算录制时长,>=60 录制结束
					this.times = 1;
					this.timesInt = setInterval(() => {
      
      
						this.times ++;
						console.log(this.times)
						if(this.times>= 60){
      
      
							clearInterval(this.timesInt);
							this.closeShow = false;
							recorderManager.stop();
							console.log('结束录制');
						}
					}, 1000);
					
					// 开始录制
					recorderManager.start();
					
					// 获取关闭按钮.close在屏幕中的位置信息
					this.$nextTick(()=>{
      
      
						let close = uni.createSelectorQuery().select(".close");
						close.boundingClientRect((data)=> {
      
      
							this.dom = data;
						}).exec()
					})
				}else{
      
      
					this.show = false;
				}
			},
			// 手指在屏幕中的位置,判断是否:录制中/删除
			audioXY(e){
      
      
				let x = e.x;
				let y = e.y;
				let left = this.dom.left;
				let top = this.dom.top;
				if(x>left && x<left+this.dom.width && y>top && y<top+this.dom.height){
      
      
					this.closeShow = true;
				}else{
      
      
					this.closeShow = false;
				}
			},
			// 手指结束触摸,通知父组件关闭弹窗,根据this.closeShow类型,判断是取消还是发送
			audioTouchendShow(e){
      
      
				this.$emit('closeAudioShow')
				if(this.number == 1){
      
      
					this.number++;
					if(this.closeShow){
      
      
						console.log('取消录制')
						clearInterval(this.timesInt);
						this.closeShow = false;
						recorderManager.stop();
					}else{
      
      
						console.log('发送音频');
						clearInterval(this.timesInt);
						this.closeShow = false;
						recorderManager.stop();
						this.status = 1;
					}
				}
			}
		},
		data() {
      
      
			return {
      
      
				show:false, // 弹窗
				closeShow:false, // 正常/删除
				winSize:{
      
      },
				dom:{
      
      }, // 删除按钮位置
				
				times:1, // 计时器
				timesInt:null, // 计时器
				status:0, //0录制中,1录制结束。
				number:1,
			}
		},
		mounted() {
      
      
			// 录音停止事件,会回调文件地址,如果status == 1,上传音频,并通知父组件发送音频信息
			recorderManager.onStop((res)=> {
      
      
				console.log(res)
				this.audioSrc = res.tempFilePath;
				if(this.status == 1){
      
      
					this.upload(this.audioSrc, 'audio');
				}
			});
			uni.getSystemInfo({
      
      
				success: (res) => {
      
      
					this.winSize = {
      
      
						"witdh": res.windowWidth,
						"height": res.windowHeight
					}
				}
			})
		},
		methods: {
      
      
			// 上传音频,并发送
			upload(file, type) {
      
      
				this.$uploadImage('/api/***', file).then(res => {
      
      
					if (res.code == 1) {
      
      
						this.$emit('submit',type,res.data.url)
					}
				})
			},
		},
	}
</script>
<style lang="scss" scoped>
	.chatAudio {
      
      
		.audioPlay{
      
      
			width: 750rpx;
			min-height: 100vh;
			position: fixed;
			left: 0;
			top: 0;
			z-index: 999;
			display: flex;
			align-items: center;
			justify-content: center;
			background: rgba(0, 0, 0, .8);
			text-align: center;
			.content{
      
      
				position: absolute;
				left: 0;
				bottom: 100rpx;
				.gif{
      
      
					width: 364rpx;
					height: 172rpx;
					background: #6C9FEB;
					border-radius: 32rpx;
					margin: auto;
					display: flex;
					align-items: center;
					justify-content: center;
					transition: all .5s;
					uni-image{
      
      
						width: 160rpx;
						height: 48rpx;
					}
				}
				.red{
      
      
					background-color: #FB5353;
				}
				.close{
      
      
					margin: 176rpx auto 42rpx;
					width: 132rpx;
					height: 132rpx;
					uni-image{
      
      
						width: 132rpx;
						height: 132rpx;
					}
				}
				.bom{
      
      
					position: relative;
					.times{
      
      
						position: absolute;
						left: 50%;
						top: 125rpx;
						margin-left: -70rpx;
					}
					uni-image{
      
      
						width: 750rpx;
						height: 254rpx;
						margin-top: 26rpx;
					}
					uni-text{
      
      
						font-size: 28rpx;
						color: #9E9E9E;
					}
				}
				
			}
		}
	}
</style>

2.父组件

<template>
	<view>
		<view class="footer">
			<!--
				@longpress:长按元素,弹出弹窗。
				@touchmove:手指触摸元素后移动,获取手指在屏幕中的位置。
				@touchend:手指结束触摸元素,判断是否结束录制音频
			-->
			<view 
				@longpress="audioShow = true" 
				@touchmove.stop.prevent="audioTouchmove"
				@touchend.stop.prevent="audioTouchendShow = true">
				<text>按住 说话</text>
			</view>
		</view>
		
		<!--
				@submit:通知父组件,发送消息内容。
				audioXY:手指在屏幕中的位置信息。
				audioShow:是否弹出子组件
				audioTouchendShow:是否结束录制
				closeAudioShow:子组件通知父组件,结束录制,
			-->
		<chatAudio 
			@submit="submit" 
			:audioXY="audioXY" 
			:audioShow="audioShow" 
			:audioTouchendShow="audioTouchendShow" 
			@closeAudioShow="audioTouchendShow = false,audioShow = false">
		</chatAudio>
	</view>
	
</template>
<script>
	export default {
      
      
		data() {
      
      
			return {
      
      
				audioShow:false,// 录制音频弹窗
				audioTouchendShow:false,// 是否结束录制音频
			}
		},
		methods:{
      
      
			// 录音长按
			audioTouchmove(e){
      
      
				let x = e.changedTouches[0].clientX;
				let y = e.changedTouches[0].clientY;
				this.audioXY = {
      
      
					x:x,
					y:y
				}
			},
			// 发送
			submit(type,url){
      
      
			
			}
		}
	}
</script>

猜你喜欢

转载自blog.csdn.net/qq_40745143/article/details/129689995
今日推荐