Node.js结合FFmpeg实现RTSP转RTMP推流详解

作者:接口漫谈时间:2026-10-22 09:55:06浏览:519

本文介绍如何利用Node.js与FFmpeg构建局域网视频接收、转码及互联网推流方案。通过fluent-ffmpeg封装命令行工具,实现从RTSP源拉取视频并转换为RTMP格式推送至指定地址。文章涵盖环境配置、核心代码实现及性能测试分析,适用于需要简单视频分发场景的开发参考。

Node.js结合FFmpeg实现RTSP转RTMP推流详解

本文旨在基于FFmpeg核心功能,开发一款能够在局域网内接收视频流、进行转码处理,并将结果推送到互联网的客户端软件。内容仅涉及FFmpeg的基础应用,包括拉取远端视频流、格式转换、推流操作以及基础的播放设置。

工作流程概述

工作流程概述

  1. 首先,系统从远端拉取视频流,该视频流的原始格式为RTSP协议。
  2. 接着,将拉取到的视频流转换为通用的RTMP播放格式,以便后续处理。
  3. 最后,将转换后的视频流推送到指定的播放端口,地址格式为rtmp://您的推送端地址。用户只需使用支持该协议的播放软件连接此地址,即可直接观看视频内容。

所需工具及软件清单

所需工具及软件清单

1. FFmpeg命令行工具:可通过官网链接获取。选择FFmpeg的主要优势在于:

  1. 它是免费开源的软件。
  2. 无需复杂安装过程,这大大降低了用户的操作复杂度。
  3. 支持通过命令行启动和调用,便于集成到程序中。

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资源。若需进行多路视频推送,建议采用其他优化方案解决性能瓶颈。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持本站。

作者最新文章