lsc 2 роки тому
батько
коміт
4798d53bc2
2 змінених файлів з 180 додано та 14 видалено
  1. 6 6
      src/components/audioDemo.vue
  2. 174 8
      src/components/liveProjectDetail.vue

+ 6 - 6
src/components/audioDemo.vue

@@ -61,12 +61,12 @@ const recorder = new Recorder({
 // 绑定事件-打印的是当前录音数据
 
 recorder.onprogress = function (params) {
-  // console.log('--------------START---------------')
-  // console.log('录音时长(秒)', params.duration);
-  // console.log('录音大小(字节)', params.fileSize);
-  // console.log('录音音量百分比(%)', params.vol);
-  // console.log('当前录音的总数据([DataView, DataView...])', params.data);
-  // console.log('--------------END---------------')
+  console.log('--------------START---------------')
+  console.log('录音时长(秒)', params.duration);
+  console.log('录音大小(字节)', params.fileSize);
+  console.log('录音音量百分比(%)', params.vol);
+  console.log('当前录音的总数据([DataView, DataView...])', params.data);
+  console.log('--------------END---------------')
 };
 
 export default {

+ 174 - 8
src/components/liveProjectDetail.vue

@@ -668,6 +668,40 @@
               </div>-->
             </div>
           </div>
+          <div
+            class="answerBox"
+            :class="{ fullStyle: full }"
+            v-if="isBlock == 10"
+          >
+            <div style="height: 70%; width: 100%">
+              <div class="wheel">
+                <div style="height: 100%">
+                  <el-button type="primary" @click="startRecorder()">{{
+                    !isRecord ? "开始录音" : "结束录音"
+                  }}</el-button>
+                  <el-button type="primary" @click="playRecorder()">{{
+                    !isPlayerRecord ? "录音播放" : "停止播放"
+                  }}</el-button>
+                  <el-button type="primary" @click="getMp3Data()"
+                    >上传录音</el-button
+                  >
+
+                  <div
+                    style="margin: 10px auto 0; display: flex;align-items: center;"
+                    v-if="LuAudioUrl"
+                  >
+                    <span>已上传录音:</span>
+                    <audio :src="LuAudioUrl" controls="controls" ref="audio">
+                      Your browser does not support the audio element.
+                    </audio>
+                  </div>
+                </div>
+              </div>
+              <!-- <div class="nextStepBox" style="margin-top: 5%">
+                <div class="nextStepOne" @click="isBlock = 0">关闭</div>
+              </div>-->
+            </div>
+          </div>
         </div>
       </div>
     </div>
@@ -776,6 +810,27 @@
 <script>
 import pdf from "./components/pdf";
 import html2canvas from "html2canvas";
+
+import Recorder from "js-audio-recorder";
+const lamejs = require("lamejs");
+
+const recorder = new Recorder({
+  sampleBits: 16, // 采样位数,支持 8 或 16,默认是16
+  sampleRate: 48000, // 采样率,支持 11025、16000、22050、24000、44100、48000,根据浏览器默认值,我的chrome是48000
+  numChannels: 1, // 声道,支持 1 或 2, 默认是1
+  // compiling: false,(0.x版本中生效,1.x增加中) // 是否边录边转换,默认是false
+});
+
+// 绑定事件-打印的是当前录音数据
+recorder.onprogress = function (params) {
+  // console.log('--------------START---------------')
+  // console.log('录音时长(秒)', params.duration);
+  // console.log('录音大小(字节)', params.fileSize);
+  // console.log('录音音量百分比(%)', params.vol);
+  // console.log('当前录音的总数据([DataView, DataView...])', params.data);
+  // console.log('--------------END---------------')
+};
+
 export default {
   components: {
     pdf,
@@ -824,7 +879,7 @@ export default {
       typeC: [],
       toolCount: 0,
       tools: [
-        "",
+        { tools: [30] },
         //  {
         //   file: [
         //     {
@@ -937,9 +992,104 @@ export default {
       videoBlock: 0,
       Vwidth: 0,
       tiankongAnswer: [],
+      LuAudioUrl: "",
+      isRecord: false,
+      isPlayerRecord: false,
     };
   },
   methods: {
+    // 开始录音
+    startRecorder() {
+      let _this = this;
+      if (!_this.isRecord) {
+        recorder.destroy(); // 销毁录音
+        _this.isRecord = true;
+        recorder.start().then(
+          () => {},
+          (error) => {
+            _this.$message.error(`${error.name} : ${error.message}`);
+            // 出错了
+            console.log(`${error.name} : ${error.message}`);
+          }
+        );
+      } else {
+        _this.isRecord = false;
+        recorder.stop(); // 结束录音
+      }
+    },
+
+    // 录音播放
+    playRecorder() {
+      if (!recorder.fileSize) {
+        return;
+      }
+      if (!this.isPlayerRecord) {
+        this.isPlayerRecord = true;
+        recorder.play();
+      } else {
+        this.isPlayerRecord = false;
+        recorder.stopPlay(); // 停止录音播放
+      }
+      recorder.onplayend = () => {
+        this.isPlayerRecord = false;
+        console.log("onplayend");
+      };
+    },
+
+    /**
+     * 文件格式转换 wav-map3
+     * */
+    getMp3Data() {
+      if (!recorder.fileSize) {
+        this.$message.error("请录音后在上传语音");
+        return;
+      }
+      const mp3Blob = this.convertToMp3(recorder.getWAV());
+      let audioFile = this.dataURLtoAudio(mp3Blob, "音频");
+      console.log(audioFile);
+      this.beforeUpload1(audioFile, 3);
+      // recorder.download(mp3Blob, "recorder", "mp3");
+    },
+    convertToMp3(wavDataView) {
+      // 获取wav头信息
+      const wav = lamejs.WavHeader.readHeader(wavDataView); // 此处其实可以不用去读wav头信息,毕竟有对应的config配置
+      const { channels, sampleRate } = wav;
+      const mp3enc = new lamejs.Mp3Encoder(channels, sampleRate, 128);
+      // 获取左右通道数据
+      const result = recorder.getChannelData();
+      const buffer = [];
+      const leftData =
+        result.left &&
+        new Int16Array(result.left.buffer, 0, result.left.byteLength / 2);
+      const rightData =
+        result.right &&
+        new Int16Array(result.right.buffer, 0, result.right.byteLength / 2);
+      const remaining = leftData.length + (rightData ? rightData.length : 0);
+      const maxSamples = 1152;
+      for (let i = 0; i < remaining; i += maxSamples) {
+        const left = leftData.subarray(i, i + maxSamples);
+        let right = null;
+        let mp3buf = null;
+        if (channels === 2) {
+          right = rightData.subarray(i, i + maxSamples);
+          mp3buf = mp3enc.encodeBuffer(left, right);
+        } else {
+          mp3buf = mp3enc.encodeBuffer(left);
+        }
+        if (mp3buf.length > 0) {
+          buffer.push(mp3buf);
+        }
+      }
+
+      const enc = mp3enc.flush();
+      if (enc.length > 0) {
+        buffer.push(enc);
+      }
+      return new Blob(buffer, { type: "audio/mp3" });
+    },
+    dataURLtoAudio(blob, filename) {
+      return new File([blob], filename, { type: "audio/mp3" });
+    },
     change(val) {
       console.log(val);
     },
@@ -1051,7 +1201,12 @@ export default {
       this.noneBtnImg = _tmp.length >= 1;
     },
     beforeUpload1(event, type) {
-      var file = event.target.files[0];
+      var file;
+      if (type == 3) {
+        file = event;
+      } else {
+        file = event.target.files[0];
+      }
       var credentials = {
         accessKeyId: "AKIATLPEDU37QV5CHLMH",
         secretAccessKey: "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",
@@ -1107,6 +1262,9 @@ export default {
                 _this.upload[0].url = data.Location;
                 _this.imgChange(null, null, type);
                 _this.addWork(7);
+              } else if (type == 3) {
+                _this.LuAudioUrl = data.Location;
+                _this.addWork(8);
               }
               console.log(data.Location);
             }
@@ -1235,6 +1393,8 @@ export default {
         a = JSON.stringify(this.typeC);
       } else if (type == 5) {
         a = JSON.stringify(this.tkAnswer);
+      } else {
+        a = this.LuAudioUrl;
       }
       let params = {
         uid: this.userid,
@@ -1282,6 +1442,8 @@ export default {
           _type = 6;
         } else if (this.tools[this.ppage - 1].tools.indexOf(29) != -1) {
           _type = 7;
+        } else if (this.tools[this.ppage - 1].tools.indexOf(30) != -1) {
+          _type = 8;
         }
       }
       this.isAnswer = false;
@@ -1308,6 +1470,9 @@ export default {
             } else if (res.data[0][0].type == 6) {
               this.isNoHomeWork = true;
               this.rateList = JSON.parse(res.data[0][0].upload);
+            } else if (res.data[0][0].type == 8) {
+              this.isNoHomeWork = true;
+              this.LuAudioUrl = res.data[0][0].upload;
             }
           }
         })
@@ -1482,11 +1647,7 @@ export default {
         this.full = false;
         this.howTools = 0;
         this.toolCount = 0;
-        if (
-          this.tools[page - 1].tools &&
-          (this.tools[page - 1].tools[0] == 14 ||
-            this.tools[page - 1].tools[0] == 12)
-        ) {
+        if (this.tools[page - 1].tools && this.tools[page - 1].tools[0] == 12) {
           this.isBlock = 0;
         }
         if (
@@ -1538,6 +1699,10 @@ export default {
           this.isBlock = 8;
         }
 
+        if (this.tools[page - 1].tools && this.tools[page - 1].tools[0] == 30) {
+          this.isBlock = 10;
+        }
+
         if (
           this.tools[this.ppage - 1].file &&
           this.tools[this.ppage - 1].file.length
@@ -1583,7 +1748,8 @@ export default {
             if (this.ppage == res.data[0][0].page && this.isBlock !== 0) {
               return;
             } else {
-              this.ppage = res.data[0][0].page;
+              // this.ppage = res.data[0][0].page;
+              this.ppage = 1;
               // this.ppage = 11;
               this.typeC = [];
               this.isAnswer = false;