302 lines
9.4 KiB
TypeScript
302 lines
9.4 KiB
TypeScript
import { taskinfo, uploadavatar, uploadrecord, checkavatar, checkvoice, saveHumanAssets } from "../../../utils/request"
|
|||
|
|
|
||
|
|
const waveBars = [
|
||
|
|
{ id: 'b1', cls: 'bar-22' },
|
||
|
|
{ id: 'b2', cls: 'bar-34' },
|
||
|
|
{ id: 'b3', cls: 'bar-48' },
|
||
|
|
{ id: 'b4', cls: 'bar-34' },
|
||
|
|
{ id: 'b5', cls: 'bar-62' },
|
||
|
|
{ id: 'b6', cls: 'bar-42' },
|
||
|
|
{ id: 'b7', cls: 'bar-70' },
|
||
|
|
{ id: 'b8', cls: 'bar-52' },
|
||
|
|
{ id: 'b9', cls: 'bar-38' },
|
||
|
|
{ id: 'b10', cls: 'bar-58' },
|
||
|
|
{ id: 'b11', cls: 'bar-46' },
|
||
|
|
{ id: 'b12', cls: 'bar-30' },
|
||
|
|
]
|
||
|
|
const miniBars = [
|
||
|
|
{ id: 'm1', cls: 'mini-bar-18' },
|
||
|
|
{ id: 'm2', cls: 'mini-bar-30' },
|
||
|
|
{ id: 'm3', cls: 'mini-bar-46' },
|
||
|
|
{ id: 'm4', cls: 'mini-bar-28' },
|
||
|
|
{ id: 'm5', cls: 'mini-bar-56' },
|
||
|
|
{ id: 'm6', cls: 'mini-bar-36' },
|
||
|
|
]
|
||
|
|
|
||
|
|
function formatRecordTime(totalSeconds: number) {
|
||
|
|
const minutes = Math.floor(totalSeconds / 60)
|
||
|
|
const seconds = totalSeconds % 60
|
||
|
|
return `${String(minutes).padStart(2, '0')}:${String(seconds).padStart(2, '0')}`
|
||
|
|
}
|
||
|
|
|
||
|
|
Page({
|
||
|
|
recordTimer: 0,
|
||
|
|
voiceCheckTimer: 0,
|
||
|
|
|
||
|
|
data: {
|
||
|
|
isRecording: false,
|
||
|
|
recordingClass: 'recording-active',
|
||
|
|
elapsedSeconds: 0,
|
||
|
|
recordTime: '00:00',
|
||
|
|
waveBars,
|
||
|
|
miniBars,
|
||
|
|
taskinfo: null as any,
|
||
|
|
avatar: '/static/images/my/image.png',
|
||
|
|
avatarUrl: '',
|
||
|
|
avatarChecked: false,
|
||
|
|
recordUrl: '',
|
||
|
|
recordDurationMs: 0,
|
||
|
|
voiceAsrTaskId: '',
|
||
|
|
voiceChecked: false,
|
||
|
|
voiceText: '',
|
||
|
|
voiceStatusText: ''
|
||
|
|
},
|
||
|
|
|
||
|
|
|
||
|
|
onLoad(ops: any) {
|
||
|
|
taskinfo(ops.taskid).then((res: any) => {
|
||
|
|
if (!res.code) {
|
||
|
|
this.setData({ taskinfo: res.data });
|
||
|
|
}
|
||
|
|
})
|
||
|
|
},
|
||
|
|
|
||
|
|
onShow() {
|
||
|
|
if (this.data.isRecording) {
|
||
|
|
this.startRecordTimer()
|
||
|
|
}
|
||
|
|
},
|
||
|
|
|
||
|
|
onHide() {
|
||
|
|
this.clearRecordTimer()
|
||
|
|
this.clearVoiceCheckTimer()
|
||
|
|
},
|
||
|
|
|
||
|
|
onUnload() {
|
||
|
|
this.clearRecordTimer()
|
||
|
|
this.clearVoiceCheckTimer()
|
||
|
|
},
|
||
|
|
|
||
|
|
handleBack() {
|
||
|
|
wx.navigateBack({
|
||
|
|
fail: () => wx.navigateTo({ url: '/pages/aiPackage/preview/index' }),
|
||
|
|
})
|
||
|
|
},
|
||
|
|
|
||
|
|
handleUploadPhoto() {
|
||
|
|
const that = this;
|
||
|
|
wx.chooseImage({
|
||
|
|
count: 1,
|
||
|
|
success(res: any) {
|
||
|
|
const file = res.tempFilePaths[0];
|
||
|
|
wx.showLoading({ mask: true, title: '上传照片中' });
|
||
|
|
uploadavatar(file, {}, '/api/upload/avatar').then((uploadRes: any) => {
|
||
|
|
if (uploadRes.code) {
|
||
|
|
wx.hideLoading();
|
||
|
|
wx.showModal({ title: '温馨提示', content: uploadRes.message || '照片上传失败', showCancel: false })
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
wx.showLoading({ mask: true, title: '人脸检测中' });
|
||
|
|
checkavatar(uploadRes.data.url).then((checkRes: any) => {
|
||
|
|
wx.hideLoading();
|
||
|
|
if (!checkRes.code) {
|
||
|
|
that.setData({ avatar: uploadRes.data.url, avatarUrl: uploadRes.data.url, avatarChecked: true })
|
||
|
|
wx.showToast({ title: '照片检测通过', icon: 'success' })
|
||
|
|
} else {
|
||
|
|
that.setData({ avatarUrl: '', avatarChecked: false })
|
||
|
|
wx.showModal({ title: '温馨提示', content: checkRes.message || '未检测到人脸', showCancel: false })
|
||
|
|
}
|
||
|
|
}).catch(() => {
|
||
|
|
wx.hideLoading();
|
||
|
|
that.setData({ avatarUrl: '', avatarChecked: false })
|
||
|
|
wx.showModal({ title: '温馨提示', content: '人脸检测失败,请稍后再试', showCancel: false })
|
||
|
|
})
|
||
|
|
}).catch(() => {
|
||
|
|
wx.hideLoading();
|
||
|
|
wx.showModal({ title: '温馨提示', content: '网络异常,请稍后再试', showCancel: false })
|
||
|
|
})
|
||
|
|
}
|
||
|
|
})
|
||
|
|
},
|
||
|
|
|
||
|
|
handleUseDefaultAvatar() {
|
||
|
|
wx.showToast({ title: '暂未配置默认形象', icon: 'none' })
|
||
|
|
},
|
||
|
|
|
||
|
|
handleRecord() {
|
||
|
|
if (this.data.isRecording) return
|
||
|
|
|
||
|
|
if (this.recordTimer) {
|
||
|
|
clearTimeout(this.recordTimer);
|
||
|
|
clearInterval(this.recordTimer);
|
||
|
|
}
|
||
|
|
|
||
|
|
this.clearVoiceCheckTimer()
|
||
|
|
this.recordTimer = 0;
|
||
|
|
|
||
|
|
this.setData({
|
||
|
|
isRecording: true,
|
||
|
|
recordTime: '00:00',
|
||
|
|
elapsedSeconds: 0,
|
||
|
|
recordingClass: 'recording-active',
|
||
|
|
recordUrl: '',
|
||
|
|
recordDurationMs: 0,
|
||
|
|
voiceAsrTaskId: '',
|
||
|
|
voiceChecked: false,
|
||
|
|
voiceText: '',
|
||
|
|
voiceStatusText: ''
|
||
|
|
})
|
||
|
|
this.startRecordTimer()
|
||
|
|
},
|
||
|
|
|
||
|
|
handleUseDefaultVoice() {
|
||
|
|
this.clearRecordTimer()
|
||
|
|
this.clearVoiceCheckTimer()
|
||
|
|
this.setData({ isRecording: false, recordingClass: '' })
|
||
|
|
wx.showToast({ title: '暂未配置默认音色', icon: 'none' })
|
||
|
|
},
|
||
|
|
|
||
|
|
handleStopRecord() {
|
||
|
|
this.clearRecordTimer()
|
||
|
|
this.recordTimer = 0;
|
||
|
|
this.setData({ isRecording: false, recordingClass: '' })
|
||
|
|
wx.getRecorderManager().stop()
|
||
|
|
},
|
||
|
|
|
||
|
|
handleNext() {
|
||
|
|
if (!this.data.taskinfo || !this.data.taskinfo.task_no) {
|
||
|
|
wx.showModal({ title: '温馨提示', content: '创作记录不存在', showCancel: false })
|
||
|
|
return
|
||
|
|
}
|
||
|
|
if (!this.data.avatarChecked || !this.data.avatarUrl) {
|
||
|
|
wx.showModal({ title: '温馨提示', content: '请先上传并通过数字人照片检测', showCancel: false })
|
||
|
|
return
|
||
|
|
}
|
||
|
|
if (!this.data.voiceChecked || !this.data.recordUrl || !this.data.voiceText) {
|
||
|
|
wx.showModal({ title: '温馨提示', content: '请先录制并通过音色检测', showCancel: false })
|
||
|
|
return
|
||
|
|
}
|
||
|
|
|
||
|
|
wx.showLoading({ mask: true, title: '保存中' })
|
||
|
|
saveHumanAssets({
|
||
|
|
taskId: this.data.taskinfo.task_no,
|
||
|
|
avatarUrl: this.data.avatarUrl,
|
||
|
|
voiceUrl: this.data.recordUrl,
|
||
|
|
voiceText: this.data.voiceText,
|
||
|
|
durationMs: this.data.recordDurationMs,
|
||
|
|
asrTaskId: this.data.voiceAsrTaskId
|
||
|
|
}).then((res: any) => {
|
||
|
|
wx.hideLoading()
|
||
|
|
if (!res.code) {
|
||
|
|
wx.redirectTo({ url: '/pages/aiPackage/bg/index?taskId=' + encodeURIComponent(this.data.taskinfo.task_no) })
|
||
|
|
} else {
|
||
|
|
wx.showModal({ title: '温馨提示', content: res.message || '保存失败', showCancel: false })
|
||
|
|
}
|
||
|
|
}).catch(() => {
|
||
|
|
wx.hideLoading()
|
||
|
|
wx.showModal({ title: '温馨提示', content: '网络异常,请稍后再试', showCancel: false })
|
||
|
|
})
|
||
|
|
},
|
||
|
|
|
||
|
|
startRecordTimer() {
|
||
|
|
let that = this;
|
||
|
|
that.clearRecordTimer()
|
||
|
|
that.recordTimer = setInterval(() => {
|
||
|
|
const elapsedSeconds = that.data.elapsedSeconds + 1
|
||
|
|
that.setData({ elapsedSeconds, recordTime: formatRecordTime(elapsedSeconds) })
|
||
|
|
}, 1000) as unknown as number
|
||
|
|
|
||
|
|
let recorder = wx.getRecorderManager();
|
||
|
|
recorder.onError(that.onRecordError.bind(that));
|
||
|
|
recorder.onStop(that.onRecordStop.bind(that))
|
||
|
|
recorder.start({ duration: 10000, format: 'mp3' });
|
||
|
|
},
|
||
|
|
|
||
|
|
onRecordError(err: any) {
|
||
|
|
console.log(err)
|
||
|
|
this.clearRecordTimer()
|
||
|
|
this.setData({ isRecording: false, recordingClass: '' })
|
||
|
|
wx.showModal({ title: '温馨提示', content: '录音失败,请重新录制', showCancel: false })
|
||
|
|
},
|
||
|
|
|
||
|
|
onRecordStop(resource: { duration: number, fileSize: number, tempFilePath: string }) {
|
||
|
|
this.clearRecordTimer()
|
||
|
|
this.recordTimer = 0;
|
||
|
|
this.setData({ isRecording: false, recordingClass: '', voiceStatusText: '录音上传中' })
|
||
|
|
|
||
|
|
wx.showLoading({ mask: true, title: '上传录音中' })
|
||
|
|
uploadrecord(resource.tempFilePath).then((res: any) => {
|
||
|
|
if (res.code) {
|
||
|
|
wx.hideLoading()
|
||
|
|
this.setData({ voiceStatusText: '', voiceChecked: false })
|
||
|
|
wx.showModal({ title: '温馨提示', content: res.message || '录音上传失败', showCancel: false })
|
||
|
|
return
|
||
|
|
}
|
||
|
|
|
||
|
|
this.setData({
|
||
|
|
recordUrl: res.data.url,
|
||
|
|
recordDurationMs: res.data.durationMs || resource.duration || 0,
|
||
|
|
voiceAsrTaskId: '',
|
||
|
|
voiceChecked: false,
|
||
|
|
voiceText: '',
|
||
|
|
voiceStatusText: '录音识别中'
|
||
|
|
})
|
||
|
|
this.pollVoiceCheck('')
|
||
|
|
}).catch(() => {
|
||
|
|
wx.hideLoading()
|
||
|
|
this.setData({ voiceStatusText: '', voiceChecked: false })
|
||
|
|
wx.showModal({ title: '温馨提示', content: '网络异常,请稍后再试', showCancel: false })
|
||
|
|
})
|
||
|
|
},
|
||
|
|
|
||
|
|
pollVoiceCheck(asrTaskId: string) {
|
||
|
|
checkvoice(this.data.recordUrl, asrTaskId).then((res: any) => {
|
||
|
|
if (res.code === 200) {
|
||
|
|
wx.hideLoading()
|
||
|
|
const nextTaskId = res.data && res.data.asrTaskId ? res.data.asrTaskId : asrTaskId
|
||
|
|
this.setData({ voiceAsrTaskId: nextTaskId, voiceStatusText: '录音识别中' })
|
||
|
|
this.clearVoiceCheckTimer()
|
||
|
|
this.voiceCheckTimer = setTimeout(() => {
|
||
|
|
this.pollVoiceCheck(nextTaskId)
|
||
|
|
}, 1500) as unknown as number
|
||
|
|
return
|
||
|
|
}
|
||
|
|
|
||
|
|
wx.hideLoading()
|
||
|
|
if (!res.code) {
|
||
|
|
this.clearVoiceCheckTimer()
|
||
|
|
this.setData({
|
||
|
|
voiceAsrTaskId: res.data.asrTaskId,
|
||
|
|
voiceText: res.data.recognizedText,
|
||
|
|
voiceChecked: true,
|
||
|
|
voiceStatusText: '录音检测通过'
|
||
|
|
})
|
||
|
|
wx.showToast({ title: '音色检测通过', icon: 'success' })
|
||
|
|
} else {
|
||
|
|
this.clearVoiceCheckTimer()
|
||
|
|
this.setData({ voiceChecked: false, voiceStatusText: '' })
|
||
|
|
wx.showModal({ title: '温馨提示', content: res.message || '录音识别失败,请重新录制', showCancel: false })
|
||
|
|
}
|
||
|
|
}).catch(() => {
|
||
|
|
wx.hideLoading()
|
||
|
|
this.clearVoiceCheckTimer()
|
||
|
|
this.setData({ voiceChecked: false, voiceStatusText: '' })
|
||
|
|
wx.showModal({ title: '温馨提示', content: '录音识别失败,请稍后再试', showCancel: false })
|
||
|
|
})
|
||
|
|
},
|
||
|
|
|
||
|
|
clearRecordTimer() {
|
||
|
|
if (!this.recordTimer) return
|
||
|
|
clearInterval(this.recordTimer)
|
||
|
|
this.recordTimer = 0
|
||
|
|
},
|
||
|
|
|
||
|
|
clearVoiceCheckTimer() {
|
||
|
|
if (!this.voiceCheckTimer) return
|
||
|
|
clearTimeout(this.voiceCheckTimer)
|
||
|
|
this.voiceCheckTimer = 0
|
||
|
|
},
|
||
|
|
})
|
||
|
|
|