当前位置:   article > 正文

uni-app小程序实现录音功能,uniapp实现录音功能并上传java,uniapp简单实现录音功能_uniapp 录音

uniapp 录音

前言

【简单的录音例子,复制过去就可用】
使用了uni组件和uView组件;
uniapp小程序授权录音并录制后保存到java后端。

效果图

在这里插入图片描述

uniapp实现

直接复制过去粘贴到.vue文件即可测试;官方的回调有时候无效,所以有些地方注释了。

<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>

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • 176
  • 177
  • 178
  • 179
  • 180
  • 181
  • 182
  • 183
  • 184
  • 185
  • 186
  • 187
  • 188
  • 189
  • 190
  • 191
  • 192
  • 193
  • 194
  • 195
  • 196
  • 197
  • 198
  • 199
  • 200
  • 201
  • 202
  • 203
  • 204
  • 205
  • 206
  • 207
  • 208
  • 209
  • 210
  • 211
  • 212
  • 213
  • 214
  • 215
  • 216
  • 217
  • 218
  • 219
  • 220
  • 221
  • 222
  • 223
  • 224
  • 225
  • 226
  • 227
  • 228
  • 229
  • 230
  • 231
  • 232
  • 233
  • 234
  • 235
  • 236
  • 237
  • 238
  • 239
  • 240
  • 241
  • 242
  • 243
  • 244
  • 245
  • 246
  • 247
  • 248
  • 249
  • 250
  • 251
  • 252
  • 253
  • 254
  • 255
  • 256
  • 257
  • 258

小程序授权

在startRecord()方法中已经体现,如果检测到没有授权麦克风,就弹到设置中需要用户手动开启
参考官网:https://uniapp.dcloud.net.cn/api/other/setting.html#opensetting
在这里插入图片描述

java端接收

    /**
     * 临时文件存储(小程序)
     *
     * @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("文件上传异常");
        }
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26

存储文件

在这里插入图片描述
参考官网:https://uniapp.dcloud.net.cn/api/media/record-manager.html

音频播放https://blog.csdn.net/weixin_43992507/article/details/129861379

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/AllinToyou/article/detail/565535
推荐阅读
相关标签
  

闽ICP备14008679号