1
0
forked from dyf/APP
Files
APP/pages/common/audioManager/Recording.vue
2025-11-07 12:16:10 +08:00

1557 lines
37 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<view class="maincontent contentBg">
<!-- 文字转语音 -->
<view v-if="Status.pageType==='Txt'">
<view>
<view class="importTxt fright" @click="importDoc">导入文档</view>
<view class="clear"></view>
</view>
<view class="text-content">
<view class="uni-textarea">
<textarea class="textarea" v-model="formData.txt" placeholder-class="placehoderClass"
placeholder="请输入要转换的文本" :auto-height="true" maxlength="100" cursor-color="#BBE600" />
</view>
<view class="line"></view>
<view class="footBtn">
<view class="fright convert" @click.stop="txtToAudio()">转换</view>
<view class="fright audioSett" @click.stop="formData.txt=''">清空</view>
<view class="clear"></view>
</view>
</view>
</view>
<!-- 获取到的语音信息 -->
<view class="cEdit" :class="{'displayNone':(!AudioData.tempFilePath && Status.pageType!=='Txt')|| (AudioData.hexLength===0 && Status.pageType==='Txt')}">
<view class="audioRemark">
<view>
<view>
<input type="text" class="txtName" v-model="cEdit.name" placeholder="音频名称"
placeholder-class="placehoderClass" />
</view>
<view>
<text>{{cEdit.createTime}}</text>
<text>{{getFormatSeconds(cEdit.time,true)}}</text>
</view>
</view>
<view class="btnSave" v-if="Status.pageType!=='Txt'" @click.stop="uploadLuYin">保存</view>
</view>
<view class="slide" v-if="Status.pageType!=='Txt'">
<view class="circle" :style="{'left':PlayProgress}"></view>
<view class="line"></view>
<view class="fleft">
{{getFormatSeconds(cEdit.currTime)}}
</view>
<view class="fright">
{{getFormatSeconds(cEdit.time)}}
</view>
<view class="clear"></view>
</view>
<view class="control" v-if="Status.pageType!=='Txt'">
<view class="playControl">
<view class="seek" @click.stop="seek(-10)">
<image class="img" src="/static/images/common/prev.png" mode="aspectFit"></image>
</view>
<view class="play" @click="playToggle()">
<image class="img"
:class="{'displayNone':Status.playState!=='ready' && Status.playState!=='pause'}"
src="/static/images/common/play.png" mode="aspectFit"></image>
<image class="img" :class="{'displayNone':!Status.playState || Status.playState!=='play'}"
src="/static/images/common/pause.png" mode="aspectFit"></image>
</view>
<view class="seek" @click.stop="seek(10)">
<image class="img" src="/static/images/common/next.png" mode="aspectFit"></image>
</view>
</view>
<view class="drop" v-if="Status.pageType!=='Txt'" @click.stop="drop()">
<uni-icons type="trash" size="30" color="#e03434"></uni-icons>
</view>
</view>
</view>
<view class="txtBtns" v-if="Status.pageType==='Txt'"
:class="{'displayNone':AudioData.hexLength===0}">
<view class="btnSave fright" @click.stop="SaveTTS()">保存</view>
<view class="audioSett fright" @click.stop="CancelTTS">取消</view>
<view class="clear"></view>
</view>
<!-- 录音的提示 -->
<view v-if="Status.pageType==='Record'">
<view class="tips" :class="{'displayNone':Status.isRecord || AudioData.tempFilePath}">
点击下方红色录制按钮开始录音吐字清晰语句流畅
</view>
</view>
<!-- 录音选择文件操作 -->
<view class="footer" v-if="Status.pageType!=='Txt'">
<view class="opt">
<view class="recording" :class="{'displayNone':Status.pageType!=='Record'}">
<view class="recordTitle">语音录制{{Status.RecordName}}</view>
<view class="recordName" :class="{'visibilityHidden':!formatSecondsToDHMS}">{{formatSecondsToDHMS?formatSecondsToDHMS:"00:00"}}</view>
</view>
<view class="btnRecord center" @click.stop="toggleRecord()"
:class="{'displayNone':Status.pageType!=='Record'}">
<view class="start" :class="{'active':Status.isRecord}"></view>
</view>
<view class="btnRemark" :class="{'displayNone':Status.pageType!=='Record'}">
{{Status.isRecord?'录制中':'录制'}}
</view>
<view class="btnCheckFile center" @click.stop="checkFile()"
:class="{'displayNone':Status.pageType!=='File'}">
<view class="polygon center">
<uni-icons type="plusempty" size="45" color="#ffffff99"></uni-icons>
</view>
</view>
</view>
</view>
<!-- 自定义弹出层 -->
<MessagePopup :visible="Status.Pop.showPop" :type="Status.Pop.popType" :bgColor="Status.Pop.bgColor"
:borderColor="Status.Pop.borderColor" :textColor="Status.Pop.textColor"
:buttonBgColor="Status.Pop.buttonBgColor" :buttonTextColor="Status.Pop.buttonTextColor"
:iconUrl="Status.Pop.iconUrl" :message="Status.Pop.message" :buttonText="Status.Pop.buttonText"
@buttonClick="HidePop" :visiblePrompt="Status.Pop.visiblePrompt" :promptTitle="Status.Pop.promptTitle"
v-model="Status.Pop.modelValue" @closePop="closePop" :buttonCancelText="Status.Pop.buttonCancelText"
:showCancel="Status.Pop.showCancel" @cancelPop="closePop" :showSlot="Status.Pop.showSlot">
<view class="popup-prompt">
<input type="text" class="popup-prompt-input" placeholder="请输入名称" v-model="cEdit.name" />
</view>
</MessagePopup>
<global-loading ref="loading" />
<xe-upload ref="XeUpload" :options="uploadOptions" @callback="handleUploadCallback"></xe-upload>
</view>
</template>
<script>
var eventChannel = null;
var these = null;
var innerAudioContext = null;
var AudeoRecoder = null;
var audioTime = null;
var hexs = null;
import BleTool from '@/utils/BleHelper.js';
import request, {
baseURL
} from '@/utils/request';
import {
showLoading,
hideLoading,
updateLoading
} from '@/utils/loading.js';
import Common from '@/utils/Common.js';
export default {
data() {
return {
Status: {
playState: '', //播放状态
pageType: '', //页面类型,用于区分录音、选择文件、文字转语音
pageValid: false, //页面状态,是否已销毁
recoderIntval: null, //录音的定时器
isRecord: false, //是否正在录音
RecordTime: null, //已录间的时长
Pop: { //弹出框的配置
showPop: false, //是否显示弹窗
popType: 'custom',
bgColor: '#383934bd',
borderColor: '#BBE600',
textColor: '#ffffffde',
buttonBgColor: '#BBE600',
buttonTextColor: '#232323DE',
iconUrl: '',
message: '您确定要这样做吗?',
buttonText: '确定',
clickEvt: '',
visiblePrompt: false,
promptTitle: '设备名称',
modelValue: '',
visibleClose: false,
okCallback: null,
buttonCancelText: '',
showCancel: false,
showSlot: false
},
},
cEdit: {
Id: "", //编号
name: "", //名称
createTime: "", //创建时间
localPath: "", //本地地址
webPath: "", //网络地址
statu: "", //状态,是否公开
isApply: "", //是否使用中
time: "", //音频总长度
currTime: '', //当前播放进度
type:''
},
AudioData: {
tempFilePath: '',
hexLength:0
},
uploadOptions: {
},
formData: {
txt: '只要你能吃苦,就有吃不完的苦'
}
}
},
computed: {
formatSecondsToDHMS() {
let seconds = this.Status.RecordTime;
return this.getFormatSeconds(seconds);
},
PlayProgress() {
return this.cEdit.currTime / (this.cEdit.time === 0 ? 1 : this.cEdit.time) * 100 + '%';
}
},
onLoad(opt) {
eventChannel = this.getOpenerEventChannel();
these = this;
this.Status.pageType = opt.pageType;
let title = ""
if (opt.pageType === 'Record') {
title = "录制语音";
} else if (opt.pageType === 'Txt') {
title = '文字转语音';
} else {
title = "文件上传";
}
uni.setNavigationBarTitle({
title: title
});
},
onUnload() {
this.destoryAudioPlayer();
clearInterval(audioTime);
eventChannel.emit('RecordOver', {
data: '从音频页面返回,刷新数据'
});
},
onBackPress(e) {
debugger;
if (this.Status.isRecord) { //如果正在录音,提示是否放弃
this.showMsg("正在录音,是否放弃?", false, true, () => {
these.Status.pageValid = true;
these.stopLuYin();
uni.navigateBack();
});
return true;
} else {
if (this.AudioData.tempFilePath) {
this.showMsg("录音没有保存是否放弃?", false, true, () => {
these.Status.pageValid = true;
this.dropTmpFile();
this.AudioData.tempFilePath = "";
AudeoRecoder = null;
uni.navigateBack();
});
return true;
}
}
},
methods: {
CancelTTS(){
this.cEdit.name='';
this.cEdit.Id="";
this.cEdit.createTime="";
this.cEdit.currTime="";
this.cEdit.isApply="";
this.cEdit.localPath="";
this.cEdit.statu="";
this.cEdit.time="";
this.cEdit.webPath="";
this.AudioData.hexLength=0;
this.cEdit.type=this.Status.pageType;
hexs=[];
},
SaveTTS() {
if (!this.cEdit.name) {
this.showMsg("请输入语音名称");
return;
}
this.cEdit.localPath = "";
this.cEdit.Id = Common.guid();
this.cEdit.createTime = Common.DateFormat(new Date(), "yyyy年MM月dd日");
this.cEdit.isApply = false;
this.cEdit.statu = false;
this.cEdit.type=this.Status.pageType;
this.cEdit.webPath = "";
let pro1 = new Promise((resolve, reject) => {
uni.setStorage({
key: Common.pcmStorageKey + "_" + this
.cEdit.Id,
data: hexs,
success() {
resolve();
},
fail(ex) {
reject(ex)
}
});
});
let pro2 = new Promise((resolve, reject) => {
let array = uni.getStorageSync(Common
.audioStorageKey);
if (!array) {
array = [this.cEdit];
} else {
array.unshift(this.cEdit);
}
uni.setStorage({
key: Common.audioStorageKey,
data: array,
success() {
resolve();
},
fail(ex) {
reject(ex)
}
});
});
Promise.allSettled([pro1, pro2]).then(res => {
if (res[0].status == 'fulfilled' && res[1]
.status == 'fulfilled') {
updateLoading(these, {
text: "操作成功"
});
this.AudioData.tempFilePath = "";
this.Status.isRecord = false;
uni.navigateBack();
return;
} else {
updateLoading(these, {
text: "操作没有成功"
});
}
this.timeOutCloseLoad();
}).catch(ex => {
updateLoading(these, {
text: "出现异常" + JSON.stringify(ex)
});
this.timeOutCloseLoad();
});
},
importDoc() {
this.checkFile();
},
txtToAudio() {
let msg = "";
if (!this.formData.txt) {
msg = '请输入语音内容';
}
if (this.formData.txt.length > 100) {
msg = "内容限制在100字以内";
}
if (msg) {
this.showMsg(msg);
return;
}
hexs = [];
this.AudioData.hexLength=0;
showLoading(this, {
text: '正在生成语音'
});
let closeWaiting = () => {
setTimeout(() => {
hideLoading(this);
}, 2000)
}
let task = () => {
return new Promise((succ, err) => {
request({
url: "/app/video/audioTTS",
method: 'GET',
data: {
text: this.formData.txt
}
}).then(res => {
if (res && res.code && res.code === 200) {
succ(res.data);
} else {
err(res);
}
}).catch(ex => {
console.error("出现异常", ex);
err(res);
});
})
}
task().then(res => {
try {
debugger;
console.log("文本转语音成功", res);
hexs = res;
this.AudioData.hexLength =hexs.length;
this.AudioData.tempFilePath = "";
this.cEdit.localPath = "";
this.cEdit.time="";
this.playInit("");
updateLoading(this, {
text: '文本转语音成功'
});
} catch (error) {
console.error("出现错误,", error)
}
}).catch(ex => {
console.error("出现异常", ex);
updateLoading(this, {
text: '生成失败'
});
}).finally(closeWaiting);
},
timeOutCloseLoad() {
setTimeout(() => {
hideLoading(these);
}, 1200);
},
uploadLuYin() {
let key = Common.pcmStorageKey + "_" + this.cEdit.Id;
var store = uni.getStorageInfoSync();
var f = store.keys.includes(key);
if (f) {
return;
}
const token = uni.getStorageSync('token');
const clientid = uni.getStorageSync('clientID');
showLoading(this, {
text: "文件上传中"
});
console.log("token=", {
token: token,
clientid: clientid
});
setTimeout(() => {
uni.uploadFile({
url: baseURL + "/app/video/audio",
filePath: this.AudioData.tempFilePath,
name: 'file',
header: {
"Method": "POST",
"Content-Type": "multipart/form-data",
"Authorization": 'Bearer ' + token,
"clientid": clientid
},
timeout: 1200000,
fail: (ex) => {
updateLoading(these, {
text: "未知的原因上传失败"
});
this.timeOutCloseLoad();
},
success: (res) => {
// console.log("服务器响应=", res);
if (res && res.data) {
try {
res.data = JSON.parse(res.data);
if (res.data.code == 200) {
let pro1 = new Promise((resolve, reject) => {
uni.setStorage({
key: Common.pcmStorageKey + "_" + this
.cEdit.Id,
data: res.data.data,
success() {
resolve();
},
fail(ex) {
reject(ex)
}
});
});
let pro2 = new Promise((resolve, reject) => {
let array = uni.getStorageSync(Common
.audioStorageKey);
if (!array) {
array = [this.cEdit];
} else {
array.unshift(this.cEdit);
}
uni.setStorage({
key: Common.audioStorageKey,
data: array,
success() {
resolve();
},
fail(ex) {
reject(ex)
}
});
});
Promise.allSettled([pro1, pro2]).then(res => {
if (res[0].status == 'fulfilled' && res[1]
.status == 'fulfilled') {
updateLoading(these, {
text: "操作成功"
});
this.AudioData.tempFilePath = "";
this.Status.isRecord = false;
uni.navigateBack();
return;
} else {
updateLoading(these, {
text: "操作没有成功"
});
}
this.timeOutCloseLoad();
}).catch(ex => {
updateLoading(these, {
text: "出现异常" + JSON.stringify(ex)
});
this.timeOutCloseLoad();
});
return;
}
} catch (error) {
console.error("出现异常,", error);
}
}
updateLoading(these, {
text: "未知的异常上传失败"
});
this.timeOutCloseLoad();
},
complete() {
}
});
}, 10);
},
drop() {
this.showMsg("您确定删除该音频吗?", false, true, () => {
these.dropTmpFile();
this.cEdit = {
Id: "", //编号
name: "", //名称
createTime: "", //创建时间
localPath: "", //本地地址
webPath: "", //网络地址
statu: "", //状态,是否公开
isApply: "", //是否使用中
time: "", //音频总长度
currTime: '' //当前播放进度
};
this.Status.playState = "";
})
},
seek(intval) { //快进快退
let tmp = this.cEdit.currTime + intval;
console.log("tmp=" + tmp)
if (tmp < 0) {
this.cEdit.currTime = 0;
innerAudioContext.seekTo(0);
innerAudioContext.play();
} else if (tmp > this.cEdit.time) {
this.cEdit.currTime = this.cEdit.time;
innerAudioContext.seekTo(this.cEdit.time);
innerAudioContext.stop();
clearInterval(audioTime);
} else {
this.cEdit.currTime = tmp;
innerAudioContext.seekTo(tmp);
}
},
playToggle() {
if (this.Status.playState === '') {
this.showMsg("音频未就绪");
return;
}
if (innerAudioContext) {
if (this.Status.playState == 'play') {
innerAudioContext.pause();
} else {
innerAudioContext.play();
}
} else {
this.showMsg("播放器未就绪");
}
},
getFormatSeconds(seconds, Ms) {
if (!seconds) {
return "";
}
let totalSeconds = Math.floor(seconds);
let days = Math.floor(totalSeconds / 86400); // 1天=86400秒
let remainingSeconds = totalSeconds % 86400;
let hours = Math.floor(remainingSeconds / 3600);
let minutes = Math.floor((remainingSeconds % 3600) / 60);
let secs = remainingSeconds % 60;
// 补零处理
let paddedDays = String(days).padStart(2, '0');
let paddedHours = String(hours).padStart(2, '0');
let paddedMinutes = String(minutes).padStart(2, '0');
let paddedSecs = String(secs).padStart(2, '0');
if (Ms) {
return `${paddedMinutes}${paddedSecs}`;
}
return `${paddedMinutes}:${paddedSecs}`;
},
createAudioPlayer() {
try {
console.log("准备创建播放器");
if (innerAudioContext) {
this.destoryAudioPlayer();
clearInterval(audioTime);
this.cEdit.currTime = 0;
}
innerAudioContext = plus.audio.createPlayer({
src: this.cEdit.localPath,
autoplay: false,
backgroundControl: false,
});
console.log('播放器创建成功');
innerAudioContext.addEventListener('canplay', () => {
console.log("准备就绪,可以播放了");
this.Status.playState = 'ready';
this.cEdit.time = innerAudioContext.getDuration();
this.cEdit.time =Math.ceil(this.cEdit.time);
console.log("音频长度:", this.cEdit.time);
});
console.log("canplay事件注册成功")
//开始播放
innerAudioContext.addEventListener("play", (res) => {
if (this.Status.playState === 'ready') {
this.cEdit.currTime = 0;
}
this.Status.playState = 'play';
audioTime = setInterval(() => {
this.cEdit.currTime += 1;
}, 1000);
console.log("播放中", res);
});
console.log("play事件注册成功")
//播放结束
innerAudioContext.addEventListener("ended", (res) => {
clearInterval(audioTime);
this.cEdit.currTime = 0;
this.Status.playState = 'ready';
console.log("播放结束", res);
});
console.log("ended事件注册成功")
//暂停播放
innerAudioContext.addEventListener("pause", (res) => {
clearInterval(audioTime);
audioTime = null;
this.Status.playState = 'pause';
console.log("暂停了", res);
});
console.log("pause事件注册成功")
innerAudioContext.addEventListener("seeked", (res) => {
console.log("seek完成了", res);
})
console.log("seeked事件注册成功")
innerAudioContext.addEventListener('error',ex=>{
console.log("出错了",ex)
});
console.log("error事件注册成功");
this.Status.playState = 'ready';
} catch (ex) {
console.error("出现错误", ex);
}
},
destoryAudioPlayer() { //销毁播放器
if (innerAudioContext) {
innerAudioContext.close();
console.log("播放器已销毁");
}
},
handleUploadCallback(res) {
console.log("选择文件:", res);
if (res && res.data) {
if (this.Status.pageType === 'File') { //文件上传
if (res.data[0].type.indexOf('audio') > -1) {
this.cEdit.name = res.data[0].name;
this.playInit(res.data[0].tempFilePath);
} else {
this.showMsg("只能选择音频文件");
}
return;
}
if (this.Status.pageType === 'Txt') { //文字转语音
let file = res.data[0];
let path = file.tempFilePath;
let type = file.type;
if (type === 'application/vnd.openxmlformats-officedocument.wordprocessingml.document') {
this.parseWord(path); //docx
return;
}
if (type === 'text/plain') {
this.parseTxt(path); //txt
return;
}
if (type == "application/msword") { //doc
this.showPop({
showPop: true, //是否显示弹窗
popType: 'custom',
bgColor: '#383934bd',
borderColor: '#BBE600',
textColor: '#ffffffde',
buttonBgColor: '#BBE600',
buttonTextColor: '#232323DE',
iconUrl: '',
message: '打开文档后请手动复制文本内容',
buttonText: '打开',
clickEvt: '',
visiblePrompt: false,
promptTitle: '',
modelValue: '',
visibleClose: false,
okCallback: () => {
this.parseDoc(path);
},
showSlot: false,
buttonCancelText: '取消',
showCancel: true,
});
return;
}
this.showMsg("只能选择.txt、.docx、.doc文档");
return;
}
} else {
console.log("未选择任何文件");
}
},
parseTxt(txtPath) { //读取txt文件
showLoading(this, {
text: "文档读取中"
});
let promise = new Promise((resolve, reject) => {
plus.io.resolveLocalFileSystemURL(
txtPath,
(entry) => {
// 2. 获取文件对象
console.log("111111");
entry.file(
(file) => {
console.log("22222")
try {
let reader = new plus.io.FileReader();
reader.onloadend = function(e) {
// Get data
console.log("读取成功:", e.target.result);
resolve(e.target.result);
};
reader.onerror = function(ex) {
console.error("err=", ex)
reject("reader.onerror");
}
reader.readAsText(file);
} catch (err) {
console.error("err=", err);
reject(err.message)
}
},
(err) => {
console.error('获取文件对象失败:', err);
reject('获取文件对象失败')
}
);
},
(err) => {
console.error('解析文件路径失败:', err);
reject('解析文件路径失败')
}
);
});
promise.then(txt => {
this.formData.txt = txt;
updateLoading(this, {
text: '读取成功'
});
}).catch(ex => {
updateLoading(this, {
text: '无法读取文档'
});
}).finally(() => {
setTimeout(() => {
hideLoading(these);
}, 500)
})
},
parseDoc(filePath) {
uni.openDocument({
filePath: filePath,
fail(err) {
these.showMsg("无法打开文档");
}
});
},
parseWord(filePath) { //读取word文件
const token = uni.getStorageSync('token');
const clientid = uni.getStorageSync('clientID');
showLoading(this, {
text: "文档读取中"
});
let promise = new Promise((resolve, reject) => {
uni.uploadFile({
url: baseURL + "/app/video/extract",
filePath: filePath,
name: 'file',
header: {
"Method": "POST",
"Content-Type": "multipart/form-data",
"Authorization": 'Bearer ' + token,
"clientid": clientid
},
timeout: 600000,
fail: (ex) => {
reject('文件无法读取,请手动复制文本内容');
},
success: (res) => {
if (res.statusCode === 200) {
res = JSON.parse(res.data);
console.log("服务器响应=", res);
if (res && res.data) {
these.formData.txt = res.data;
updateLoading(this, {
text: '读取成功'
});
resolve();
return;
}
}
reject('文件无法读取,请手动复制文本内容');
},
complete() {
setTimeout(() => {
hideLoading(these);
}, 500);
}
});
});
promise.then(res => {}).catch(ex => {
updateLoading(these, {
text: ex
});
uni.openDocument({
filePath: filePath,
fail(err) {
console.error("无法打开文件", err);
}
});
});
},
checkFile() {
this.$refs.XeUpload.upload('file');
},
toggleRecord() {
if (this.Status.recoderIntval) {
this.stopLuYin();
} else {
this.startLuYin();
}
},
playInit(tempFilePath) {
let task = (path) => {
try {
console.log("path=", path);
this.AudioData.tempFilePath = path;
this.cEdit.localPath = path;
this.cEdit.Id = Common.guid();
this.cEdit.createTime = Common.DateFormat(new Date(), "yyyy年MM月dd日");
this.cEdit.isApply = false;
this.cEdit.statu = false;
this.cEdit.type=this.Status.pageType;
this.cEdit.webPath = "";
console.log("aaaaaaaaaaaaaaaaaaa");
if(path){
this.createAudioPlayer();
}
else{
this.cEdit.time="";
}
} catch (exx) {
console.error("exx=", exx)
}
}
//将文件移动到downloads目录因为doc目录会丢失
Common.moveFileToDownloads(tempFilePath).then(res => {
console.log("文件移动成功", res);
task(res);
}).catch(ex => {
console.error("文件移动失败了", ex);
task(tempFilePath);
});
},
startLuYin() {
this.destoryAudioPlayer();
if (!AudeoRecoder) {
// #ifdef APP
try {
AudeoRecoder = uni.getRecorderManager();
AudeoRecoder.onStop(function(res) {
try {
console.log('录音停止:' + JSON.stringify(res));
these.AudioData = res;
these.cEdit.time = these.Status.RecordTime;
these.cEdit.name = "语音录制" + these.Status.RecordName;
if (these.Status.pageValid) {
these.dropTmpFile();
these.Status.pageValid = false;
AudeoRecoder = null;
} else {
these.playInit(these.AudioData.tempFilePath);
}
} catch (ex) {
console.error("ex=", ex);
}
});
} catch (ex) {
}
// #endif
}
let startTask = () => {
clearInterval(this.Status.recoderIntval);
this.Status.recoderIntval = null;
// #ifdef APP
try {
AudeoRecoder.start({
duration: 60000,
sampleRate: 44100,
format: 'wav',
frameSize: 16
});
} catch (error) {
//TODO handle the exception
}
// #endif
this.Status.RecordTime = 0;
this.Status.RecordName = Common.DateFormat(new Date(), "yyyyMMddHHmmss");
this.AudioData.tempFilePath = "";
this.Status.recoderIntval = setInterval(() => {
this.Status.RecordTime += 1;
if (this.Status.RecordTime >= 60) {
this.toggleRecord();
}
}, 1000);
this.Status.isRecord = !this.Status.isRecord;
}
if (this.AudioData.tempFilePath) {
this.showMsg("当前录音未保存,您要放弃该录音吗?", false, true, () => {
these.dropTmpFile();
startTask();
})
} else {
startTask()
}
},
stopLuYin() {
debugger;
clearInterval(this.Status.recoderIntval);
this.Status.recoderIntval = null;
try {
AudeoRecoder.stop();
} catch (ex) {
if (!these.Status.pageValid) {
these.AudioData.tempFilePath = "_doc/" + this.Status.RecordName + ".mp3"
}
} finally {
this.Status.isRecord = !this.Status.isRecord;
}
},
dropTmpFile() {
//删除丢弃的文件
// #ifdef APP
if (!these.AudioData.tempFilePath) {
return;
}
try {
plus.io.resolveLocalFileSystemURL(these.AudioData.tempFilePath, (entry) => {
// 确认是文件类型
if (entry.isFile) {
entry.remove(
() => {
console.log('文件删除成功');
// 删除成功后的逻辑
these.AudioData.tempFilePath = "";
},
(err) => {
console.error('文件删除失败:', err.message);
}
);
} else {
console.error('路径指向的不是文件');
}
}, (err) => {
console.error('路径解析失败:', err.message);
});
} catch (error) {
}
// #endif
},
closePop: function() {
this.Status.Pop.showPop = false;
if (this.Status.Pop.cancelCallback) {
this.Status.Pop.cancelCallback();
}
},
HidePop: function() {
this.Status.Pop.showPop = false;
if (this.Status.Pop.okCallback) {
this.Status.Pop.okCallback();
}
},
showPop: function(option) {
hideLoading(this);
let def = {
showPop: true, //是否显示弹窗
popType: 'custom',
bgColor: '#383934bd',
borderColor: '#BBE600',
textColor: '#ffffffde',
buttonBgColor: '#BBE600',
buttonTextColor: '#232323DE',
iconUrl: '',
message: '',
buttonText: '确定',
clickEvt: '',
visiblePrompt: false,
promptTitle: '',
modelValue: '',
visibleClose: false,
okCallback: null,
showSlot: false,
buttonCancelText: '',
showCancel: false,
}
let keys = Object.keys(def);
for (let i = 0; i < keys.length; i++) {
let key = keys[i];
if (key in option) {
continue;
}
this.Status.Pop[key] = def[key];
}
if (option) {
keys = Object.keys(option);
for (let i = 0; i < keys.length; i++) {
let key = keys[i];
this.Status.Pop[key] = option[key];
}
}
if (!option.borderColor) {
option.borderColor = '#BBE600';
option.buttonBgColor = '#BBE600';
}
these.Status.Pop.showPop = true;
},
showMsg(msg, isSucc, showCancel, okCallback) {
if (showCancel === undefined) {
showCancel = false;
}
if (okCallback === undefined) {
okCallback = null;
}
let icoUrl = '/static/images/6155/DeviceDetail/uploadErr.png';
let borderColor = "#e034344d";
let buttonBgColor = "#E03434";
if (isSucc) {
icoUrl = '/static/images/common/success.png';
borderColor = "#BBE600";
buttonBgColor = "#BBE600";
}
this.showPop({
message: msg,
iconUrl: icoUrl,
borderColor: borderColor,
buttonBgColor: buttonBgColor,
buttonText: '确定',
okCallback: okCallback,
showCancel: showCancel,
});
}
}
}
</script>
<style>
.footer .opt {
display: flex;
flex-direction: column;
flex-wrap: wrap;
align-content: center;
align-items: center;
justify-content: flex-start;
}
.footer .recordTitle {
color: rgba(255, 255, 255, 0.87);
font-family: PingFang SC;
font-size: 28rpx;
font-weight: 400;
line-height: 40rpx;
letter-spacing: 0.14rpx;
text-align: center;
}
.footer .recordName {
color: rgba(255, 255, 255, 0.6);
font-family: PingFang SC;
font-size: 24rpx;
font-weight: 400;
line-height: 34rpx;
letter-spacing: 0.14px;
text-align: center;
margin-bottom: 40rpx;
}
.footer .btnRecord .start {
background: rgba(224, 52, 52, 1);
width: 80rpx;
height: 80rpx;
border-radius: 50%;
}
.footer .btnRecord .start.active {
border-radius: 8rpx;
background: rgba(224, 52, 52, 1);
width: 40rpx;
height: 40rpx;
}
.footer .btnRecord {
width: 110rpx;
height: 110rpx;
box-sizing: border-box;
border: 4rpx solid rgba(255, 255, 255, 0.6);
border-radius: 50%;
}
.footer .btnRemark {
color: rgba(255, 255, 255, 0.6);
margin-top: 20rpx;
font-family: PingFang SC;
font-size: 28rpx;
font-weight: 400;
line-height: 40rpx;
letter-spacing: 0.14px;
text-align: center;
}
.footer {
padding-top: 60rpx;
padding-bottom: 60rpx;
width: 100%;
height: auto;
position: fixed;
z-index: 99;
left: 0rpx;
bottom: 0rpx;
border-radius: 16rpx 16rpx 0px 0px;
background: rgba(26, 26, 26, 1);
display: flex;
flex-direction: column;
flex-wrap: nowrap;
align-content: center;
align-items: center;
justify-content: flex-start;
}
.popup-prompt {
width: 100%;
margin-top: 40rpx;
}
.popup-prompt-input {
width: 100%;
height: 80rpx;
line-height: 80rpx;
border: 1rpx solid #BBE60096;
border-radius: 10rpx;
padding: 0 20rpx;
margin-bottom: 30rpx;
font-size: 26rpx;
box-sizing: border-box;
text-align: left;
}
.tips {
color: rgba(255, 255, 255, 0.6);
font-family: PingFang SC;
font-size: 28rpx;
font-weight: 400;
line-height: 40rpx;
letter-spacing: 0.14rpx;
text-align: left;
}
.polygon {
width: 300rpx;
height: 150rpx;
background-color: #3A3A3A;
border-radius: 10rpx;
color: rgba(255, 255, 255, 0.6);
;
}
.cEdit {
width: 100%;
height: auto;
border-radius: 8px;
background: rgba(26, 26, 26, 1);
box-sizing: border-box;
padding: 40rpx 30rpx
}
.btnSave {
width: 130rpx;
height: 55rpx;
line-height: 55rpx;
text-align: center;
color: rgba(23, 23, 23, 1);
font-family: PingFang SC;
font-size: 24rpx;
font-weight: 400;
letter-spacing: 12rpx;
background-color: #BBE600;
border-radius: 180rpx;
}
.txtName {
color: rgba(174, 214, 0, 1);
border-bottom: 1rpx solid rgba(174, 214, 0, 1);
font-family: PingFang SC;
font-size: 32rpx;
font-weight: 400;
line-height: 44rpx;
letter-spacing: 0.14px;
text-align: left;
margin-bottom: 10rpx;
}
.audioRemark {
display: flex;
flex-wrap: nowrap;
align-content: center;
align-items: center;
justify-content: space-between;
}
.slide {
padding-top: 60rpx;
width: 100%;
position: relative;
}
.slide .line {
width: 100%;
height: 4rpx;
border-radius: 12rpx;
background: rgba(106, 106, 106, 1);
}
.slide .circle {
position: absolute;
margin-top: -4rpx;
width: 12rpx;
height: 12rpx;
background: rgba(234, 234, 234, 1);
border-radius: 50%;
}
.control {
width: 100%;
padding: 40rpx;
position: relative;
}
.control .playControl {
width: 100%;
position: absolute;
left: 0rpx;
bottom: 0rpx;
z-index: 1;
display: flex;
flex-direction: row;
flex-wrap: nowrap;
align-content: center;
align-items: center;
justify-content: center;
}
.control .drop {
position: absolute;
z-index: 2;
bottom: 0rpx;
right: 0rpx;
}
.playControl .seek .img {
width: 32rpx;
height: 32rpx;
}
.playControl .play .img {
width: 38rpx;
height: 44rpx;
margin: 0rpx 80rpx;
}
.input {
border-bottom: 1rpx solid #FFFFFF;
}
.placehoderClass {
color: rgba(255, 255, 255, 0.6);
font-family: PingFang SC;
font-size: 32rpx;
font-weight: 400;
line-height: 44rpx;
letter-spacing: 0.14px;
}
.text-content {
border-radius: 16rpx;
background: rgba(26, 26, 26, 1);
width: 100%;
height: auto;
box-sizing: border-box;
padding: 20rpx;
margin-bottom: 20rpx;
}
.importTxt {
color: rgba(174, 214, 0, 1);
font-family: PingFang SC;
font-size: 28rpx;
font-weight: 400;
height: 60rpx;
line-height: 60rpx;
letter-spacing: 0.14px;
}
.textarea {
min-height: 300rpx;
width: 100%;
box-sizing: border-box;
}
.line {
width: 100%;
height: 0rpx;
border-bottom: 1rpx solid rgba(255, 255, 255, 0.36);
margin-bottom: 20rpx;
}
.footBtn {
width: 100%;
}
.footBtn .convert {
/* 组合 99 */
width: 130rpx;
height: 55rpx;
line-height: 55rpx;
border-radius: 180px;
color: #232323;
background-color: #AED600;
text-align: center;
font-family: PingFang SC;
font-size: 24rpx;
font-weight: 400;
letter-spacing: 12rpx;
}
.footBtn .audioSett,
.audioSett{
margin-right: 50rpx;
color: #FFFFFFDE;
color: rgba(255, 255, 255, 0.87);
font-family: PingFang SC;
font-size: 28rpx;
font-weight: 400;
line-height: 55rpx;
letter-spacing: 0px;
text-align: center;
}
.txtBtns{
box-sizing: border-box;
width: 100%;
padding:20rpx;
}
</style>