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

NODEJS基于FFMPEG视频流测试

时间:2023-04-04 00:25:05 Node.js

,以ffmpeg为核心,封装了一个在局域网接收转码并推送到互联网的客户端软件。本文只使用了ffmpeg的基本功能,推流、转码、推流和简单的播放设置。工作流拉取远程视频流,将视频流格式从rtsp转为常用播放格式rtmp推送到播放端口rtmp://你的推送端地址,用户连接后可以直接播放内容地址与播放软件。而软件ffmpeg命令行工具官网链接,选择它的好处是:它是免费的,不需要安装,大大降低了用户操作的复杂度。命令行启动调用nodejs版本号为v6.11.3。(实际项目中使用的是electron,但如果不需要打包成客户端,nodejs可以正常运行)tsc的版本号是v2.6.1。项目使用TypeScript作为主要编写语言,你使用JavaScript没有问题。如果使用tsc,请使用2.0或以上版本。内置的@type工具将大大提高编码效率。fluent-ffmpeg的版本号是v2.1.2。nodejs包封装了ffmpeg的命令行调用部分,增强了代码的可读性。如果您熟悉ffmpeg命令行用户手册,则无需使用此包。npminstall--savefluent-ffmpeg//使用js编码的用户可以忽略下一个命令npminstall--save@types/fluent-ffmpegVLC播放软件。用于监控推流、转码、播放是否正常。官网链接实现代码constffmpegPath="./dist/ffmpegProgram/bin/ffmpeg.exe";constffprobePath="./dist/ffmpegProgram/bin/ffprobe.exe";constflvtoolPath="./dist/ffmpegProgram/bin/ffplay.exe";exportfunctionstartPushVideo():void{getCommands().then((commands:ffmpegPaths[])=>{for(letkeyincommands){letcommand=commands[key];//设置输入流地址letffCommand=ffmpeg(command.inputPath)//设置输出流address.output(command.outputPath)//因为客户端软件需要打包,ffmpeg打包到软件中//需要设置每个应用程序对应的路径//如果只在本机使用,可以跳过这一步//设置环境变量,添加PATH.setFfmpegPath(ffmpegPath).setFfprobePath(ffprobePath).setFlvtoolPath(flvtoolPath)//为保证灵活性,配置了非必要参数文件读取mode.size(command.size);for(letkeyincommand.args){ffCommand.outputOption(command.args[key]);}ffCommand.on("start",(commandLine)=>{//commandLine是实际调用的命令行命令,拼接逻辑是//你的ffmpeg所在的路径-iinputOptions你拉流协议和路径outputOptions推流协议和地址//ffmpeg-i"rtsp://yourPullUrl"-fflv-r25-s640x480-an"rtmp://yourPushUrl"console.log('['+showTime()+']Vedio正在推送!');console.log('['+showTime()+']SpawnedFfmpegwithcommand!');console.log('['+showTime()+']Command:'+commandLine);}).on('error',function(err,stdout,stderr){console.log('error:'+err.message);console.log('stdout:'+stdout);console.log('stderr:'+stderr);}).on('end',function(){console.log('['+showTime()+']视频推送完成!');})。跑步();}},(error)=>{console.log('error:'+error);})}Summary通过监听“start”得到的Commands也可以通过exec(yourCommandLine)运行调用,但是此时无法控制ffmpeg的运行结果。程序运行结束后,ffmpeg进程还在运行,直到stream报错或手动停止进程。不清楚为什么fluent-ffmpeg可以在主体进程结束后通知第三方进程关闭。猜测是通过命令行输入来切断进程,而第三方进程只能通过ChildProcess.kill()无法关闭。运行在I58G机器上,单流推送已经占用CPU35%左右,多流推送需要其他方案解决。