zoukankan      html  css  js  c++  java
  • 关于rtsp转码rtmp播放的两种方式,客户端直接转,远程服务器转

    需求

    一、场景

    用户多家门店有监控探头,设备是海康的和大华的。用户总部和门店不在一个网络下,并且总部要能实时调用查看门店监控,和门店回放画面。我们知道监控摄像机获取的视频是 rtsp 流的格式。 只能在特用的软件中播放,并且只能在相同的网络下播放。用户要求开发一个管理软件根据业务需要来播放视频。最终的目地是要把rtsp 流视频 转换为能在浏览器,手机等主流的播放渠道上能播放的视频(rtmp,mp4,flv,m3u8等格式);

    解决办法

    (1)、客户端转码

    我们用electron 来打包客户端,客户端中安装一个在线转码ffmpeg 模块,这个模块中有功能接口能直接对rtsp 进行转码(这种场景主要给 播放软件和门店在一个网络下能直接连接的场景);

    用到两个模块 “fluent-ffmpeg” “node-media-server”

    fluent-ffmpeg 转码模块

    我们用这个模块转码为rtmp 直播流,转码后推送到一个我们在软件内部搭建的一个rtmp 直播流服务器地址
    “rtmp://localhost:1938/live/livestream”

    node-media-server 模块做rtmp直播流服务器

    上面的fluent-ffmpeg 模块转码推送rtmp 流到这个服务器rtmp://localhost:1938/live/livestream,

    到此rtsp被本地转换为了 rtmp流了。 由于rtmp流可以在浏览器中播放, 我们找一个播放器播放这个地址即可。 能播放rtmp流的播放器很多。 我用了一个阿里的flash 播放器来播放可行。

    # electron main.js 部分功能代码
    const ffmpeg = require('fluent-ffmpeg');
    const { NodeMediaServer } = require('node-media-server');
    
    
    // rtmp 播放 服务器
    
      const config = {
        rtmp: {
          port: 1938,
          chunk_size: 60000,
          gop_cache: true,
          ping: 60,
          ping_timeout: 30
        },
        http: {
          port: 8000,
          allow_origin: '*'
        }
      };
    
      var nms = new NodeMediaServer(config)
      nms.run();
    
    
    // 转码指令
    var command = ffmpeg(uri)
        .outputOptions([
          '-fflags',
          'nobuffer',
          '-vcodec',
          'libx264',
          '-preset',
          'superfast',
          '-rtsp_transport',
          'tcp',
          '-threads',
          '2',
          // '-f',
          // 'flv',
          '-r',
          '25',
          // '-s',
          // '640x480',
          //'1280x720',
          '-an'
        ])
        .inputFPS(25)
        .noAudio()
        .size('640x?')
        .aspect('4:3')
        .format('flv')
        // 此处的 /live/camera, camera类似于一个房间的概念, 你可以设置为你想要的名字
        .save(`rtmp://localhost:1938/live/livestream`)
        .on('start', function (e) {
          running = true
          console.log('stream is start: ' + e)
        })
        .on('end', function () {
          running = false
          console.log('ffmpeg is end')
        })
        .on('error', function (err) {
          running = true
          console.log('ffmpeg is error! ' + err)
          //command.kill()
          //reloadStream(uri)
        })
    
    
    

    (2)、服务器端转码

    另一种转码是在外部服务器端安装一套转码服务器,业务中发送接口到远程服务器,服务器收到指令后“主动去拉取rtmp流进行转码”,转码后 再 推送到 服务器上的另外一个 rtmp 服务器上进行分发 rtmp 流;

    1.转码服务器

    我们用一个docker 容器来跑转码服务;

    docker pull   ranmufei/srs-php5-transcode-server:v1.18
    

    容器中封装了一个FFmpeg + web服务器 http://127.0.0.1//runffmpeg.php?type=run; post 提交参数
    rtsp地址

    curl -X POST 
      http://xxxx.cn/admin/Index/testrunffmpeg 
      -H 'cache-control: no-cache' 
      -H 'content-type: application/x-www-form-urlencoded' 
      -H 'postman-token: 148e4b67-1e03-f854-5c71-b1fc6502210c' 
      -H 'token: 667778c46b900c9768c65ac7ce8102d9' 
      -d rtsp=rtsp%3A%2F%2Fadmin%3Aadmin123%4010.31.37.50%3A554%2Fcam%2Frealmonitor%3Fchannel%3D1%26subtype%3D1
    
    

    转码服务器放回 播rtmp 播放地址

    放回格式json

    {
        "response": {
            "ipinfo": {
                "pid": null,
                "ipinfo": null,
                "command": null
            },
            "pid": "31199",
            "playurl": "rtmp://srs-docker-rmf.bubugao:1935/live/livestream_1547693691",
            "str": "/srs/objs/ffmpeg/bin/ffmpeg -rtsp_transport tcp -re -i  'rtsp://admin:xxxxx@10.31.37.50:554/cam/realmonitor?channel=1&subtype=1' -c:a copy -c:v libx264 -preset ultrafast -b:v 200k -r 8 -s 640x480 -f flv rtmp://srs-docker-rmf.bubugao:1935/live/livestream_1547693691 >  /dev/null 2>&1 & echo $!;",
            "rtsp": "rtsp://admin:xxxx@10.31.37.50:554/cam/realmonitor?channel=1&subtype=1",
            "playpath": "rtmp://transcode.xxxxxx.cn:1935/live/livestream_1547693691",
            "datainfo": {
                "type": "run",
                "rtsp": "rtsp://admin:xxxxx@10.31.37.50:554/cam/realmonitor?channel=1&subtype=1"
            }
        },
        "status": 200,
        "API_debug": {
            "url": "transcode.video//runffmpeg.php?type=run",
            "data": {
                "type": "run",
                "rtsp": "rtsp://admin:xxxx@10.31.37.50:554/cam/realmonitor?channel=1&subtype=1"
            }
        }
    }
    
    

    2.rtmp 分发流服务器

    和第一中方式类似,也是拉取rtsp 地址 进行转码 ,这是转码后推送到了云上的这台rtmp 流分发服务器上来了;

    docker pull ossrs/srs:3.0.42-ffmpeg
    

    配置服务器作为 rtmp 服务器; srs 的功能很强大,目前我们只用到了它的分发rtmp 流功能;

    配置参考 https://github.com/ossrs/srs/wiki/v2_CN_Home

    分发为m3u8 格式 供移动端播放

    # srs 的docker.conf 配置中添加hls  配置 会生成 m3u8 的文件,当有流推送到 srs 服务器的时候 会自动高转换为 m3u8 格式文件。
    vhost __defaultVhost__ {
        hls {
            enabled         on;
            hls_path        ./objs/nginx/html;
            hls_fragment    10;
            hls_window      60;
        }
    }
    
    

    参考资料

  • 相关阅读:
    内部类
    抽象类与接口
    多态
    继承
    封装
    创建对象的内存分析
    构造器
    面向对象 类与对象
    uniapp跳转
    uniapp-组件引用错误,仅支持 import 方式引入组件
  • 原文地址:https://www.cnblogs.com/freefei/p/10281300.html
Copyright © 2011-2022 走看看