vue + node如何通过一个Txt文件批量生成MP3并压缩成Zip


Posted in Javascript onJune 02, 2020

看看效果叭

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", function (err, 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内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Javascript 相关文章推荐
javascript textarea光标定位方法(兼容IE和FF)
Mar 12 Javascript
js常用代码段整理
Nov 30 Javascript
jquery select动态加载选择(兼容各种浏览器)
Feb 01 Javascript
使用Jquery实现点击文字后变成文本框且可修改
Sep 21 Javascript
Node.js中使用jQuery的做法
Aug 17 Javascript
JS沙箱模式实例分析
Sep 04 Javascript
使用原生js封装的ajax实例(兼容jsonp)
Oct 12 Javascript
关于React动态加载路由处理的相关问题
Jan 07 Javascript
微信小程序swiper左右扩展各显示一半代码实例
Dec 05 Javascript
node.js使用mongoose操作数据库实现购物车的增、删、改、查功能示例
Dec 23 Javascript
Vue绑定用户接口实现代码示例
Nov 04 Javascript
解决Vue大括号字符换行踩的坑
Nov 09 Javascript
js简单实现自动生成表格功能示例
Jun 02 #Javascript
JS中准确判断变量类型的方法
Jun 01 #Javascript
Vuex中的Mutations的具体使用方法
Jun 01 #Javascript
vue使用自定义事件的表单输入组件用法详解【日期组件与货币组件】
Jun 01 #Javascript
Bootstrap table 服务器端分页功能实现方法示例
Jun 01 #Javascript
easyUI 实现的后台分页与前台显示功能示例
Jun 01 #Javascript
JS如何寻找数组中心索引过程解析
Jun 01 #Javascript
You might like
php include的妙用,实现路径加密
2008/07/29 PHP
PHP MySQL应用中使用XOR运算加密算法分享
2011/08/28 PHP
PHP生成json和xml类型接口数据格式
2015/05/17 PHP
php用户密码加密算法分析【Discuz加密算法】
2016/10/12 PHP
php str_replace替换指定次数的方法详解
2017/05/05 PHP
ExtJS 2.0实用简明教程 之ExtJS版的Hello
2009/04/29 Javascript
背景图跟随鼠标移动的Mootools插件实现代码
2011/12/12 Javascript
拥抱模块化的JavaScript
2012/03/07 Javascript
33个优秀的 jQuery 图片展示插件分享
2012/03/14 Javascript
js自动生成对象的属性示例代码
2013/10/28 Javascript
js获取指定日期周数以及星期几的小例子
2014/06/27 Javascript
javascript图片预加载实例分析
2015/07/16 Javascript
javascript实现数组中的内容随机输出
2015/08/11 Javascript
JS实现带有3D立体感的银灰色竖排折叠菜单代码
2015/10/20 Javascript
Angular学习笔记之angular的$filter服务浅析
2016/11/12 Javascript
Vue CLI3 如何支持less的方法示例
2018/08/29 Javascript
Vue实现的父组件向子组件传值功能示例
2019/01/19 Javascript
Vue+Element UI+Lumen实现通用表格分页功能
2019/02/02 Javascript
vue router动态路由设置参数可选问题
2019/08/21 Javascript
Python跳出循环语句continue与break的区别
2014/08/25 Python
举例区分Python中的浅复制与深复制
2015/07/02 Python
Python比较2个时间大小的实现方法
2018/04/10 Python
使用pandas对矢量化数据进行替换处理的方法
2018/04/11 Python
详解用pyecharts Geo实现动态数据热力图城市找不到问题解决
2019/06/26 Python
使用PyTorch将文件夹下的图片分为训练集和验证集实例
2020/01/08 Python
使用Python Tkinter实现剪刀石头布小游戏功能
2020/10/23 Python
python 如何对logging日志封装
2020/12/02 Python
HTML5本地存储和本地数据库实例详解
2017/09/05 HTML / CSS
小学生演讲稿
2014/01/12 职场文书
药店主任岗位责任制
2014/02/10 职场文书
内蒙古鄂尔多斯市市长寄语
2014/04/10 职场文书
2016会计专业自荐信范文
2016/01/28 职场文书
小学2016年“我们的节日·重阳节”活动总结
2016/04/01 职场文书
比较几种Redis集群方案
2021/06/21 Redis
MySQL 原理与优化之原数据锁的应用
2022/08/14 MySQL
CSS中理解层叠性及权重如何分配
2022/12/24 HTML / CSS