qgt 1 month ago
parent
commit
15715c9ef0

+ 1 - 1
dist/index.html

@@ -32,7 +32,7 @@
       width: 100%;
       background: #e6eaf0;
       font-family: '黑体';
-    }</style><link href=./static/css/app.69fc29f3fdc3eb01d41b01d8f4bfc7fc.css rel=stylesheet></head><body><div id=app></div><script type=text/javascript src=./static/js/manifest.23ea04dc469b57e2b4f8.js></script><script type=text/javascript src=./static/js/vendor.dfc8a8e3392292c7b8e5.js></script><script type=text/javascript src=./static/js/app.8f84b0b687bca50a7b90.js></script></body></html><script>function stopSafari() {
+    }</style><link href=./static/css/app.d20d59ebd2d033eec209ecb5a7031fb2.css rel=stylesheet></head><body><div id=app></div><script type=text/javascript src=./static/js/manifest.13ce8e475898fba4b86d.js></script><script type=text/javascript src=./static/js/vendor.715d92365c85ab803f65.js></script><script type=text/javascript src=./static/js/app.30eebf9fec06c84113c8.js></script></body></html><script>function stopSafari() {
     //阻止safari浏览器双击放大功能
     let lastTouchEnd = 0  //更新手指弹起的时间
     document.documentElement.addEventListener("touchstart", function (event) {

File diff suppressed because it is too large
+ 0 - 0
dist/static/css/app.d20d59ebd2d033eec209ecb5a7031fb2.css


File diff suppressed because it is too large
+ 0 - 0
dist/static/css/app.d20d59ebd2d033eec209ecb5a7031fb2.css.map


File diff suppressed because it is too large
+ 0 - 0
dist/static/js/0.9f2408d57b212f100e92.js


File diff suppressed because it is too large
+ 0 - 0
dist/static/js/0.9f2408d57b212f100e92.js.map


File diff suppressed because it is too large
+ 0 - 0
dist/static/js/0.eb6bdee5e7207bfd76b0.js.map


File diff suppressed because it is too large
+ 0 - 0
dist/static/js/app.30eebf9fec06c84113c8.js


File diff suppressed because it is too large
+ 0 - 0
dist/static/js/app.30eebf9fec06c84113c8.js.map


+ 2 - 2
dist/static/js/manifest.23ea04dc469b57e2b4f8.js → dist/static/js/manifest.13ce8e475898fba4b86d.js

@@ -1,2 +1,2 @@
-!function(e){var n=window.webpackJsonp;window.webpackJsonp=function(r,c,a){for(var i,u,f,s=0,l=[];s<r.length;s++)u=r[s],t[u]&&l.push(t[u][0]),t[u]=0;for(i in c)Object.prototype.hasOwnProperty.call(c,i)&&(e[i]=c[i]);for(n&&n(r,c,a);l.length;)l.shift()();if(a)for(s=0;s<a.length;s++)f=o(o.s=a[s]);return f};var r={},t={8:0};function o(n){if(r[n])return r[n].exports;var t=r[n]={i:n,l:!1,exports:{}};return e[n].call(t.exports,t,t.exports,o),t.l=!0,t.exports}o.e=function(e){var n=t[e];if(0===n)return new Promise(function(e){e()});if(n)return n[2];var r=new Promise(function(r,o){n=t[e]=[r,o]});n[2]=r;var c=document.getElementsByTagName("head")[0],a=document.createElement("script");a.type="text/javascript",a.charset="utf-8",a.async=!0,a.timeout=12e4,o.nc&&a.setAttribute("nonce",o.nc),a.src=o.p+"static/js/"+e+"."+{0:"eb6bdee5e7207bfd76b0",1:"14e8e8c7e44fc858e4a6",2:"94e1427bfc7ef0b4c685",3:"3a9f53a78da16650e6b8"}[e]+".js";var i=setTimeout(u,12e4);function u(){a.onerror=a.onload=null,clearTimeout(i);var n=t[e];0!==n&&(n&&n[1](new Error("Loading chunk "+e+" failed.")),t[e]=void 0)}return a.onerror=a.onload=u,c.appendChild(a),r},o.m=e,o.c=r,o.d=function(e,n,r){o.o(e,n)||Object.defineProperty(e,n,{configurable:!1,enumerable:!0,get:r})},o.n=function(e){var n=e&&e.__esModule?function(){return e.default}:function(){return e};return o.d(n,"a",n),n},o.o=function(e,n){return Object.prototype.hasOwnProperty.call(e,n)},o.p="./",o.oe=function(e){throw console.error(e),e}}([]);
-//# sourceMappingURL=manifest.23ea04dc469b57e2b4f8.js.map
+!function(e){var n=window.webpackJsonp;window.webpackJsonp=function(r,c,a){for(var i,u,f,s=0,l=[];s<r.length;s++)u=r[s],t[u]&&l.push(t[u][0]),t[u]=0;for(i in c)Object.prototype.hasOwnProperty.call(c,i)&&(e[i]=c[i]);for(n&&n(r,c,a);l.length;)l.shift()();if(a)for(s=0;s<a.length;s++)f=o(o.s=a[s]);return f};var r={},t={8:0};function o(n){if(r[n])return r[n].exports;var t=r[n]={i:n,l:!1,exports:{}};return e[n].call(t.exports,t,t.exports,o),t.l=!0,t.exports}o.e=function(e){var n=t[e];if(0===n)return new Promise(function(e){e()});if(n)return n[2];var r=new Promise(function(r,o){n=t[e]=[r,o]});n[2]=r;var c=document.getElementsByTagName("head")[0],a=document.createElement("script");a.type="text/javascript",a.charset="utf-8",a.async=!0,a.timeout=12e4,o.nc&&a.setAttribute("nonce",o.nc),a.src=o.p+"static/js/"+e+"."+{0:"9f2408d57b212f100e92",1:"14e8e8c7e44fc858e4a6",2:"94e1427bfc7ef0b4c685",3:"3a9f53a78da16650e6b8"}[e]+".js";var i=setTimeout(u,12e4);function u(){a.onerror=a.onload=null,clearTimeout(i);var n=t[e];0!==n&&(n&&n[1](new Error("Loading chunk "+e+" failed.")),t[e]=void 0)}return a.onerror=a.onload=u,c.appendChild(a),r},o.m=e,o.c=r,o.d=function(e,n,r){o.o(e,n)||Object.defineProperty(e,n,{configurable:!1,enumerable:!0,get:r})},o.n=function(e){var n=e&&e.__esModule?function(){return e.default}:function(){return e};return o.d(n,"a",n),n},o.o=function(e,n){return Object.prototype.hasOwnProperty.call(e,n)},o.p="./",o.oe=function(e){throw console.error(e),e}}([]);
+//# sourceMappingURL=manifest.13ce8e475898fba4b86d.js.map

File diff suppressed because it is too large
+ 0 - 0
dist/static/js/manifest.13ce8e475898fba4b86d.js.map


File diff suppressed because it is too large
+ 0 - 0
dist/static/js/vendor.715d92365c85ab803f65.js


File diff suppressed because it is too large
+ 0 - 0
dist/static/js/vendor.715d92365c85ab803f65.js.map


File diff suppressed because it is too large
+ 0 - 0
dist/static/js/workPage-manifest.2ece51fa34be51c8610a.js.map


+ 13 - 2
src/components/pages/classroomObservation/components/chatArea.vue

@@ -591,6 +591,7 @@ import addNewTeacherVoiceprintDialog from "./addNewTeacherVoiceprintDialog.vue";
 import * as Sy from "@/lib/shengyang";
 import Recorder from "recorder-core/recorder.mp3.min";
 import { fetchEventSource } from "@microsoft/fetch-event-source";
+import {mediaFileToWavFile} from '../tools/tools.js'
 // import { saveAs } from "file-saver";
 
 // import Recorder from 'recorder-core/recorder.wav.min'
@@ -845,7 +846,7 @@ export default {
       this.languageShow = !this.languageShow;
     },
     // 上传录音
-    uploadRecording() {
+    async uploadRecording() {
       if (!this.tid) {
         return this.$parent.addNewCourse().then(_ => {
           this.uploadRecording();
@@ -858,7 +859,7 @@ export default {
       // input.accept = "audio/*, .txt, .pdf, .xlsx";
       input.accept = ".m4a,.mp3,.wav,.txt,.pdf,.xlsx,.doc,.docx,.csv";
       input.click();
-      input.onchange = () => {
+      input.onchange = async () => {
         this.uploadFileLoading = true;
         let file = input.files[0];
         if (!/\.(m4a|mp3|wav|txt|pdf|xlsx|doc|docx|csv)$/i.test(file.name)) {
@@ -867,7 +868,17 @@ export default {
             "请上传.mp3,.wav,.txt,.pdf,.xlsx,.doc,.docx,.csv格式的文件"
           );
         }
+
+				// 判断如果是m4a文件
+        if (/\.m4a$/i.test(file.name)) {
+          file = await mediaFileToWavFile(file,{sampleRate:8000}) 
+        }
+
+
+				// return console.log("成熟市场",file)
+
         this.uploadFile(file, { changeText: true, flag: true });
+
         // this.uploadWavFileAndGetText(file);
       };
     },

+ 112 - 0
src/components/pages/classroomObservation/tools/tools.js

@@ -0,0 +1,112 @@
+const mediaFileToWavFile = async (mediaObj, options = {}) => {
+  let _file = null
+  // if (mediaObj.url) {
+  //   let res = await getFile(mediaObj.url)
+  //   if (res.data === 1) {
+  //     console.log('获取媒体文件失败')
+  //     return ''
+  //   }
+  //   _file = new File([res.data], mediaObj.name, { type: mediaObj.type })
+  // } else {
+    _file = mediaObj
+  // }
+
+  // 添加参数配置
+  const { sampleRate = 22050, optimize = false } = options
+  
+  return new Promise((resolve) => {
+    try {
+      const reader = new FileReader();
+      reader.onload = async (e) => {
+        const audioContext = new (window.AudioContext || window.webkitAudioContext)();
+        const buffer = await audioContext.decodeAudioData(e.target.result);
+        
+        let targetBuffer = buffer;
+        
+        // 如果启用优化或指定采样率
+        if (optimize || sampleRate !== buffer.sampleRate) {
+          const targetSampleRate = Math.min(sampleRate, buffer.sampleRate);
+          
+          const offlineAudioContext = new OfflineAudioContext({
+            numberOfChannels: buffer.numberOfChannels,
+            length: Math.floor(buffer.length * targetSampleRate / buffer.sampleRate),
+            sampleRate: targetSampleRate
+          });
+          
+          const source = offlineAudioContext.createBufferSource();
+          source.buffer = buffer;
+          source.connect(offlineAudioContext.destination);
+          source.start();
+          
+          targetBuffer = await offlineAudioContext.startRendering();
+        }
+        
+        const wavBlob = bufferToWav(targetBuffer);
+        const fileName = mediaObj.name ? 
+          mediaObj.name.replace(/\.[^/.]+$/, "") + '.wav' : 
+          'audio.wav';
+        const audioFile = new File([wavBlob], fileName, { type: 'audio/wav' });
+        
+        console.log(`转换成功,采样率: ${targetBuffer.sampleRate}Hz,文件大小: ${(audioFile.size / 1024 / 1024).toFixed(2)}MB`)
+        resolve(audioFile)
+      }
+      reader.readAsArrayBuffer(_file);
+    } catch (error) {
+      console.log('音频提取失败', error)
+      resolve('')
+    }
+  })
+}
+
+function bufferToWav(buffer) {
+  const numChannels = buffer.numberOfChannels;
+  const sampleRate = buffer.sampleRate;
+  const format = 1; // PCM
+  const bitDepth = 16;
+  
+  const bytesPerSample = bitDepth / 8;
+  const blockAlign = numChannels * bytesPerSample;
+  const byteRate = sampleRate * blockAlign;
+  const dataSize = buffer.length * blockAlign;
+  
+  const bufferLength = 44 + dataSize;
+  const arrayBuffer = new ArrayBuffer(bufferLength);
+  const view = new DataView(arrayBuffer);
+  
+  // WAV 头部
+  writeString(view, 0, 'RIFF');
+  view.setUint32(4, bufferLength - 8, true);
+  writeString(view, 8, 'WAVE');
+  writeString(view, 12, 'fmt ');
+  view.setUint32(16, 16, true); // fmt chunk size
+  view.setUint16(20, format, true);
+  view.setUint16(22, numChannels, true);
+  view.setUint32(24, sampleRate, true);
+  view.setUint32(28, byteRate, true);
+  view.setUint16(32, blockAlign, true);
+  view.setUint16(34, bitDepth, true);
+  writeString(view, 36, 'data');
+  view.setUint32(40, dataSize, true);
+  
+  // 写入 PCM 数据
+  let offset = 44;
+  for (let i = 0; i < buffer.length; i++) {
+    for (let channel = 0; channel < numChannels; channel++) {
+      const sample = Math.max(-1, Math.min(1, buffer.getChannelData(channel)[i]));
+      view.setInt16(offset, sample < 0 ? sample * 0x8000 : sample * 0x7FFF, true);
+      offset += 2;
+    }
+  }
+  
+  return new Blob([arrayBuffer], { type: 'audio/wav' });
+}
+
+function writeString(view, offset, string) {
+  for (let i = 0; i < string.length; i++) {
+    view.setUint8(offset + i, string.charCodeAt(i));
+  }
+}
+
+export {
+	mediaFileToWavFile
+}

Some files were not shown because too many files changed in this diff