|
@@ -1,6 +1,13 @@
|
|
|
<template>
|
|
<template>
|
|
|
<div class="pptEasyClass">
|
|
<div class="pptEasyClass">
|
|
|
<div class="pec_main" v-loading="pageLoading">
|
|
<div class="pec_main" v-loading="pageLoading">
|
|
|
|
|
+ <!-- 录音转文字 -->
|
|
|
|
|
+ <iframe
|
|
|
|
|
+ allow="camera *; microphone *;display-capture;midi;encrypted-media;"
|
|
|
|
|
+ src="https://beta.cloud.cocorobo.cn/browser/public/index.html"
|
|
|
|
|
+ ref="iiframe"
|
|
|
|
|
+ v-show="false"
|
|
|
|
|
+ ></iframe>
|
|
|
<div class="pec_header">
|
|
<div class="pec_header">
|
|
|
<div class="pec_h_left">
|
|
<div class="pec_h_left">
|
|
|
<div @click.stop="back" class="backBtn" v-if="screenType != 2 || tType == 1">
|
|
<div @click.stop="back" class="backBtn" v-if="screenType != 2 || tType == 1">
|
|
@@ -44,10 +51,9 @@
|
|
|
</div>
|
|
</div>
|
|
|
<div class="pec_h_right">
|
|
<div class="pec_h_right">
|
|
|
<div class="pec_h_r_btnArea">
|
|
<div class="pec_h_r_btnArea">
|
|
|
- <!-- <div class="pec_h_r_btn_refresh" @click="refreshCourse">
|
|
|
|
|
- <img src="../../assets/icon/newIcons/refresh.png" alt="" />
|
|
|
|
|
- <span>刷新</span>
|
|
|
|
|
- </div> -->
|
|
|
|
|
|
|
+ <div class="pec_h_r_btn_refresh" :class="{ 'recording': recordedForm.status == 1 }" @click="toggleRecording" v-show="(jArray.includes(oid) || jArray.includes(org)) && courseDetail.userid == userid">
|
|
|
|
|
+ <span>{{ recordedForm.status == 1 ? '结束录音' : '开始录音' }}</span>
|
|
|
|
|
+ </div>
|
|
|
<div class="pec_h_r_btn_afterClass" @click="afterClass" v-if="courseDetail.userid == userid">
|
|
<div class="pec_h_r_btn_afterClass" @click="afterClass" v-if="courseDetail.userid == userid">
|
|
|
<img src="../../assets/icon/newIcon/afterClass.svg" alt="" />
|
|
<img src="../../assets/icon/newIcon/afterClass.svg" alt="" />
|
|
|
<span>下课</span>
|
|
<span>下课</span>
|
|
@@ -95,6 +101,29 @@ export default {
|
|
|
startTime: "",
|
|
startTime: "",
|
|
|
freeBrowse: true, // 默认自由浏览
|
|
freeBrowse: true, // 默认自由浏览
|
|
|
opertimer: null, // 定时器
|
|
opertimer: null, // 定时器
|
|
|
|
|
+ jArray: [],
|
|
|
|
|
+ // 录音相关变量
|
|
|
|
|
+ languageRadio: 2, // 语言选择
|
|
|
|
|
+ recordedForm: {
|
|
|
|
|
+ status: 0, // 0: 未开始, 1: 录音中, 2: 暂停, 3: 结束
|
|
|
|
|
+ startTime: 0,
|
|
|
|
|
+ endTime: 0,
|
|
|
|
|
+ timeDuration: 0,
|
|
|
|
|
+ textList: [],
|
|
|
|
|
+ audioBlob: []
|
|
|
|
|
+ },
|
|
|
|
|
+ controlsStatus: 0, // 控制状态
|
|
|
|
|
+ showIndexPage: true, // 显示索引页
|
|
|
|
|
+ pageStatus: 1, // 页面状态
|
|
|
|
|
+ editorBarData: {
|
|
|
|
|
+ type: "0",
|
|
|
|
|
+ content: ""
|
|
|
|
|
+ },
|
|
|
|
|
+ uploadFileLoading: false, // 上传文件加载状态
|
|
|
|
|
+ transcriptionData: {
|
|
|
|
|
+ content: ""
|
|
|
|
|
+ },
|
|
|
|
|
+ showGetTextLoading: false, // 显示获取文本加载状态
|
|
|
};
|
|
};
|
|
|
},
|
|
},
|
|
|
methods: {
|
|
methods: {
|
|
@@ -104,6 +133,136 @@ export default {
|
|
|
refreshCourse() {
|
|
refreshCourse() {
|
|
|
this.getCourseDetail();
|
|
this.getCourseDetail();
|
|
|
},
|
|
},
|
|
|
|
|
+ audioStart(){
|
|
|
|
|
+ this.onStartRecordWithMicrosoft();
|
|
|
|
|
+ },
|
|
|
|
|
+ toggleRecording() {
|
|
|
|
|
+ if (this.recordedForm.status == 1) {
|
|
|
|
|
+ this.onFinishRecordWithMicrosoft();
|
|
|
|
|
+ } else {
|
|
|
|
|
+ this.onStartRecordWithMicrosoft();
|
|
|
|
|
+ }
|
|
|
|
|
+ },
|
|
|
|
|
+ // ============ start 微软录音转译
|
|
|
|
|
+ onStartRecordWithMicrosoft() {
|
|
|
|
|
+ let iiframe = this.$refs["iiframe"];
|
|
|
|
|
+ iiframe.contentWindow.window.document.getElementById(
|
|
|
|
|
+ "languageOptions"
|
|
|
|
|
+ ).selectedIndex = this.languageRadio;
|
|
|
|
|
+
|
|
|
|
|
+ // 录音开始
|
|
|
|
|
+ let flag = true;
|
|
|
|
|
+ console.log("开始录音", iiframe);
|
|
|
|
|
+ this.recordedForm.status = 1;
|
|
|
|
|
+ iiframe.contentWindow.window.onRecognizedResult = e => {
|
|
|
|
|
+ console.log("onRecognizedResult", e);
|
|
|
|
|
+ this.recordedForm.endTime = this.recordedForm.timeDuration;
|
|
|
|
|
+ if (flag) {
|
|
|
|
|
+ this.controlsStatus = 1;
|
|
|
|
|
+ this.showIndexPage = false;
|
|
|
|
|
+ this.pageStatus = 2;
|
|
|
|
|
+ this.editorBarData.type = "0";
|
|
|
|
|
+ flag = false;
|
|
|
|
|
+ this.uploadFileLoading = false;
|
|
|
|
|
+ this.transcriptionData.content = "";
|
|
|
|
|
+ this.editorBarData.content = "";
|
|
|
|
|
+ this.recordedForm.textList = [];
|
|
|
|
|
+ }
|
|
|
|
|
+ this.showGetTextLoading = true;
|
|
|
|
|
+ let privText = e.privText;
|
|
|
|
|
+ let privSpeakerId = e.privSpeakerId;
|
|
|
|
|
+ let _copyPrivSpeakerId = privSpeakerId;
|
|
|
|
|
+ console.log("👇转译对象👇");
|
|
|
|
|
+ console.log(e);
|
|
|
|
|
+ console.log("👇转译结果👇");
|
|
|
|
|
+ console.log(privText);
|
|
|
|
|
+ if (!privText || !privSpeakerId || privSpeakerId == "Unknown") {
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ const newItem = {
|
|
|
|
|
+ value: privText,
|
|
|
|
|
+ role: "",
|
|
|
|
|
+ startTime: this.updateRecordedTime({
|
|
|
|
|
+ duration: this.recordedForm.startTime
|
|
|
|
|
+ }),
|
|
|
|
|
+ endTime: this.updateRecordedTime({
|
|
|
|
|
+ duration: this.recordedForm.endTime
|
|
|
|
|
+ }),
|
|
|
|
|
+ time: this.updateRecordedTime({
|
|
|
|
|
+ duration: this.recordedForm.endTime - this.recordedForm.startTime
|
|
|
|
|
+ })
|
|
|
|
|
+ };
|
|
|
|
|
+ this.recordedForm.textList.push(newItem);
|
|
|
|
|
+ this.recordedForm.startTime = this.recordedForm.timeDuration + 1;
|
|
|
|
|
+ this.transcriptionData.content +=
|
|
|
|
|
+ _copyPrivSpeakerId + ":" + privText + "\n";
|
|
|
|
|
+ this.onRecordAddLine(newItem);
|
|
|
|
|
+ };
|
|
|
|
|
+
|
|
|
|
|
+ iiframe.contentWindow.ConversationTranscriber();
|
|
|
|
|
+ },
|
|
|
|
|
+ onFinishRecordWithMicrosoft() {
|
|
|
|
|
+ if (this.recordedForm.status == 1) {
|
|
|
|
|
+ //正在录音时
|
|
|
|
|
+ let iiframe = this.$refs["iiframe"];
|
|
|
|
|
+ iiframe.contentWindow.window.document
|
|
|
|
|
+ .getElementById("scenarioStopButton")
|
|
|
|
|
+ .click();
|
|
|
|
|
+ // 录音借宿
|
|
|
|
|
+ iiframe.contentWindow.onSessionStopped = (s, e) => {
|
|
|
|
|
+ this.recordedForm.status = 0;
|
|
|
|
|
+ this.controlsStatus = 2;
|
|
|
|
|
+ this.showGetTextLoading = false;
|
|
|
|
|
+ this.$message.success("已结束录音");
|
|
|
|
|
+ console.log("结束录音👇");
|
|
|
|
|
+ console.log("结束录音", e);
|
|
|
|
|
+ this.recordedForm.audioBlob.push(e.preaudio);
|
|
|
|
|
+ let blob = new Blob(this.recordedForm.audioBlob, {
|
|
|
|
|
+ type: "audio/wav"
|
|
|
|
|
+ });
|
|
|
|
|
+ let file = new File([blob], "recordedFile.wav", {
|
|
|
|
|
+ type: "audio/wav"
|
|
|
|
|
+ });
|
|
|
|
|
+ // 存储文件和文本到全局对象
|
|
|
|
|
+ this.storeRecordingData(file);
|
|
|
|
|
+ iiframe.contentWindow.onSessionStopped = null;
|
|
|
|
|
+ iiframe.contentWindow.window.onRecognizedResult = null;
|
|
|
|
|
+ };
|
|
|
|
|
+ } else if (this.recordedForm.status == 2) {
|
|
|
|
|
+ //暂停录音时
|
|
|
|
|
+ this.recordedForm.status = 0;
|
|
|
|
|
+ this.controlsStatus = 2;
|
|
|
|
|
+ this.showGetTextLoading = false;
|
|
|
|
|
+ let blob = new Blob(this.recordedForm.audioBlob, {
|
|
|
|
|
+ type: "audio/wav"
|
|
|
|
|
+ });
|
|
|
|
|
+ let file = new File([blob], "recordedFile.wav", { type: "audio/wav" });
|
|
|
|
|
+ // 存储文件和文本到全局对象
|
|
|
|
|
+ this.storeRecordingData(file);
|
|
|
|
|
+ }
|
|
|
|
|
+ },
|
|
|
|
|
+ storeRecordingData(file) {
|
|
|
|
|
+ // 配置全局 window 对象存储录音数据
|
|
|
|
|
+ if (!window.recordingData) {
|
|
|
|
|
+ window.recordingData = {};
|
|
|
|
|
+ }
|
|
|
|
|
+ window.recordingData.file = file;
|
|
|
|
|
+ window.recordingData.text = this.transcriptionData.content;
|
|
|
|
|
+ window.recordingData.textList = this.recordedForm.textList;
|
|
|
|
|
+ console.log("录音数据已存储到全局对象:", window.recordingData);
|
|
|
|
|
+ },
|
|
|
|
|
+ updateRecordedTime({ duration }) {
|
|
|
|
|
+ // 格式化录音时间
|
|
|
|
|
+ const minutes = Math.floor(duration / 60);
|
|
|
|
|
+ const seconds = Math.floor(duration % 60);
|
|
|
|
|
+ return `${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}`;
|
|
|
|
|
+ },
|
|
|
|
|
+ onRecordAddLine(item) {
|
|
|
|
|
+ // 添加录音文本行
|
|
|
|
|
+ console.log("添加录音文本行:", item);
|
|
|
|
|
+ // 这里可以根据需要添加更多处理逻辑
|
|
|
|
|
+ },
|
|
|
getCourseDetail() {
|
|
getCourseDetail() {
|
|
|
this.pageLoading = true;
|
|
this.pageLoading = true;
|
|
|
let params = {
|
|
let params = {
|
|
@@ -264,6 +423,15 @@ export default {
|
|
|
console.error(err);
|
|
console.error(err);
|
|
|
});
|
|
});
|
|
|
},
|
|
},
|
|
|
|
|
+ getAIJ(){
|
|
|
|
|
+ this.ajax.get(this.$store.state.api+"getAIJ","").then(res=>{
|
|
|
|
|
+ let a = res.data[4];
|
|
|
|
|
+ console.log(a)
|
|
|
|
|
+ let Array = [];
|
|
|
|
|
+ a.forEach(i=>Array.push(i.oid))
|
|
|
|
|
+ this.jArray = Array;
|
|
|
|
|
+ })
|
|
|
|
|
+ },
|
|
|
},
|
|
},
|
|
|
destroyed() {
|
|
destroyed() {
|
|
|
clearInterval(this.opertimer);
|
|
clearInterval(this.opertimer);
|
|
@@ -292,6 +460,7 @@ export default {
|
|
|
timeZone: "Asia/Shanghai"
|
|
timeZone: "Asia/Shanghai"
|
|
|
}).replace(/\//g, "-")
|
|
}).replace(/\//g, "-")
|
|
|
this.getClassName()
|
|
this.getClassName()
|
|
|
|
|
+ this.getAIJ();
|
|
|
this.getCourseDetail();
|
|
this.getCourseDetail();
|
|
|
this.setOperationTime();
|
|
this.setOperationTime();
|
|
|
window.onFreeBrowseChange = (value) => {
|
|
window.onFreeBrowseChange = (value) => {
|
|
@@ -415,6 +584,24 @@ export default {
|
|
|
border-color: #0061ff;
|
|
border-color: #0061ff;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+.pec_h_r_btnArea>.pec_h_r_btn_refresh.recording {
|
|
|
|
|
+ background-color: #F53F3F;
|
|
|
|
|
+ border-color: #F53F3F;
|
|
|
|
|
+ animation: pulse 1.5s infinite;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+@keyframes pulse {
|
|
|
|
|
+ 0% {
|
|
|
|
|
+ box-shadow: 0 0 0 0 rgba(245, 63, 63, 0.4);
|
|
|
|
|
+ }
|
|
|
|
|
+ 70% {
|
|
|
|
|
+ box-shadow: 0 0 0 10px rgba(245, 63, 63, 0);
|
|
|
|
|
+ }
|
|
|
|
|
+ 100% {
|
|
|
|
|
+ box-shadow: 0 0 0 0 rgba(245, 63, 63, 0);
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
.pec_h_r_btnArea>.pec_h_r_btn_afterClass {
|
|
.pec_h_r_btnArea>.pec_h_r_btn_afterClass {
|
|
|
border-color: #F0E1DD;
|
|
border-color: #F0E1DD;
|
|
|
background-color: #FFF7F5;
|
|
background-color: #FFF7F5;
|