当前位置: 首页 > 后端技术 > Node.js

vscode语音注释丰富资料(中)

时间:2023-04-03 11:40:37 Node.js

vscode语音注释丰富资料(中)及其他相关功能。1.Mac电脑获取音频文件(后面会有坑,到时候补上)要开发音频'播放'功能,那么我们首先需要一个音频文件,网上下载的mp3文件大多需要要注册的话直接用电脑用带的录音功能生成mp3就可以了。这种方式存在bug,我们稍后会解决。下面是mac电脑录音功能的演示:第一步:找到软件:第二步:将录制的音频分享到一个appm4a文件:(我们可以手动修改后缀名)》m4a是MPEG-4音频standardfile和大家熟悉的mp3一样,也是一种音频格式文件,Apple用这个名字来区别mpeg4视频。二、播放音频插件的选择这里的播放指的是“鼠标悬停”播放Audio,那么在web意义上是无法播放的,因为我们无法使用audio标签来实现,vscode是基于开发的在Electron上,所以里面的插件也是在node环境下,那么我们就可以使用node将音频流输入到Audio输出设备,达到播放的目的。用node播放音频的插件不多网上有,这里推荐两个:play.js&node-wav-playerplay.js:github地址node-wav-player:github地址play.js有一个缺陷,就是不能暂停播放问题可能是开发者难以忍受,所以最终选择了node-wav-player,虽然叫wav播放器,但是mp3也可以播放。安装启动:yarnadd使用播放:(这里暂时使用绝对地址)在`hover.ts文件中添加:import*asvscodefrom'vscode';import*asplayerfrom'node-wav-player';import{getVoiceAnnotationDirPath,targetName,testTargetReg}from'./util'letstopFn:()=>void;functionplayVoice(id:string){constvoiceAnnotationDirPath=getVoiceAnnotationDirPath()if(voiceAnnotationDirPath){player.play({path:`/xxx/xxxx/xx.mp3`}).catch(()=>{vscode.window.showErrorMessage('播放失败')})stopFn=()=>{player.stop()}}}导出默认的vscode.languages。registerHoverProvider("*",{provideHover(documennt:vscode.TextDocument,position:vscode.Position){stopFn?.()constword=documennt.getText(documennt.getWordRangeAtPosition(position));consttestTargetRes=testTargetReg.exec(word);if(testTargetRes){playVoice(testTargetRes[1])返回新的vscode.Hover('Playing...')}}})player.play路径播放地址暂时硬编码,你会发现可以正常播放音频。如果这时候你认为播放功能没问题,那就大错特错了错误三、node-wav-player的核心原理node-wav-player的代码非常简单,远比我想象的要简洁。以下是我简化后的代码。是不是清爽多了:初始化的play方法,只负责对数据进行排序,实际播放依赖于_play方法_play方法节点child_process.spawn用于启动一个新的‘子进程’,也就是“子进程”用于启动音频播放。第一个参数是命令语句,如果第二个参数是数组,就是执行命令的位置。下面我来演示一下spawn的使用方法:比如afplay音频地址可以在mac上播放声音。如果监听错误不是code0或者手动调用this._called_stop===true停止,会报“playfailure”。如果在500毫秒内没有报错,则removeAllListeners("close")将移除已关闭的监听器。监视器。如何终止播放?直接在stop方法中kill掉'subprocess'即可:4.'Where'录制音频?好的用户可以一键“录音”,一键生成音频注释。我最初的想法是尽量在vscode里面做,也就是不开一个新的h5页面,让用户不要超出vscode的层次。录音不能等同于播放音频,因为录音涉及到录音后重播,保存音频文件,还有开始+暂停+结束等操作,所以最好有一个操作界面,而不是靠node单打独斗。5.webview创建webviewvscode内部提供了webview的能力。第一眼看到就‘心动’了。我们可以使用以下代码添加一个webview页面。constpanel=vscode.window.createWebviewPanel("Typexxx","Titlexxx",vscode.ViewColumn.One,{});定义内容需要使用panel.webview.html属性,类似于innerHTML:constpanel=vscode.window.createWebviewPanel("Typexxx","Titlexxx",vscode.ViewColumn.One,{});panel.webview.html=`

123
`;局限看了官方文档,也查了ts类型的文件,可惜没有找到音频授权的方法,所以无法使用audio标签来收集用户的音频信息,只能另辟蹊径实现了.6、右键录音我参考了一些音乐播放软件,发现几乎所有人的播放功能都是通过打开h5页面来实现的,所以我们的录音功能也可以这样尝试。原理当然是用node启动一个web服务,然后帮用户打开一个像http://localhost:8830/这样的地址,返回一段html给用户,这里就是记录的地方.定义右键导航,在package.json文件中添加“contributes”:group":"navigation"}]},"commands":[{"command":"vn.recording","title":"在本项目中录制语音笔记"}]}editor/context定义权限的内容-单击菜单栏。whenactivatesthisfunctiondefinitioninwhichlifecycle,这里选择当获得编辑焦点时。命令定义命令名称。title是菜单中显示的名称。打开h5页面extension.ts,添加一个新的导航模块:import*asvscodefrom'vscode';importhoverfrom'./hover';importinitVoiceAnnotationStylefrom'./initVoiceAnnotationStyle';importnavigationfrom'./navigation'//新的导出函数activate(context:vscode.ExtensionContext){initVoiceAnnotationStyle()context.subscriptions.push(hover);context.subscriptions.push(导航);//添加context.subscriptions.push(vscode.window.onDidChangeActiveTextEditor(()=>{initVoiceAnnotationStyle()}))}exportfunctiondeactivate(){}navigation,ts文件,负责启动服务和打开浏览器跳转到相应页面:yarnaddopenimport*asvscodefrom'vscode';import*asopenfrom'open';importserverfrom'./server';import{serverProt}from'./util';import{Server}from'http';letserverObj:Server;exportdefaultvscode.commands.registerCommand("vn.recording",function(){constvoiceAnnotationDirPath=getVoiceAnnotationDirPath()if(voiceAnnotationDirPath){if(!serverObj){serverObj=server()}open(`http://127.0.0.1:${serverProt()}`);}})startserver因为我们的插件要越小越好,当然这里不使用任何框架,直接用原来的就可以了:新建一个server.ts文件:import*asfs从'fs';从'http'导入*作为http;从'path'导入*作为路径;从'url'导入*作为url;从'./util'导入{targetName,getVoiceID};导出默认函数(){constserver=http.createServer(function(req:http.IncomingMessage,res:http.ServerResponse){res.write(123)res.end()}).listen(8830)returnserver}七、返回页面,定义api服务器无法启动,现在开始定义接口能力,在server.ts中:import*asfsfrom'fs';从“http”导入*作为http;从“路径”导入*作为路径;从“url”导入*作为url;从“./util”导入{serverProt,targetName,getVoiceID};consttemp=fs.readFileSync(路径.join(__dirname,"./index.html"))导出默认函数(){constserver=http.createServer(function(req:http.IncomingMessage,res:http.ServerResponse){if(req.method==="POST"&&req.url==="/create_voice"){createVoice(req,res)}else{res.writeHead(200,{"content-type":'text/html;charset="fs.unwatchFile-8"'})res.write(temp)res.end()}}).listen(serverProt())returnserver}src/html/index.html文件就是我们录制的h5接口文件。我们定义上传为“POST”请求,请求地址为/create_voice。createVoice方法该方法用于接收音频文件并保存在用户指定的位置:functioncreateVoice(req:http.IncomingMessage,res:http.ServerResponse){letdata:Uint8Array[]=[];req.on("data",(chunck:Uint8Array)=>{data.push(chunck)})req.on("end",()=>{letbuffer=Buffer.concat(data);constvoiceId=getVoiceID()try{fs.writeFileSync(`Wheretosaveaudio`,buffer,)}catch(error){res.writeHead(200)res.end()}res.writeHead(200)res.end(JSON.stringify({voiceId:`//${targetName}_${voiceId}`}))})}因为前端会使用formData传输音频文件,所以需要这种接收方式。将最后生成的//voice_annotation_20220220153713111音频注释字符串返回给前端,这样前端就可以直接放入用户剪贴板。end接下来是录音和上传(涉及webRTC相关知识),以及如何定义音频文件的存储路径,以及附加的vscode插件的发布。这次就是这样,希望能和大家一起进步。