Node.js结合FFmpeg实现RTSP转RTMP推流详解
本文介绍如何利用Node.js与FFmpeg构建局域网视频接收、转码及互联网推流方案。通过fluent-ffmpeg封装命令行工具,实现从RTSP源拉取视频并转换为RTMP格式推送至指定地址。文章涵盖环境配置、核心代码实现及性能测试分析,适用于需要简单视频分发场景的开发参考。
Node.js结合FFmpeg实现RTSP转RTMP推流详解
本文旨在基于FFmpeg核心功能,开发一款能够在局域网内接收视频流、进行转码处理,并将结果推送到互联网的客户端软件。内容仅涉及FFmpeg的基础应用,包括拉取远端视频流、格式转换、推流操作以及基础的播放设置。
工作流程概述
工作流程概述
- 首先,系统从远端拉取视频流,该视频流的原始格式为RTSP协议。
- 接着,将拉取到的视频流转换为通用的RTMP播放格式,以便后续处理。
- 最后,将转换后的视频流推送到指定的播放端口,地址格式为rtmp://您的推送端地址。用户只需使用支持该协议的播放软件连接此地址,即可直接观看视频内容。
所需工具及软件清单
所需工具及软件清单
1. FFmpeg命令行工具:可通过官网链接获取。选择FFmpeg的主要优势在于:
- 它是免费开源的软件。
- 无需复杂安装过程,这大大降低了用户的操作复杂度。
- 支持通过命令行启动和调用,便于集成到程序中。
2. Node.js环境:建议使用v6.11.3版本。在实际项目中,如果不需要打包成独立的客户端应用,直接使用Node.js即可正常运行相关逻辑;若需打包客户端,可结合Electron使用。
3. TypeScript编译器(tsc):建议使用v2.6.1版本。本项目主要使用TypeScript进行编写,但如果您熟悉JavaScript,直接使用JS也是可行的。
若选择使用tsc,请确保版本在2.0以上,其自带的@types工具包能显著提升编码效率。
4. fluent-ffmpeg库:建议使用v2.1.2版本。该Node.js包对FFmpeg的命令行调用进行了封装,增强了代码的可读性。如果您熟悉FFmpeg的命令行手册,也可以选择不使用此包直接调用。
npm install --save fluent-ffmpeg
//使用js编码的用户,可以忽略下条命令
npm install --save @types/fluent-ffmpeg
5. VLC播放软件:用于监测推流、转码及播放过程是否正常,可通过官网链接下载。
实现代码部分
实现代码部分
const ffmpegPath = "./dist/ffmpegProgram/bin/ffmpeg.exe";
const ffprobePath = "./dist/ffmpegProgram/bin/ffprobe.exe";
const flvtoolPath = "./dist/ffmpegProgram/bin/ffplay.exe";
export function startPushVideo():void{
getCommands().then((commands:ffmpegPaths[])=>{
for(let key in commands){
let command = commands[key];
//设置输入流地址
let ffCommand = ffmpeg(command.inputPath)
//设置输出流地址
.output(command.outputPath)
//因需要打包客户端软件,故而将ffmpeg打包进软件中
//需设置各应用程序的对应路径
//若仅在本机使用,可以跳过该步骤
//设置环境变量,添加 PATH 即可
.setFfmpegPath(ffmpegPath)
.setFfprobePath(ffprobePath)
.setFlvtoolPath(flvtoolPath)
//为保证灵活性,非必须参数采用配置文件读取模式
.size(command.size);
for(let key in command.args){
ffCommand.outputOption(command.args[key]);
}
ffCommand.on("start",(commandLine)=>{
//commandLine 为实际上调用的命令行命令,拼接逻辑为
//您的ffmpeg所在路径 -i inputOptions 您的拉流协议和路径 outputOptions 推送流协议和地址
//ffmpeg -i "rtsp://yourPullUrl" -f flv -r 25 -s 640x480 -an "rtmp://yourPushUrl"
console.log('[' + showTime() + '] Vedio is Pushing !');
console.log('[' + showTime() + '] Spawned Ffmpeg with command !');
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() + '] Vedio Pushing is Finished !');
})
.run();
}
},(error)=>{
console.log('error: ' + error);
})
}
小结与注意事项
小结与注意事项
可以通过监听"start"事件获取命令执行状态,也可以使用exec(yourCommandLine)直接调用。但后者无法有效控制FFmpeg的运行结果:程序结束后,FFmpeg进程可能仍在后台运行,直到出现流错误或手动停止进程。目前尚不清楚fluent-ffmpeg为何能在主进程结束后通知关闭第三方进程,推测其可能通过命令行输入切断进程,而仅使用ChildProcess.kill()可能无法有效关闭第三方进程。
在配备I5处理器和8G内存的机器上运行测试,单路视频推送已占用约35%的CPU资源。若需进行多路视频推送,建议采用其他优化方案解决性能瓶颈。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持本站。
全栈开发中JavaScript与Java怎么协作?前后端技术栈配合解析
2026-11-04 11:08:24
Node.js官网访问慢?国内镜像加速下载方案
2026-11-03 18:57:24
Node.js 连接 MySQL 数据库实现增删改查操作
2026-11-03 14:31:14
Windows系统安装Node.js:下载、配置与环境验证
2026-11-03 14:15:56
Linux (Ubuntu/CentOS) 环境下安装Node.js的常用方法
2026-11-03 10:18:39
