nodejs ffmpeg 超级工具 rtsp fmp4 rtmp

Posted qianbo_insist

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了nodejs ffmpeg 超级工具 rtsp fmp4 rtmp相关的知识,希望对你有一定的参考价值。

1、为何使用nodejs作为测试工具

1 、nodejs作为一个非常棒的工具,启动http协议使用express或者koi这种工具非常方便
2 、性能卓越,单线程启动不用担心有访问加锁问题
3、在使用c,c++,等程序来使用ffmpeg sdk时,常常可以使用nodejs和ffmpeg来验证

2、使用express ffmpeg来启动做视频封面

ffmpeg -i a.mp4 -y -f image2 -frames 1 a.jpg
ffmpeg -i 11.mp4 -vframes 1 xx.jpg
ffmpeg -i a.mp4 -r 0.1 frames_%04.png
convert -background white -flatten ***.pdf ***.png

3、使用express ffmpeg来做fmp4的工具

3.1 fmp4常识

fmp4 :
  分段mp4,可以作为直播工具
ffmepg movflags参数:
  frag_keyframe: 导致碎片输出,empty_moov:将导致输出100%分段;

ffmpeg c sdk调用方式如下

AVDictionary *opts = NULL;
av_dict_set(&opts, "movflags", "frag_keyframe+empty_moov", 0);
avformat_write_header(o_fmt_ctx, &opts);
av_dict_free(&opts);

3.2 使用fluent-ffmpeg

fluent-ffmpeg 是一个非常好的nodejs封装ffmpeg工具
npm install --save fluent-ffmpeg

const fs = require('fs');
const ffmpegPath = require('ffmpeg-static').path;
const ffmpeg = require('fluent-ffmpeg');
ffmpeg.setFfmpegPath(ffmpegPath);//这个可以使用当前目录


const express = require('express');
const app = express();

app.use(express.static(__dirname + '/public'));

app.get('/', function (req, res) {
  res.send('index.html');
});

app.get('/video/:filename', function (req, res) {
  res.contentType('mp4');
  // make sure you set the correct path to your video file storage
  var pathToMovie = 'public/' + req.params.filename;
  var proc = ffmpeg(pathToMovie)
    // use the 'flashvideo' preset (located in /lib/presets/flashvideo.js)
    .outputOptions('-movflags','frag_keyframe+empty_moov')
    .noAudio()
    .videoCodec('copy')
    .format('mp4')
    // setup event handlers
    .on('end', function () {
      console.log('file has been converted succesfully');
    })
    .on('error', function (err) {
      console.log('an error happened: ' + err.message);
    })
    // save to stream
    .pipe(res, { end: true });
});

app.listen(4000);

4、canvas 传输到后台使用ffmpeg 转化成rtmp

如何把canvas的内容使用h264 经过 websocket传输到后台,我的博客里面有,仔细找一定能找到

以下这个技巧非常有用

/**
 *  Copyright (c) MST.
 */

const child_process = require('child_process');
const express = require('express');
const WebSocketServer = require('ws').Server;
const http = require('http');

const app = express();
const server = http.createServer(app).listen(3000, () => {
  console.log('Listening...');
});
//建立一个websocket server
const ws_server = new WebSocketServer({
  server: server
});

app.use((req, res, next) => {
  console.log('HTTP Request: ' + req.method + ' ' + req.originalUrl);
  return next();
});

app.use(express.static(__dirname + '/www'));

ws_server.on('connection', (ws, req) => {
  
  rtmpUrl = "rtmp://192.168.0.1/live/1001"
  console.log('Target RTMP URL:', rtmpUrl);
 
  const ffmpeg = child_process.spawn('ffmpeg', [
    
    '-f', 'lavfi', '-i', 'anullsrc',
    // FFmpeg will read input video from STDIN
    '-i', '-',
    '-shortest',
    '-vcodec', 'copy',
    '-acodec', 'aac',
    // FLV is the container format used in conjunction with RTMP
    '-f', 'flv',
    rtmpUrl 
  ]);
  
  // If FFmpeg stops for any reason, close the WebSocket connection.
  const rtspUrl = "rtsp://127.0.0.1:5554/1001";
  ffmpeg.on('close', (code, signal) => {
    console.log('FFmpeg child process closed, code ' + code + ', signal ' + signal);
    ws.terminate();
  });
  
  ffmpeg.stdin.on('error', (e) => {
    console.log('FFmpeg STDIN Error', e);
  });
  
  // FFmpeg outputs all of its messages to STDERR.  Let's log them to the console.
  ffmpeg.stderr.on('data', (data) => {
    console.log('FFmpeg STDERR:', data.toString());
  });

  // When data comes in from the WebSocket, write it to FFmpeg's STDIN.
  ws.on('message', (msg) => {
    console.log('DATA', msg);
    ffmpeg.stdin.write(msg);
  });
  
  // If the client disconnects, stop FFmpeg.
  ws.on('close', (e) => {
    ffmpeg.kill('SIGINT');
  });
  
});

换一下,推送到rtsp server

 const ffmpeg = child_process.spawn('ffmpeg', [

    '-f', 'lavfi', '-i', 'anullsrc',
    // FFmpeg will read input video from STDIN
    '-i', '-',
    '-shortest',
    '-c:v', 'copy',
    '-c:a', 'aac',
    '-buffer_size', '1024000',
    '-f','rtsp',
    '-fflags', 'nobuffer',
    rtspUrl
    // FLV is the container format used in conjunction with RTMP
    //'-f', 'flv',
    //rtmpUrl 
  ]);

推摄像头到rtsp

var outputh = 'rtsp://' + 'ip' + ':' + 'port' + '/' + textname;
var ffmpegPath = "./ffmpeg_bin/ffmpeg.exe";
var ffmpeg = require('fluent-ffmpeg');
command = new ffmpeg('video=HD USB Camera')
    .setFfmpegPath(ffmpegPath)
    .inputOptions('-f dshow')
    .size('800x600')
    .on('start', function(commandLine) {
        console.log("start push......." + commandLine);
        console.log("start command......." + command);
    })
    .on('end', function() {
        console.log("storp push........")
        stopPush();
    })
    .on('error', function(err, stdout, stderr) {
        console.log('error:' + err.message);
        console.log('stdout:' + stdout);
        console.log('stderr:' + stderr);
        stopPush();
    })
    .addOptions([
        // '-preset veryfast',
        '-rtsp_transport tcp',
        '-f rtsp'
    ])
    .pipe(outputh, { end: true });`

以上是关于nodejs ffmpeg 超级工具 rtsp fmp4 rtmp的主要内容,如果未能解决你的问题,请参考以下文章

求救 怎样使用ffmpeg函数接收rtsp 网络数据

FFmpeg入门详解之84:RTSP协议讲解

QT Web引擎支持rtsp流吗

FFMPEG:RTSP 流冻结,但 FFMPEG 继续录制

h5播放rtsp流

FFmpeg 播放 RTSP/Webcam 流