赞
踩
这是一个按钮录音弹窗:你也可你自己换成别的!
点击保存会返回 录音的 路径 通过 v-model 绑定的!(你也可以自己写个emit 返回方法,)
# 要删除的(就这俩) import { usualUploadFileOne, removeFile, usualGetFileList, getSpeech } from '@/common/api/ip' try{ let res = await getSpeech({ filePath: this.recordFile.fullPath }, { myFile: this.recordFile.fullPath }) this.loading = false this.$refs.uToast.show({ title: '录音转文字成功,请粘贴内容', type: 'success' }) this.$emit('input', JSON.parse(res.data.data)[0]) this.releaseManger() }catch(e){ this.loading = false this.$refs.uToast.show({ title: e, type: 'warning' }) }
注意: 项目没有 uview 组件库的,自己想办法吧!该录音也没用什么,就用了个 进度条和按钮, 自己整的替换了就行
图片资源:三个
注意: 图片资源自己去 https://www.iconfont.cn/上找 长这样(我不知道怎么传!)
注意: 俩svg 和一个png ;命名和 图片格式别搞错了!导入到对应的 static/img中
文件名 fs-audio
<template> <view> <view> <slot> <u-button type="default" @click="openRecordDialog">录音转文字</u-button> </slot> </view> <!-- 录音弹窗 --> <u-mask :show="toggleDialog" :mask-click-able="false"> <view class="recordWrap"> <view class="top_tip">{{topTipText}}</view> <view class="progress_time_wrap" v-if="toggleDialog"> <view class="record_progress"> <u-circle-progress bg-color="#000" active-color="#2979ff" :percent="record_progress_time"> <image style="width: 70%;height: 70%;" mode="aspectFit" src="/static/img/arecord.png"></image> </u-circle-progress> </view> <view class="record_time">{{record_formate_time}}</view> </view> <view class="record_control"> <view class="btn record_reset" @click="resetRecord" v-if="record_status >= 4"> <view class="in_btn reset_btn"></view> <view class="btn_title">重新录制</view> </view> <view class="btn record_start" @click="startRecord"> <view class="in_btn l_btn" :class="{start:record_status == 0 || record_status >=4,pause: record_status == 1 || record_status== 3}"></view> <view class="in_btn r_btn" :class="{start:record_status == 0 || record_status >=4,pause: record_status == 1 || record_status== 3}"></view> <template v-if="record_status == 2"> <image style="width: 100%;height: 100%;margin-left: 6rpx;" src="/static/img/play.svg" alt=""></image> </template> <view class="btn_title">{{startBtnText}}</view> </view> <view class="btn record_reset" @click="playRecord" v-if="record_status >= 4"> <view v-if="record_status == 4" class="in_btn play l_play_btn"> <image style="width: 100%;height: 100%;margin-left: 6rpx;" src="/static/img/play.svg" alt=""></image> </view> <template v-if="record_status == 5"> <view class="in_btn pause r_end_btn"></view> <view class="in_btn pause r_end_btn"></view> </template> <view class="btn_title">{{playBtnText}}</view> </view> <!-- #ifdef MP-WEIXIN --> <view class="btn record_start" @click="saveRecord" v-if="record_status == 2"> <view class="in_btn" style="width: 100%; transform: translateX(-4rpx);background-color: #ff000000;"> <image style="width: 100%;height: 100%;margin-left: 6rpx;" src="/static/img/dui.svg" alt=""></image> </view> </view> <!-- #endif --> </view> <!-- <view> {{recordFile.name}} </view> <view> {{recordFile.fullPath}} </view> --> <view class="action_btn"> <u-button :ripple="true" :plain="true" class="btn" @click="successClick">确定</u-button> <u-button :ripple="true" :plain="true" class="btn" @click="cancalClick">取消</u-button> </view> <!-- <view class="footer"> <button type="default" @click="toggleDialog = false">关闭</button> </view> --> </view> </u-mask> <!-- 加载 --> <u-mask :show="loading" @click="loading = false"> <view class="load_more_m"> <u-loading mode="circle" color="#169ef9" /> <view class="word">录音转文字中...</view> </view> </u-mask> <!-- 提示 --> <u-toast ref="uToast" /> </view> </template> <script> import { usualUploadFileOne, removeFile, usualGetFileList, getSpeech } from '@/common/api/ip' export default { name: "fs-audio", props:{ value: String, time:{type:Number, default: 600},//录音可录制的总时常 }, data() { return { loading: false, //共 toggleDialog: false, //录音弹窗切换 record_time: 0, //录音时间 record_time_copy: 0, //录音时间 record_progress_time: 0, //录音进度时间 record_formate_time: '00:00:00', //录音格式化时间 record_status: 0,//录音状态 0未开始,1开始,2暂停,3继续,4结束录,5播放,6重新录 record_img: '', startBtnText:'开始',//录制按钮文字 playBtnText:'播放录音',//录制按钮文字 topTipText: '', timer: null,//定时器 recordFile: {},//录音文件 //录 recordInstance: null, //录音对象 //播 playInstance: null, //录音对象 tempFilePath:'' }; }, methods: { //点击取消 cancalClick() { uni.showModal({ title: "取消录制", content: "是否取消录制?", success: (res) => { if (res.confirm) { this.releaseManger() } } }) }, //释放管理器 releaseManger() { this.record_status = 0 this.recordInstance = null this.playInstance = null this.toggleDialog = false }, //点击确定 async successClick() { if (!this.recordFile.fullPath) { this.$refs.uToast.show({title: '请录音后再保存',type: 'warning'}) return; } //录音转文字 this.loading = true try{ // await this.getSpeech() let res = await getSpeech({ filePath: this.recordFile.fullPath }, { myFile: this.recordFile.fullPath }) this.loading = false this.$refs.uToast.show({ title: '录音转文字成功,请粘贴内容', type: 'success' }) this.$emit('input', JSON.parse(res.data.data)[0]) this.releaseManger() }catch(e){ this.loading = false this.$refs.uToast.show({ title: e, type: 'warning' }) //TODO handle the exception } }, // 播放录音 playRecord() { if(this.record_status == 4) { // #ifdef APP-PLUS this.playInstance = plus.audio.createPlayer(this.recordFile.fullPath) this.playInstance.addEventListener('play',()=> { this.record_time = 0 this.record_status = 5 this.$nextTick(() =>{ this.setTime() }) }) this.playInstance.play((res) => { console.log('播放成功完成') this.record_time = this.record_time_copy this.record_status = 4 },(err) => { console.log('播放失败') }) // #endif // #ifdef MP-WEIXIN this.playInstance = uni.createInnerAudioContext() this.playInstance.src = this.recordFile.fullPath //音频播放事件 this.playInstance.onPlay(() => { console.log('开始播放') this.record_time = 0 this.record_status = 5 this.$nextTick(() =>{ this.setTime() }) }) // 音频自然播放结束事件/ this.playInstance.onEnded(() => { console.log('播放结束') this.record_time = this.record_time_copy this.record_status = 4 }) this.playInstance.play() // #endif }else { this.playInstance.stop() this.record_status = 4 this.record_time = this.record_time_copy } }, //初始化数据 initData() { this.record_time = 0, //录音时间 this.record_progress_time = 0, //录音进度时间 this.record_formate_time = '00:00:00', //录音格式化时间 this.clearTime() }, //初始化对象 init() { }, // #ifdef MP-WEIXIN // #endif // 重置录音 resetRecord() { this.record_status = 0 }, //录音弹窗切换 openRecordDialog() { console.log('录音弹窗切换', this.toggleDialog) this.getRecordSetting() // this.toggleDialog = !this.toggleDialog }, //创建录音列表 createAudioList() { }, //开始录音 startRecord() { if(this.record_status == 4) { this.$refs.uToast.show({ title: '请点击重新录制再进行此操作', type: 'warning' }) } // #ifdef APP-PLUS this.recordInstance = plus.audio.getRecorder(); if(this.record_status == 0) { this.recordInstance.record({ filename: '_doc/audio/' }, (recordFile) => { console.log(recordFile,'保存录音----') plus.io.resolveLocalFileSystemURL(recordFile, (entry) => { console.log(entry,'转换后的录音地址') this.recordFile = entry // this.getSpeech(entry.fullPath) }, (e) => { this.$refs.uToast.show({ title: '读取录音文件错误', type: 'warning' }) }); }, (e) => { console.log(e,) this.$refs.uToast.show({ title: '录音失败', type: 'warning' }) }); }else { this.record_status = 4//结束录 this.record_time_copy = this.record_time this.recordInstance.stop() } if(this.record_status == 0) this.record_status = 1 // #endif console.log(this.recordInstance,'this.recordInstance') // #ifdef MP-WEIXIN this.recordInstance = uni.getRecorderManager() this.setSetting() // #endif }, //小程序录音功能 MPWEIXINstart() { console.log(this.recordInstance,'this.recordInstance') //监听开始 this.recordInstance.onStart((res) => { if(this.record_status == 0) this.record_status = 1 console.log('开始录音') }) //监听暂停 this.recordInstance.onPause(() => { console.log('监听暂停') this.record_status = 2 this.record_time_copy = this.record_time }) //监听继续 this.recordInstance.onResume(() => { console.log('监听继续') this.record_status = 3 this.record_time_copy = this.record_time }) //监听结束 this.recordInstance.onStop((res) => { console.log(res.tempFilePath,'监听结束') this.record_status = 4 this.recordFile.fullPath = res.tempFilePath this.recordFile.name = res.tempFilePath }) //监听错误 this.recordInstance.onError((err) => { console.log(err) }) if(this.record_status == 0) { this.recordInstance.start({duration:600000,format:'wav'}); return; }else if(this.record_status == 1) {//暂停 this.recordInstance.pause() return; }else if(this.record_status == 2) {//继续 this.recordInstance.resume() return; }else if(this.record_status == 3) {//暂停 this.recordInstance.pause() return; } }, //录音完成 saveRecord() { if(this.record_status != 4) this.recordInstance.stop() }, //设置定时器 setTime() { if(this.timer) return; this.timer = setInterval(() => { if(this.record_time >= this.time){ return this.record_status = 4 } this.record_time = this.record_time + 1 },1000) }, //清除定时器 clearTime() {clearInterval(this.timer);this.timer = null}, //获取录音权限 getRecordSetting() { // console.log(uni.getSetting,'uni.getSetting') // #ifdef MP-WEIXIN this.toggleDialog = !this.toggleDialog // #endif // #ifdef APP-PLUS this.confirmPlatform() // #endif }, // #ifdef MP-WEIXIN setSetting() { uni.getSetting({ success: (res) => { console.log(res, JSON.stringify(res, 'getSetting')) if (res.authSetting['scope.record'] != undefined && res.authSetting['scope.record'] != true) { uni.showModal({ title: '请求授权位置权限', content: '需要获取位置权限,请确认授权', success: (res) => { if (res.cancel) { this.$refs.uToast.show({ title: '拒绝授权!', type: 'warning' }) } else if (res.confirm) { uni.openSetting({ success: (dataAu) => { console.log(dataAu, 'openSetting') if (dataAu.authSetting[ "scope.record"] == true) { this.$refs.uToast.show({ title: '授权成功!', type: 'success' }) //再次授权,调用wx.getLocation的API this.MPWEIXINstart() } else { this.$refs.uToast.show({ title: '授权失败!', type: 'warning' }) } } }) } } }) } else if (res.authSetting['scope.record'] == undefined) { //调用wx.getLocation的API console.log('首次授权') this.MPWEIXINstart() } else { //调用wx.getLocation的API this.MPWEIXINstart() } }, fail(err){ console.log(err,'fail') }, complete(err) { console.log(err,'getSetting') } }) }, // #endif // #ifdef APP-PLUS // 确定运行平台 confirmPlatform() { switch (uni.getSystemInfoSync().platform) { case 'android': console.log('运行Android上'); this.androidGetRecordSetting() break; case 'ios': console.log('运行iOS上'); break; default: console.log('运行在开发者工具上'); break; } }, //android权限设置 androidGetRecordSetting() { plus.android.requestPermissions(['android.permission.RECORD_AUDIO'], (e) => { console.log(e.length > 0, 'e-----android权限设置') if (e.deniedAlways.length > 0) { //权限被永久拒绝 // plus.runtime.openURL("app-settings://"); var main = plus.android.runtimeMainActivity(); var Intent = plus.android.importClass("android.content.Intent"); //可能应该直接进入应用列表的权限设置?=> android.settings.APPLICATION_SETTINGS var mIntent = new Intent('android.settings.APPLICATION_SETTINGS'); main.startActivity(mIntent); // 弹出提示框解释为何需要定位权限,引导用户打开设置页面开启 this.$refs.uToast.show({ title: '该功能需要录音权限,请在权限设置中进行授权!' }) console.log('Always Denied!!! ' + e.deniedAlways.toString()); } if (e.deniedPresent.length > 0) { //权限被临时拒绝 this.toggleDialog = !this.toggleDialog // 弹出提示框解释为何需要定位权限,可再次调用plus.android.requestPermissions申请权限 console.log('Present Denied!!! ' + e.deniedPresent.toString()); } if (e.granted.length > 0) { //权限被允许 //调用依赖获取定位权限的代码 this.toggleDialog = !this.toggleDialog console.log('Granted!!! ' + e.granted.toString()); } }, (e) => { // this.toggleDialog = !this.toggleDialog // console.log('Request Permissions error:' + JSON.stringify(e)); }); }, // #endif //数字转时间 secondsFormat(sec){ let hour = Math.floor(sec / 3600) let minute = Math.floor((sec - hour * 3600) / 60) let second = sec - hour * 3600 - minute * 60 if (hour < 10) { hour = "0" + hour; } if (minute < 10) { minute = "0" + minute; } if (second < 10) { second = "0" + second; } return hour + ":" + minute + ":" + second; }, //录音转文字 async getSpeech(tempFilePath) { await getSpeech({ filePath: this.tempFilePath || tempFilePath }, { myFile: this.tempFilePath || tempFilePath }) .then(res => { console.log(res, '录音转文字') this.$emit('input', JSON.parse(res.data.data)[0]) this.$refs.uToast.show({ title: '录音转文字成功,请粘贴内容', type: 'success' }) }) }, }, watch: { record_time(newValue, oldValue) { if(newValue == 0) { this.record_progress_time = 0 this.record_formate_time = '00:00:00' }else { this.record_progress_time = (newValue * 100) / this.time this.record_formate_time = this.secondsFormat(newValue) } }, //录音状态0未开始,1开始,2暂停,3继续,4结束录,5播放,6重新录 record_status(newValue, oldValue) { switch(newValue) { case 0 : this.initData() ;this.startBtnText = '开始';this.topTipText=""; break; case 1 : this.setTime() ;this.startBtnText = '暂停' ;this.topTipText="录音中..."; break; case 2 : this.clearTime() ;this.startBtnText = '继续' ;this.topTipText="录音中..."; break; case 3 : this.setTime() ;this.startBtnText = '暂停'; this.topTipText="录音中..."; break; case 4 : this.clearTime() ;this.startBtnText = '录制结束' ; this.playBtnText = '播放录音';this.topTipText=""; break; case 5 : this.clearTime() ;this.playBtnText = '录音播放中';this.topTipText="播放中..."; break; } }, }, mounted() { this.init() //初始化对象 }, computed:{ //格式化已经录制的时间 formatRecordTime() { return this.secondsFormat(this.record_time) } } } </script> <style lang="scss"> //录音弹窗样式 .recordWrap { width: 100%; height: 100vh; background-color: #000000; position: relative; z-index: 999; box-sizing: border-box; padding-bottom: 100rpx; overflow: hidden; color: white; .progress_time_wrap{ margin-top: 200rpx; display: flex; align-items: center; justify-content: center; flex-direction: column; } .top_tip{ position: absolute; top: 20rpx; left: 0; width: 100%; text-align: center; height: 60rpx; line-height: 60rpx; } .record_control{ display: flex; padding: 100rpx; justify-content: center; align-items: center; .btn{ position: relative; margin: 0 40rpx; transition: all .5s; background: #d8d6d6; box-shadow: 0 0 10px #d8d6d6; width: 100rpx; height: 100rpx; border-radius: 50%; display: flex; justify-content: space-around; align-items: center; padding: 20rpx; box-sizing: border-box; &:active{ transform: scale(0.8); } .btn_title{ position: absolute; top: 100%; width: 100%; font-size: 28rpx; text-align: center; white-space: nowrap; } .in_btn{ background-color: red; transition: all .5s; height: 100%; &.start { width: 40rpx; &.start.l_btn{ border-radius: 40rpx 0 0 40rpx; } &.start.r_btn{ border-radius: 0 40rpx 40rpx 0; } } &.pause { width: 20rpx; border-radius: 10rpx } &.reset_btn{ width: 100%; height: 100%; border-radius: 20rpx; } &.play{ width: 100%; height: 100%; border-radius: 10rpx; &.play.l_play_btn{ background-color: transparent; // transform: rotate(-45deg); } &.play.r_end_btn{ background-color: transparent; } } &.end{ width: 20rpx; border-radius: 10rpx } } } } .action_btn{ position: absolute; z-index: 1; bottom: 8rpx; left: 0; width: 100%; display: flex; justify-content: space-around; align-items: center; box-sizing: border-box; .btn{ flex: 1; margin: 32rpx; } } .footer{ } } .load_more_m { margin: 33vh auto auto; width: 300rpx; height: 200rpx; display: flex; align-items: center; justify-content: center; background: #fff; border-radius: 20rpx; flex-direction: column; .word { margin-top: 24rpx; letter-spacing: 0.1em; } } </style>
<fs-audio v-model="CONTENT"></fs-audio>
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。