1. 程式人生 > 程式設計 >vue + node如何通過一個Txt檔案批量生成MP3並壓縮成Zip

vue + node如何通過一個Txt檔案批量生成MP3並壓縮成Zip

看看效果叭

vue + node如何通過一個Txt檔案批量生成MP3並壓縮成Zip

解壓的檔案

vue + node如何通過一個Txt檔案批量生成MP3並壓縮成Zip

上傳的檔案格式

測試1|||測試1的文字
測試2|||測試2的文字
測試3|||測試3的文字
測試4|||測試4的文字
測試5|||測試5的文字

實現的邏輯如下

  • 上傳檔案
  • 解析txt
  • 傳送內容至百度語音合成
  • 生成資料夾放置本次合成的mp3檔案,並壓縮成zip
  • 傳送zip的地址給前端

使用了 element-ui 的 el-upload 元件

<el-upload
  v-loading="loading"
  class="upload-demo"
  drag
  ref="upload"
  action="#"
  accept=".txt"
  :before-upload="onBeforeUploadImage"
  :http-request="UploadImage"
  :on-change="fileChange"
  :file-list="fileList"
 >
 <i class="el-icon-upload"></i>
 <div class="el-upload__text">
  將檔案拖到此處,或
  <em>點選上傳</em>
 </div>
 <div class="el-upload__tip" slot="tip">只能上傳txt檔案,且不超過1M</div>
</el-upload>

在上傳之前判斷上傳的檔案是否符合要求

onBeforeUploadImage(file) {
 const isTxt = file.type === "text/plain";
 const isLt1M = file.size / 1024 / 1024 < 1;
 if (!isTxt) {
  this.$message.error("上傳檔案只能是txt格式!");
 }
 if (!isLt1M) {
  this.$message.error("上傳檔案大小不能超過 1MB!");
 }
 return isTxt && isLt1M;
}

一次只上傳一個檔案,在檔案列表更新時先清除之前的檔案

fileChange(file) {
  let obj = this.onBeforeUploadImage(file.raw);
  if (obj) {
    this.$refs.upload.clearFiles(); 
    this.fileList = [{ name: file.name,url: file.url }];
  }
}

上傳的主要函式

UploadImage(param) {
  this.loading = true;
  const formData = new FormData();
  formData.append("file",param.file);
  this.$axios({
    url: process.env.VUE_APP_BASE_API + "api/txtToMp3",method: "post",data: formData
  })
  .then(response => {
    if (response.data.code == 0) {
      this.loading = false;
      this.dialogVisible = true;
      this.url = response.data.data.url;
    }
  })
  .catch(error => {
    console.log(error);
  });
}

node程式碼

用到的依賴項

const formidable = require("formidable"); //獲取上傳的txt,並儲存
const path = require("path"); 
const AipSpeech = require("baidu-aip-sdk").speech; //百度語音合成sdk
const fs = require("fs"); 
const compressing = require("compressing"); //壓縮資料夾用

介面程式碼

router.post("/txtToMp3",async function (req,res,next) {
 let form = new formidable.IncomingForm();
 form.encoding = "utf-8"; //編碼
 form.uploadDir = path.join(__dirname + "/../txt"); //儲存上傳檔案地址
 form.keepExtensions = true; //保留後綴

 form.parse(req,function (err,fields,files) {
  let filename;
  filename = files.file.name;

  let nameArray = filename.split("."); //分割
  let type = nameArray[nameArray.length - 1];
  let name = "";
  for (let i = 0; i < nameArray.length - 1; i++) {
   name = name + nameArray[i];
  }
  let date = new Date();
  let time = "_" + date.getTime();
  let avatarName = name + time + "." + type;
  let newPath = form.uploadDir + "/" + avatarName;
  fs.renameSync(files.file.path,newPath); //移動檔案
  fs.readFile(newPath,"utf-8",data) {
   if (err) {
    console.log(err);
    new Result(null,"讀取失敗").fail(res);
   } else {
    let client = new AipSpeech(
     0,"百度語音合成key","百度語音合成secret"
    );

    let resultData = data.split("\n");
    let number = resultData.length;
    let formTime = new Date().getTime();
    let mp3FileDir = path.join(__dirname + "/../mp3_" + formTime);
    fs.mkdirSync(mp3FileDir);
    for (let i in resultData) {
      setTimeout(function(){
        if (resultData[i].indexOf("|||") != -1) {
        let text = resultData[i].split("|||")[1];
        // 語音合成,儲存到本地檔案
        client.text2audio(text,{ spd: 4,per: 4 }).then(
         function (result) {
          if (result.data) {
           let time = resultData[i].split("|||")[0] + "_voice";
           let avatarName_mp3 = mp3FileDir + "/" + time + ".mp3";
           fs.writeFileSync(avatarName_mp3,result.data);
           number--;
           if (number == 0) {
            let zipFileName = "zip/mp3_" + formTime + ".zip";
            compressing.zip
             .compressDir(mp3FileDir,zipFileName)
             .then(() => {
              let item = {
               url: zipFileName,};
              new Result(item,"壓縮成功").success(res);
             })
             .catch((err) => {
              new Result(null,"壓縮失敗").fail(res);
             });
           }
          } else {
           // 合成服務發生錯誤
           new Result(null,"合成失敗").fail(res);
          }
         },function (err) {
          console.log(err);
         }
        );
       } else {
        new Result(null,"檔案格式錯誤").fail(res);
       }  
      },i * 20)
    }
   }
  });
 });
});

PS:

在node部分,在判斷需要合成的檔案是否全部完成時,我是通過number的值等於0判斷完成,不知道大佬們有啥好方法不?

到此這篇關於vue + node如何通過一個Txt檔案批量生成MP3並壓縮成Zip的文章就介紹到這了,更多相關vue node批量生成MP3內容請搜尋我們以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援我們!