The uni-app applet realizes the recording function, uniapp realizes the recording function and uploads java, and uniapp simply realizes the recording function

foreword

[Simple recording example, it can be used after copying]
The uni component and uView component are used;
the uniapp applet authorizes the recording and saves it to the java backend after recording.

renderings

insert image description here

uniapp implementation

Just copy and paste it to the .vue file to test; the official callback is sometimes invalid, so some places are commented.

<template>
	<view class="container">
		<!-- 表单 -->
		<u-popup :show="showForm" mode="bottom" closeable="true" @close="closeForm" @open="openForm"
			:customStyle="{
     
     'border-radius': '20px 20px 0px 0px'}">
			<view style="padding: 50px 20px 40px 20px;height: 600rpx;overflow: auto;">
				<uni-section title="录音并上传" type="line" padding>
					<view style="margin-bottom: 100px;">
						<view style="margin-bottom: 20px;">
							<view>
								<text>剩余时间:{
   
   {tempCount}}</text><!-- 倒计时 -->
								<text style="margin-left: 10px;">已录时间:{
   
   {voiceCount}}</text><!-- 已录制 -->
							</view>
						</view>
						<u-button v-if="startState == 0" :text="btn_start_text" type="success" size="normal"
							@click="startRecord()"></u-button>
						<u-button v-if="startState == 1" :text="btn_pr_text" type="success" size="normal"
							@click="pauseResumeRecord()"></u-button>
						<u-button v-if="startState == 1" text="停止录音" type="warning" size="normal" @click="stopRecord()">
						</u-button>
					</view>
					<u-button text="提交" type="primary" size="normal" @click="submitFile()"></u-button>
				</uni-section>
			</view>
		</u-popup>
	</view>
</template>

<script>
	const recorderManager = uni.getRecorderManager(); // 录音实例对象

	export default {
      
      
		data() {
      
      
			return {
      
      
				btn_start_text: '开始录音', // 开始录制/重新录制按钮
				btn_pr_text: '暂停录音', // 暂停/继续按钮
				showForm: true, // 显示弹框表单
				voicePath: '', // 录音文件临时地址
				tempInter: null, // 计时器
				tempCount: '00:00', // 倒计时
				tempVoice: false, // 是否暂停或者结束
				startState: 0, // 0未开始录音 1开始录音
				voiceNum: 120, // 录制倒计时,2分钟
				voiceCount: '00:00', // 已录制时间
			}
		},
		onLoad() {
      
      
			//this.creatRecorder();
		},
		methods: {
      
      
			/**
			 * 录音实例-初始化
			 */
			creatRecorder() {
      
      
				let self = this;
				self.countInter(self.voiceNum); // 2分钟
				self.tempVoice = true;
				self.startState = 1;
				self.voicePath = '';
				// 录音开始(有时候失效)
				recorderManager.onStart(function() {
      
      
					// console.log('开始录音');
					// self.countInter(120); // 2分钟
					// self.tempVoice = true;
					// self.startState = 1;
					// self.voicePath = '';
				});
				// 录音暂停(有时候失效)
				recorderManager.onPause(function() {
      
      
					// console.log('暂停录音');
					// self.tempVoice = false;
					// self.btn_pr_text = '继续录音';
				});
				// 录音继续(有时候失效)
				recorderManager.onResume(function() {
      
      
					// console.log('继续录音');
					// self.tempVoice = true;
					// self.btn_pr_text = '暂停录音';
				});
				// 录音停止
				recorderManager.onStop(function(res) {
      
      
					console.log('停止录音', res);
					self.voicePath = res.tempFilePath;
					self.tempVoice = false;
					self.btn_pr_text = '暂停录音';
					self.btn_start_text = '重新录制';
					self.startState = 0;
					clearInterval(self.tempInter);
				});
				// 录音错误
				recorderManager.onError(function(errMsg) {
      
      
					console.log('录音错误', errMsg);
				});
			},
			/**
			 * 开始录音
			 */
			startRecord() {
      
      
				let self = this;
				uni.authorize({
      
      
					scope: 'scope.record',
					success() {
      
      
						recorderManager.start({
      
      
							duration: 60000 * 2 // 2分钟
						});
						self.creatRecorder();
					},
					fail() {
      
      
						uni.showModal({
      
      
							content: '检测到您没打开录音功能权限,是否去设置打开?',
							confirmText: "确认",
							cancelText: '取消',
							success(res) {
      
      
								uni.openSetting({
      
      
									success(res) {
      
      
										console.log(res);
									},
									fail(res) {
      
      
										uni.showToast({
      
      
											title: '打开授权设置失败',
											icon: 'none'
										})
									}
								});
							}
						})
					}
				})
			},
			/**
			 * 暂停/继续
			 */
			pauseResumeRecord() {
      
      
				let self = this;
				if (this.btn_pr_text == '暂停录音') {
      
      
					recorderManager.pause();
					console.log('暂停录音');
					self.tempVoice = false;
					self.btn_pr_text = '继续录音';
				} else {
      
      
					recorderManager.resume();
					console.log('继续录音');
					self.tempVoice = true;
					self.btn_pr_text = '暂停录音';
				}
			},
			/**
			 * 停止录音
			 */
			stopRecord() {
      
      
				let self = this;
				recorderManager.stop();
				self.tempVoice = false;
				self.btn_pr_text = '暂停录音';
				self.btn_start_text = '重新录制';
				self.startState = 0;
				clearInterval(self.tempInter);
			},
			/**
			 * 录音倒计时
			 * @param {Object} val
			 */
			countInter(val) {
      
      
				let self = this;
				let count = Number(val);
				self.formatTime(count);
				self.tempInter = setInterval(() => {
      
      
					if (self.tempVoice && count > 0) {
      
      
						count--;
						self.tempCount = self.formatTime(count);
						self.voiceCount = self.formatTime(self.voiceNum - count);
					} else if (self.tempVoice) {
      
      
						clearInterval(self.tempInter);
					}
				}, 1000)
			},
			/**
			 * 格式化时间格式
			 * @param {Object} num
			 */
			formatTime(num) {
      
      
				num = num.toFixed(0);
				let second = num % 60;
				second = (second < 10) ? '0' + second : second;
				let min = Math.floor(num / 60);
				min = (min < 10) ? '0' + min : min;
				return min + ":" + second;
			},
			// 表单-打开(回调)
			openForm() {
      
      },
			// 表单-关闭(回调)
			closeForm() {
      
      
				this.showForm = false;
				clearInterval(this.tempInter);
				this.tempVoice = false;
			},
			// 表单-提交
			submitFile() {
      
      
				let self = this;
				if (!this.voicePath) {
      
      
					uni.showToast({
      
      
						title: '请录制后再提交',
						icon: 'none'
					})
					return;
				}
				uni.showLoading({
      
      
					title: '提交中'
				});
				uni.uploadFile({
      
      
					url: this.jsAjax.api + '/upload/applet/voice', // 自己后台接收的接口
					filePath: this.voicePath,
					name: 'file',
					formData: {
      
      },
					success: (res) => {
      
      
						uni.hideLoading();
						uni.showToast({
      
      
							title: '上传成功',
							icon: 'none'
						})
						//self.showForm = false;
						// 重置清空数据
						self.voicePath = '';
						self.tempVoice = false;
						self.btn_pr_text = '暂停录音';
						self.btn_start_text = '开始录音';
						self.startState = 0;
						self.tempCount = self.formatTime(0);
						var obj = JSON.parse(res.data);
						console.log(obj);
					},
					fail: (err) => {
      
      
						uni.hideLoading();
						uni.showToast({
      
      
							title: '上传失败',
							icon: 'none'
						})
					}
				});
			},
		},
	}
</script>

<style>
	page {
      
      
		background-color: #fff !important;
	}

	.container {
      
      
		padding: 10px 15px;
	}

	button {
      
      
		margin-bottom: 10px;
	}
</style>

Mini Program Authorization

It has been reflected in the startRecord() method. If no authorized microphone is detected, it will pop up in the settings and need to be manually opened by the user.
Refer to the official website: https://uniapp.dcloud.net.cn/api/other/setting.html#opensetting
insert image description here

The java side receives

    /**
     * 临时文件存储(小程序)
     *
     * @param request
     * @return
     */
    @RequestMapping(value = "/applet/voice")
    @ResponseBody
    public Result voiceSave(@RequestParam("file") MultipartFile multipartFile, HttpServletRequest request) {
    
    
        try {
    
    
            // 是本地存储,或指定目录存储
            String path = (serverType == 1) ? NGINXPATH : request.getServletContext().getRealPath("");
            String yName = multipartFile.getOriginalFilename();
            String hz = yName.substring(yName.lastIndexOf("."));//获取文件后缀
            String fileName = System.currentTimeMillis() + hz;
            String filepath = "upload/tem/"+ fileName;
            File file = new File(path + filepath);
            if (!file.exists()) {
    
    
                file.mkdirs();
            }
            multipartFile.transferTo(file);
            return Result.success(filepath, "上传成功");
        }catch (Exception e){
    
    
            return Result.error("文件上传异常");
        }
    }

save file

insert image description here
Refer to the official website: https://uniapp.dcloud.net.cn/api/media/record-manager.html

Audio playback : https://blog.csdn.net/weixin_43992507/article/details/129861379

Guess you like

Origin blog.csdn.net/weixin_43992507/article/details/129857780