详解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 相关文章推荐
Nodejs全栈框架StrongLoop推荐
Nov 09 NodeJs
NodeJS学习笔记之Connect中间件模块(二)
Jan 27 NodeJs
详谈Angular路由与Nodejs路由的区别
Mar 05 NodeJs
Nodejs 获取时间加手机标识的32位标识实现代码
Mar 07 NodeJs
nodejs入门教程三:调用内部和外部方法示例
Apr 24 NodeJs
Nodejs之http的表单提交
Jul 07 NodeJs
nodejs实现套接字服务功能详解
Jun 21 NodeJs
NodeJS 将文件夹按照存放路径变成一个对应的JSON的方法
Oct 17 NodeJs
NodeJs实现简单的爬虫功能案例分析
Dec 05 NodeJs
深入理解nodejs搭建静态服务器(实现命令行)
Feb 05 NodeJs
Nodejs实现用户注册功能
Apr 14 NodeJs
nodejs一个简单的文件服务器的创建方法
Sep 13 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
探讨如何在php168_cms中提取验证码
2013/06/08 PHP
php setcookie函数的参数说明及其用法
2014/04/20 PHP
详解PHP数据压缩、加解密(pack, unpack)
2016/12/17 PHP
详解php几行代码实现CSV格式文件输出
2017/07/01 PHP
PHP ElasticSearch做搜索实例讲解
2020/02/05 PHP
Javascript注入技巧
2007/06/22 Javascript
javascript 用原型继承来实现对象系统
2010/03/22 Javascript
Google (Local) Search API的简单使用介绍
2013/11/28 Javascript
使用js Math.random()函数生成n到m间的随机数字
2014/10/09 Javascript
JavaScript中最简洁的编码html字符串的方法
2014/10/11 Javascript
js判断浏览器版本以及浏览器内核的方法
2015/01/20 Javascript
浅析JavaScript访问对象属性和方法及区别
2015/11/16 Javascript
js 实现获取name 相同的页面元素并循环遍历的方法
2017/02/14 Javascript
flag和jq on 的绑定多个对象和方法(必看)
2017/02/27 Javascript
详解angular中的作用域及继承
2017/05/31 Javascript
nodejs动态创建二维码的方法
2017/08/12 NodeJs
详解如何在angular2中获取节点
2017/11/23 Javascript
使用vue官方提供的模板vue-cli搭建一个helloWorld案例分析
2018/01/16 Javascript
animate.css在vue项目中的使用教程
2018/08/05 Javascript
JS实现移动端在线签协议功能
2019/08/22 Javascript
vue视频播放暂停代码
2019/11/08 Javascript
[43:58]DOTA2-DPC中国联赛定级赛 LBZS vs SAG BO3第一场 1月8日
2021/03/11 DOTA
浅谈Python单向链表的实现
2015/12/24 Python
Python中整数的缓存机制讲解
2019/02/16 Python
解决Tensorboard可视化错误:不显示数据 No scalar data was found
2020/02/15 Python
Python爬虫爬取、解析数据操作示例
2020/03/27 Python
python 如何将office文件转换为PDF
2020/09/22 Python
Python爬虫破解登陆哔哩哔哩的方法
2020/11/17 Python
详解canvas在圆弧周围绘制文本的两种写法
2018/05/22 HTML / CSS
Speedo速比涛德国官方网站:世界领先的泳装品牌
2019/08/26 全球购物
美国饼干礼物和美食甜点购买网站:Cheryl’s
2020/05/28 全球购物
中专生求职自荐信范文
2013/12/22 职场文书
合作意向协议书
2015/01/29 职场文书
人才市场接收函
2015/01/30 职场文书
董存瑞观后感
2015/06/11 职场文书
OpenCV-Python实现轮廓的特征值
2021/06/09 Python