|
@@ -38,9 +38,7 @@
|
|
|
</div>
|
|
|
</template>
|
|
|
</el-input>
|
|
|
- <div class="hc-icon-mic" @click="transcribeClick">
|
|
|
- <HcIcon name="mic" :fill="isMicShow"/>
|
|
|
- </div>
|
|
|
+ <HcMediaMic class="hc-query-mic" :loading="tableLoading" @change="mediaMicChange"/>
|
|
|
</div>
|
|
|
|
|
|
<div class="hc-query-filtering-collapse-box">
|
|
@@ -56,7 +54,7 @@
|
|
|
<div class="screening-key" :class="isArrIndex(classes,'key', item.key) ? 'cut': ''" @click="classesClick(item)">{{item.name}}</div>
|
|
|
</template>
|
|
|
</div>
|
|
|
- <div class="hc-search-screening-item mb-4">
|
|
|
+ <div class="hc-search-screening-item">
|
|
|
<div class="title">目录:</div>
|
|
|
<!-- <div class="screening-key text-link" @click="nodeTreeClick">
|
|
|
<HcIcon name="node-tree" :line="false"/>
|
|
@@ -87,13 +85,12 @@
|
|
|
<div class="screening-key" :class="isArrIndex(deadline,'key', item.key) ? 'cut': ''" @click="deadlineClick(item)">{{item.name}}</div>
|
|
|
</template>
|
|
|
</div>
|
|
|
- <div class="hc-search-screening-item">
|
|
|
+ <div class="hc-search-screening-item mb-4">
|
|
|
<div class="title">密级:</div>
|
|
|
<template v-for="item in securitys">
|
|
|
<div class="screening-key" :class="isArrIndex(security,'key', item.key) ? 'cut': ''" @click="securityClick(item)">{{item.name}}</div>
|
|
|
</template>
|
|
|
</div>
|
|
|
-
|
|
|
</el-collapse-item>
|
|
|
</el-collapse>
|
|
|
</div>
|
|
@@ -395,29 +392,6 @@
|
|
|
</el-collapse>
|
|
|
<HcNoData v-if="nodeTreeArr.length==0"/>
|
|
|
</HcDialog>
|
|
|
-
|
|
|
- <!--语音识别-->
|
|
|
- <HcDialog ui="hc-media-recorder-dialog"
|
|
|
- bgColor="#fff"
|
|
|
- title="语音识别搜索"
|
|
|
- :show="isMicShow"
|
|
|
- widths="360px"
|
|
|
- saveText="确认"
|
|
|
- @close="transcribeClick"
|
|
|
- >
|
|
|
- <div class="hc-media-recorder-box" @click="transcribeClick">
|
|
|
- <img :src="imageViewMic" alt="">
|
|
|
- <div class="content-box">
|
|
|
- <div class="shut-down-icon">
|
|
|
- <HcIcon name="shut-down"/>
|
|
|
- </div>
|
|
|
- <div class="time-box">
|
|
|
- <span class="time">{{micTime}}</span>
|
|
|
- <span> / 01:00</span>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- </HcDialog>
|
|
|
</div>
|
|
|
</template>
|
|
|
|
|
@@ -425,13 +399,14 @@
|
|
|
import {ref, nextTick, onMounted, watch} from "vue";
|
|
|
import {useAppStore} from "~src/store";
|
|
|
import MetaTable from "../transfer/components/meta-table.vue"
|
|
|
-import {getArrValue, arrIndex, isArrIndex, isString, getObjValue} from "js-fast-way"
|
|
|
+import HcMediaMic from "./components/media-mic/index.vue"
|
|
|
+import {getArrValue, arrIndex, isArrIndex, getObjValue} from "js-fast-way"
|
|
|
import archiveQueryApi from "~api/using/query.js";
|
|
|
import tuningApi from "~api/archiveConfig/tuning.js";
|
|
|
import imageViewGui from "~src/assets/view/gui.png";
|
|
|
import imageViewGui1 from "~src/assets/view/gui1.png";
|
|
|
import imageViewGui2 from "~src/assets/view/gui2.png";
|
|
|
-import imageViewMic from "~src/assets/view/mic.gif";
|
|
|
+
|
|
|
|
|
|
//变量
|
|
|
const useAppState = useAppStore()
|
|
@@ -1505,142 +1480,15 @@ const getmetaInfo=async(fileId)=>{
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-//语音
|
|
|
-const isMicShow = ref(false)
|
|
|
-const mediaRecorderRef = ref(null)
|
|
|
-const micTime = ref('00:00')
|
|
|
-const micTimeRef = ref(null)
|
|
|
-const transcribeClick = async () => {
|
|
|
- if (isMicShow.value) { //停止录音
|
|
|
- mediaRecorderRef.value?.stop()
|
|
|
- mediaRecorderRef.value = null
|
|
|
- isMicShow.value = false
|
|
|
- clearTimeout(micTimeRef.value);
|
|
|
- micTimeRef.value = null
|
|
|
- micTime.value = '00:00'
|
|
|
- } else {
|
|
|
- const stream = await getUserMedia()
|
|
|
- if (stream === false) return false;
|
|
|
- isMicShow.value = true
|
|
|
- startRecorder(stream)
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-//开始录音
|
|
|
-const startRecorder = (stream) => {
|
|
|
- //设置采样率
|
|
|
- const audioContext = new AudioContext({ sampleRate: 16000 });
|
|
|
- const mediaStreamAudioSourceNode = new MediaStreamAudioSourceNode(audioContext, { mediaStream: stream });
|
|
|
- const mediaStreamAudioDestinationNode = new MediaStreamAudioDestinationNode(audioContext);
|
|
|
- mediaStreamAudioSourceNode.connect(mediaStreamAudioDestinationNode);
|
|
|
- //测试
|
|
|
- let mediaRecorder = new MediaRecorder(mediaStreamAudioDestinationNode.stream), chunks;
|
|
|
- mediaRecorderRef.value = mediaRecorder
|
|
|
- //开始录音
|
|
|
- mediaRecorder.start();
|
|
|
- setMicTimeFormat() //开始计时
|
|
|
- // 录音结束时,停止并下载录音文件
|
|
|
- mediaRecorder.addEventListener("dataavailable", (e) => {
|
|
|
- clearTimeout(micTimeRef.value);
|
|
|
- micTimeRef.value = null
|
|
|
- chunks = e.data;
|
|
|
- });
|
|
|
- // 录音结束
|
|
|
- mediaRecorder.addEventListener("stop", () => {
|
|
|
- //获取wav格式音频数据
|
|
|
- let blob = new Blob([chunks], {type: "audio/wav"});
|
|
|
- let file = new window.File([blob],new Date().getTime() + ".wav", {type: "audio/wav"});
|
|
|
- //下载文件到本地
|
|
|
- testDownload(blob)
|
|
|
- //准备上传
|
|
|
- const formData = new FormData()
|
|
|
- formData.append('file', file)
|
|
|
- transcribeApi(formData)
|
|
|
- });
|
|
|
-}
|
|
|
-
|
|
|
-const testDownload = (blob) => {
|
|
|
- // 创建一个blob的对象,把Json转化为字符串作为我们的值
|
|
|
- let url = window.URL.createObjectURL(blob);
|
|
|
- // 上面这个是创建一个blob的对象连链接,
|
|
|
- // 然后创建一个链接元素,是属于 a 标签的链接元素,所以括号里才是a,
|
|
|
- let link = document.createElement("a");
|
|
|
- link.href = url;
|
|
|
- // 把上面获得的blob的对象链接赋值给新创建的这个 a 链接
|
|
|
- link.setAttribute("download", "录音.wav");
|
|
|
- // 设置下载的属性(所以使用的是download),这个是a 标签的一个属性
|
|
|
- // 后面的是文件名字,可以更改
|
|
|
- link.click();
|
|
|
-}
|
|
|
-
|
|
|
-//发起请求
|
|
|
-const transcribeApi = async (formData) => {
|
|
|
- const { error, code, data } = await archiveQueryApi.micSearchInfo(formData)
|
|
|
- console.log(data)
|
|
|
- if (!error && code === 200) {
|
|
|
- const res = getObjValue(data)
|
|
|
- searchInput.value = res.queryValue
|
|
|
- searchForm.value.searchType = 1
|
|
|
- searchForm.value.current = 1
|
|
|
- Object.keys(res).forEach(key => {
|
|
|
- searchForm.value[key] = res[key]
|
|
|
- })
|
|
|
- getTableData().then()
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-//获取录音权限
|
|
|
-const getUserMedia = () => {
|
|
|
- return new Promise((resolve) => {
|
|
|
- // 老的浏览器可能根本没有实现 mediaDevices,所以我们可以先设置一个空的对象
|
|
|
- if (navigator.mediaDevices === undefined) {
|
|
|
- navigator.mediaDevices = {};
|
|
|
- }
|
|
|
- // 一些浏览器部分支持 mediaDevices。我们不能直接给对象设置 getUserMedia
|
|
|
- // 因为这样可能会覆盖已有的属性。这里我们只会在没有 getUserMedia 属性的时候添加它。
|
|
|
- if (navigator.mediaDevices.getUserMedia === undefined) {
|
|
|
- navigator.mediaDevices.getUserMedia = function(constraints) {
|
|
|
- // 首先,如果有 getUserMedia 的话,就获得它
|
|
|
- let getUserMedia = navigator.webkitGetUserMedia || navigator.mozGetUserMedia;
|
|
|
- // 一些浏览器根本没实现它 - 那么就返回一个 error 到 promise 的 reject 来保持一个统一的接口
|
|
|
- if (!getUserMedia) {
|
|
|
- window?.$message.error('当前浏览器不支持语音功能')
|
|
|
- resolve(false)
|
|
|
- }
|
|
|
- // 否则,为老的 navigator.getUserMedia 方法包裹一个 Promise
|
|
|
- return new Promise(function(resolve, reject) {
|
|
|
- getUserMedia.call(navigator, constraints, resolve, reject);
|
|
|
- });
|
|
|
- }
|
|
|
- }
|
|
|
- navigator.mediaDevices.getUserMedia({
|
|
|
- audio: true
|
|
|
- }).then(stream => {
|
|
|
- resolve(stream)
|
|
|
- }).catch(err => {
|
|
|
- console.log(err)
|
|
|
- window?.$message.error('获取麦克风权限失败了')
|
|
|
- resolve(false)
|
|
|
- });
|
|
|
+//语音搜索
|
|
|
+const mediaMicChange = (data) => {
|
|
|
+ searchInput.value = data.queryValue
|
|
|
+ searchForm.value.searchType = 1
|
|
|
+ searchForm.value.current = 1
|
|
|
+ Object.keys(data).forEach(key => {
|
|
|
+ searchForm.value[key] = data[key]
|
|
|
})
|
|
|
-}
|
|
|
-
|
|
|
-//设置时间格式
|
|
|
-const setMicTimeFormat = () => {
|
|
|
- let startNum = 0
|
|
|
- micTime.value = '00:00'
|
|
|
- micTimeRef.value = setInterval(() => {
|
|
|
- if (startNum < 60) {
|
|
|
- startNum++
|
|
|
- let min = Math.floor(startNum / 60) //分
|
|
|
- let sec = Math.floor(startNum % 60) //秒
|
|
|
- min = min < 10 ? '0' + min : min
|
|
|
- sec = sec < 10 ? '0' + sec : sec
|
|
|
- micTime.value = `${min}:${sec}`
|
|
|
- } else {
|
|
|
- transcribeClick()
|
|
|
- }
|
|
|
- },1000)
|
|
|
+ getTableData()
|
|
|
}
|
|
|
</script>
|
|
|
|
|
@@ -1657,8 +1505,6 @@ const setMicTimeFormat = () => {
|
|
|
position: relative;
|
|
|
width: calc(100% - 40px);
|
|
|
overflow: hidden;
|
|
|
-
|
|
|
-
|
|
|
}
|
|
|
.scrollbar-content {
|
|
|
white-space: nowrap;
|