Quellcode durchsuchen

feat: tts wav to mp3

zhangjie vor 4 Monaten
Ursprung
Commit
b1ee9f56b1

+ 1 - 0
package.json

@@ -14,6 +14,7 @@
     "test:unit": "vue-cli-service test:unit"
   },
   "dependencies": {
+    "@breezystack/lamejs": "^1.2.7",
     "axios": "^0.21.1",
     "axios-progress-bar": "^1.2.0",
     "bootstrap": "^4.6.0",

+ 3 - 2
src/components/vEditor/components/VMenu.vue

@@ -152,8 +152,9 @@ export default {
 
   methods: {
     async voiceConfirm(blob) {
-      const file = new File([blob], `${new Date().getTime()}.wav`, {
-        type: "audio/wav",
+      const audioType = blob.type.split("/").pop();
+      const file = new File([blob], `${new Date().getTime()}.${audioType}`, {
+        type: blob.type,
       });
       // console.log("file", file);
       let result = true;

+ 36 - 4
src/plugins/tts/audioPlayer.esm.js

@@ -1,3 +1,5 @@
+import * as lamejs from "@breezystack/lamejs";
+
 function t(t, a, i) {
   for (var o = 0; o < i.length; o++) t.setUint8(a + o, i.charCodeAt(o));
 }
@@ -186,10 +188,40 @@ var i = (function () {
     (t.prototype.getAudioDataBlob = function (t) {
       // console.log("processor.getAudioDataBlob");
       var i, o;
-      if (null === (i = this.pcmAudioDatas) || void 0 === i ? void 0 : i.length)
-        return "wav" === t
-          ? a(this.pcmAudioDatas, this.fromSampleRate, 16)
-          : ((o = this.pcmAudioDatas), new Blob(o, { type: "audio/pcm" }));
+      if (
+        null === (i = this.pcmAudioDatas) || void 0 === i ? void 0 : i.length
+      ) {
+        if ("wav" === t) {
+          return a(this.pcmAudioDatas, this.fromSampleRate, 16);
+        } else if ("mp3" === t) {
+          return this.convertWavToMp3(this.pcmAudioDatas, this.fromSampleRate);
+        } else {
+          return (o = this.pcmAudioDatas), new Blob(o, { type: "audio/pcm" });
+        }
+      }
+    }),
+    (t.prototype.convertWavToMp3 = function (pcmData, sampleRate) {
+      var mp3Encoder = new lamejs.Mp3Encoder(1, sampleRate, 128);
+      var mp3Data = [];
+      var sampleBlockSize = 1152;
+
+      for (let p = 0; p < pcmData.length; p++) {
+        const samples = pcmData[p];
+
+        for (var i = 0; i < samples.length; i += sampleBlockSize) {
+          var sampleChunk = samples.subarray(i, i + sampleBlockSize);
+          var mp3buf = mp3Encoder.encodeBuffer(sampleChunk);
+          if (mp3buf.length > 0) {
+            mp3Data.push(new Int8Array(mp3buf));
+          }
+        }
+      }
+
+      var mp3buf = mp3Encoder.flush();
+      if (mp3buf.length > 0) {
+        mp3Data.push(new Int8Array(mp3buf));
+      }
+      return new Blob(mp3Data, { type: "audio/mp3" });
     }),
     t
   );

+ 3 - 3
src/plugins/tts/index.js

@@ -66,7 +66,7 @@ export default class TtsVoice {
   }
 
   getBlob() {
-    return this.audioPlayer.getAudioDataBlob("wav");
+    return this.audioPlayer.getAudioDataBlob("mp3");
   }
 
   encodeText(text, type) {
@@ -195,14 +195,14 @@ export default class TtsVoice {
   }
 
   download() {
-    const blob = this.audioPlayer.getAudioDataBlob("wav");
+    const blob = this.audioPlayer.getAudioDataBlob("mp3");
     if (!blob) {
       return;
     }
     let defaultName = new Date().getTime();
     let node = document.createElement("a");
     node.href = window.URL.createObjectURL(blob);
-    node.download = `${defaultName}.wav`;
+    node.download = `${defaultName}.mp3`;
     node.click();
     node.remove();
   }

+ 5 - 0
yarn.lock

@@ -1046,6 +1046,11 @@
     "@babel/helper-validator-identifier" "^7.22.20"
     to-fast-properties "^2.0.0"
 
+"@breezystack/lamejs@^1.2.7":
+  version "1.2.7"
+  resolved "https://registry.npmmirror.com/@breezystack/lamejs/-/lamejs-1.2.7.tgz#c4779f7f0b6b685da675ebbaaff85e52187a51ad"
+  integrity sha512-6wc7ck65ctA75Hq7FYHTtTvGnYs6msgdxiSUICQ+A01nVOWg6rqouZB8IdyteRlfpYYiFovkf67dIeOgWIUzTA==
+
 "@discoveryjs/json-ext@0.5.7":
   version "0.5.7"
   resolved "https://registry.npmmirror.com/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz#1d572bfbbe14b7704e0ba0f39b74815b84870d70"