详解NODEJS基于FFMPEG视频推流测试


Posted in NodeJs onNovember 17, 2017

以ffmpeg为核心,包装一款局域网内接收转码并推送互联网的客户端软件。本文仅使用ffmpeg基础功能,拉流、转码、推流及简单播放设置。

工作流程

  1. 拉取远端视频流,视频流格式为 rtsp
  2. 转换为常用播放格式 rtmp
  3. 推送至播放端口 rtmp://您的推送端地址,用户使用播放软件连接该地址后可以直接进行内容播放

所需工具及软件

1、ffmpeg 命令行工具官网链接,选择它的优势在于:

  1. 免费
  2. 无需安装,很大的减少用户操作复杂度
  3. 命令行启动调用

2、nodejs 版本号为 v6.11.3。(实际项目中使用electron,但若没有打包成客户端的需求,nodejs即可正常运行)

3、tsc 版本号为 v2.6.1。项目使用TypeScript为主要编写语言,您使用JavaScript也没有问题。

若使用tsc,请使用2.0以上版本,自带的@type工具会极大提升编码效率

4、fluent-ffmpeg 版本号为 v2.1.2。该nodejs包封装了ffmpeg的命令行调用部分,加强了代码的可读性,若熟悉ffmpeg 命令行使用手册,亦可不使用该包。

npm install --save fluent-ffmpeg
  //使用js编码的用户,可以忽略下条命令
  npm install --save @types/fluent-ffmpeg

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,多流推送需使用其他方案解决。

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

NodeJs 相关文章推荐
PHPStorm 2020.1 调试 Nodejs的多种方法详解
Sep 17 NodeJs
Nodejs中自定义事件实例
Jun 20 NodeJs
轻松创建nodejs服务器(2):nodejs服务器的构成分析
Dec 18 NodeJs
Nodejs Express4.x开发框架随手笔记
Nov 23 NodeJs
NodeJS的Promise的用法解析
May 05 NodeJs
nodejs读写json文件的简单方法(必看)
Mar 09 NodeJs
nodejs使用express创建一个简单web应用
Mar 31 NodeJs
nodejs 图片预览和上传的示例代码
Sep 30 NodeJs
nodejs爬虫初试superagent和cheerio
Mar 05 NodeJs
nodejs 简单实现动态html的方法
May 12 NodeJs
NodeJs实现简单的爬虫功能案例分析
Dec 05 NodeJs
基于nodejs的微信JS-SDK简单应用实现
May 21 NodeJs
nodejs async异步常用函数总结(推荐)
Nov 17 #NodeJs
详解IWinter 一个路由转控制器的 Nodejs 库
Nov 15 #NodeJs
nodejs判断文件、文件夹是否存在及删除的方法
Nov 10 #NodeJs
nodejs使用express获取get和post传值及session验证的方法
Nov 09 #NodeJs
nodejs操作mongodb的增删改查功能实例
Nov 09 #NodeJs
nodejs中art-template模板语法的引入及冲突解决方案
Nov 07 #NodeJs
Mac 安装 nodejs方法(图文详细步骤)
Oct 30 #NodeJs
You might like
基于Zookeeper的使用详解
2013/05/02 PHP
json的键名为数字时的调用方式(示例代码)
2013/11/15 PHP
php导入excel文件到mysql数据库的方法
2015/01/14 PHP
php基于CodeIgniter实现图片上传、剪切功能
2016/05/14 PHP
javascript 获取select下拉列表值的代码
2009/09/07 Javascript
JS 日期验证正则附asp日期格式化函数
2009/09/11 Javascript
javascript函数作用域学习示例(js作用域)
2014/01/13 Javascript
js实现jquery的offset()方法实例
2015/01/10 Javascript
javascript事件冒泡实例分析
2015/05/13 Javascript
jQuery插件实现静态HTML验证码校验
2015/11/06 Javascript
JS实现DIV容器赋值的方法
2015/12/14 Javascript
javascript实现倒计时跳转页面
2016/01/17 Javascript
轮播的简单实现方法
2016/07/28 Javascript
Angular.js去除页面中显示的空行方法示例
2017/03/30 Javascript
JavaScript反射与依赖注入实例详解
2018/05/29 Javascript
基于Angular中ng-controller父子级嵌套的相关属性详解
2018/10/08 Javascript
jQuery鼠标滑过横向时间轴样式(代码详解)
2019/11/01 jQuery
js抽奖转盘实现方法分析
2020/05/16 Javascript
python zip文件 压缩
2008/12/24 Python
Python抓取框架 Scrapy的架构
2016/08/12 Python
Python开发的HTTP库requests详解
2017/08/29 Python
Python实现输出程序执行进度百分比的方法
2017/09/16 Python
python基于ID3思想的决策树
2018/01/03 Python
tensorflow TFRecords文件的生成和读取的方法
2018/02/06 Python
python打包压缩、读取指定目录下的指定类型文件
2018/04/12 Python
对numpy中shape的深入理解
2018/06/15 Python
Python列表删除元素del、pop()和remove()的区别小结
2019/09/11 Python
python利用openpyxl拆分多个工作表的工作簿的方法
2019/09/27 Python
Tensorflow读取并输出已保存模型的权重数值方式
2020/01/04 Python
在pycharm中使用matplotlib.pyplot 绘图时报错的解决
2020/06/01 Python
Wojas罗马尼亚网站:波兰皮鞋品牌
2018/11/01 全球购物
解释一下ArrayList Vector和LinkedList的实现和区别
2013/04/26 面试题
县人大领导班子四风对照检查材料思想汇报
2014/10/09 职场文书
交通安全宣传标语(100条)
2019/08/22 职场文书
利用Python读取微信朋友圈的多种方法总结
2021/08/23 Python
python Tkinter模块使用方法详解
2022/04/07 Python