• vscode语音插件开发-在nodejs里面转换音频文件格式并压缩导出zip格式


    继我的上一篇文章:!vscode录音及语音实时转写插件开发并在工作区生成本地mp3文件 踩坑日记

    音频格式转换这里我使用的是ffmpeg第三方库,官网文档

    ffmpeg简介

    FFmpeg是一个跨平台的自由软件,用于实时音频、视频流以及音频、视频文件的录制、转换。FFmpeg是一套开源的音视频处理工具,通俗地讲,可以对音视频文件进行剪切、拼接、水印、转码等处理。由于其强大的功能和免费开源的特性,目前在全球范围内得到广泛应用。FFmpeg支持多种音视频格式的编码、解码、转换,可以输出各种容器格式。FFmpeg既可以作为命令行工具使用,也可以通过各种语言的API调用,进行二次开发。

    在音视频处理工具方面的方案可能会搜到多种,但是大多的核心都是对FFmpeg进行了包装使用,FFmpeg可以说在音视频处理方面做到了一统江湖。

    这里我使用的是命令工具

    在这里插入图片描述
    下载地址:https://ffmpeg.org/download.html

    mac:
    在这里插入图片描述
    wins:
    在这里插入图片描述
    在这里插入图片描述

    例子

    先上传一个语音文件,并拿到url
    在这里插入图片描述
    如果是mp3文件, 直接导入到本地

    // const fs = require('fs')
    // var readStream = fs.createReadStream('./test.mp3')
    
    // var writeStream = fs.createWriteStream('./data/copied.mp3')
    // readStream.pipe(writeStream)
    
    // 如果是mp3格式 直接上传服务端并且存在本地工作区
    const fileUint8Arr = await vscode.workspace.fs.readFile(url[0]);
    // 保存到本地
    await vscode.workspace.fs.writeFile(vscode.Uri.joinPath(vscode.Uri.file(path.dirname(this.documentUri!.fsPath)!), 'main.mp3'), fileUint8Arr);
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    这里我将.wav文件转为.mp3

    const url = await vscode.window.showOpenDialog({
    	openLabel: '导入语音文件',
    	title: '选择语音文件以导入',
    	canSelectFolders: false,
    	canSelectFiles: true,
    	canSelectMany: false,
    	defaultUri: undefined,
    	filters: {
    		'audio': ['mp3', 'wav', 'wma', 'avi', 'amr', 'aac', 'm4a', 'flac', 'opus']
    	}
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    封装一个转换方法

    import { ChildProcessWithoutNullStreams, spawn } from 'child_process';
    
    private convertToMp3(inputFile: string, outputFile: string, platform: string) {
    		return new Promise((resolve, reject) => {
    			let exeFilePath = '';
    			if ( platform === 'Darwin') {
    				exeFilePath = path.join(__dirname, 'common', 'mac', 'ffmpeg');
    			} else {
    				exeFilePath = path.join(__dirname, 'common', 'win', 'ffmpeg.exe');
    			}
    			// 调用FFmpeg命令
    			var ffmpeg: ChildProcessWithoutNullStreams | null = spawn(exeFilePath, ['-i', inputFile, '-acodec', 'libmp3lame', '-qscale:a', '2', outputFile]);
    			// 监听FFmpeg输出,可以在终端看到转换进度等信息
    			ffmpeg.stdout.on('data', (data) => {
    				console.log(`FFmpeg stdout: ${data}`);
    			});
    
    			// ffmpeg.stderr.on('data', (data) => {
    			// 	console.error(`FFmpeg stderr: ${data}`);
    			// });
    
    			ffmpeg.on('close', (code) => {
    				ffmpeg = null;
    				resolve(true);
    				console.log(`FFmpeg process exited with code ${code}`);
    			});
    		});
    	}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28

    调用

    // 2. 转成mp3文件存本地
    await this.convertToMp3(url[0].fsPath, path.join(path.dirname(this.documentUri!.fsPath), 'main.mp3'), this.platform);
    
    • 1
    • 2

    通过接口上传本地文件

    我这里用了axios, 由于node环境没有formdata,这里也用到一个第三方库form-data

    	const formData = new FormData();
    		//formData.append('file', fs.createReadStream(filePath), 'main.mp3');
    		console.log('开始上传-->')
    		//上传服务器
    		const res = await axios.post(`${baseUrl}/url`, formData, {
    			signal: this.abortController.signal,
    			headers: {
    				'Content-Type': 'multipart/form-data',
    				'token': (global as any).token
    			},
    		});
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    一开始使用的是

    formData.append('file', fs.createReadStream(filePath), 'main.mp3');
    
    • 1

    但是不同机型会报错,通过抓包工具看到服务端接受到的formdata数据错误。

    后来改成了

    formData.append('file', fs.readFileSync(filePath), 'main.mp3');
    
    • 1

    对比下数据正常了,看来官方给的demo 有时候也不可信!

    生成docx

    github地址:
    https://github.com/Ziv-Barber/officegen/tree/87dd5501968501555ea3bee60043affc9f67c1fa#readme
    在这里插入图片描述

    文件压缩导出zip

    一开始我使用的是jszip第三方包,但是最后生成zip文件的时候采用的是blob数据格式,我的node版本低 另外项目原因也不支持我升级node版本,最后我使用了adm-zip库.

    github地址:https://github.com/cthackers/adm-zip
    开发文档地址:https://github.com/cthackers/adm-zip/wiki/ADM-ZIP
    有大神做了翻译:
    https://blog.csdn.net/Free_Wind22/article/details/104049762

    import AdmZip from 'adm-zip';
    // 压缩文件的路径
    const filePaths = [path.join(path.dirname(this.documentUri!.fsPath), 'main.docx'), path.join(path.dirname(this.documentUri!.fsPath), 'main.mp3')];
    // 创建一个新的 zip 文件对象
    const zip = new AdmZip();
    // 将每个文件添加到 zip 文件中
    filePaths.forEach(filePath => {
    	// // 读取文件内容
    	// const fileContent = fs.readFileSync(filePath);
    	// // 将文件添加到 zip 文件中,使用文件名作为 zip 文件中的路径
    	// zip.addFile(filePath, fileContent);
    	zip.addLocalFile(filePath);
    });
    // 将 zip 文件写入磁盘
    zip.writeZip(path.join(url[0].fsPath, 'result.zip'));
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
  • 相关阅读:
    bug:XShell无法连接CentOS虚拟机
    大数据面试题:Spark和Flink的区别
    最优秀的一批程序员,在用最蠢的方式写代码
    matlab如何实现任意长序列所有排列方式
    创建域名的步骤
    QT基础教程(QDebug和QString)
    如何优化敏捷需求管理流程,敏捷需求如何管理。
    267 基于matlab的信号处理GUI人机交互
    前端框架纯js版本
    Hudi(三)集成Flink
  • 原文地址:https://blog.csdn.net/woyebuzhidao321/article/details/130912883