美文网首页nodetool
Nodejs Web推流拉流实现直播功能

Nodejs Web推流拉流实现直播功能

作者: 快乐Plus | 来源:发表于2020-01-17 10:09 被阅读0次

    一、服务器

    这里使用egg做例子,Express,Koa大小异同

    1.安装node-media-server

    npm install node-media-server --save
    

    GitHub地址:https://github.com/illuspas/Node-Media-Server

    2.node-media-server配置的参数

      const NodeMediaServerConfig = {
        rtmp: {
          port: 1935,
          chunk_size: 60000,
          gop_cache: true,
          ping: 30,
          ping_timeout: 60,
        },
        http: {
          port: 8000,
          allow_origin: '*',
        },
      };
    

    3.运行服务

      const NodeMediaServer = require('node-media-server');
      const nms = new NodeMediaServer(app.config.NodeMediaServerConfig);
      nms.run();
    

    此时两个端口的服务已经跑起来了,根据配置文件,推流使用的是默认的1935端口,当使用rtmp协议时是不需要加端口号的。
    无后端框架经验的可以根据GitHub上文档跑一个Node js文件就可以了

    二、推流

    node-media-server在文档给出的推流工具是FFmpeg,可以下载该工具后进行推流测试
    http://ffmpeg.org/

    ffmpeg -re -i INPUT_FILE_NAME -c copy -f flv rtmp://localhost/live/STREAM_NAME
    

    这个工具是一个视频处理的工具,也有无需安装而且功能强大的有点,有兴趣的可以了解,这个命令主要是把视频文件当流推到指定地址,要实现直播效果继续往下走吧

    1.推流sdk

    我这里推荐一个国内比较齐全的推流sdk,可以在网站上找到android,window,mac,flutter等的Demo
    大牛直播sdk
    这里也是建议大家使用sdk,方便快捷功能齐全,只要使用应用Demo输入服务器地址就可以内网调试了,也完整的提供了sdk

    2.Web端推流

    这个真心不怎么推荐了,如果需要玩耍的可以实现一下
    先了解下rtmp-streamer
    另外,FlashPlayer即将不再被各大浏览器支持了,所以酌情玩耍就好
    文档提到

    `rtmp-streamer` 遵循[AMD](http://requirejs.org/docs/whyamd.html)规范,可通过[`require.js`](http://requirejs.org/)等方式加载, 另外, 请确保在页面中引入了`RtmpStreamer.swf`, 否则`rtmp-streamer`将无法正确载入
    

    如果你使用webpack可以通过npm安装并require

    npm install rtmp-streamer --save
    
    值得注意的是一个swf文件需要引入,并且载入后才可以调用推流的方法

    在body加入<object>,引入swf文件

    <object>
        <embed id="rtmp-streamer" src="../RtmpStreamer.swf" bgcolor="#999999" quality="high"
               width="320" height="240" allowScriptAccess="sameDomain" type="application/x-shockwave-flash"></embed>
    </object>
    

    然后调用publish方法向服务器推视频流

    require(["rtmp-streamer"], function (RtmpStreamer) {
      var streamer = new RtmpStreamer(document.getElementById('rtmp-streamer'));
      streamer.publish(url, name);
    });
    

    在一般的html页面里面引入需要引入requireJs
    然后使用require引入rtmp-streamer

    注意必须要swf插件引入完成后才可以使用推流方法,利用全局isReady变量可以判断此状态

    这里先直接上我的代码

    <!doctype html>
    <html lang="en">
    <head>
      <!-- Required meta tags -->
      <meta charset="utf-8">
      <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
      <!-- 新 Bootstrap 核心 CSS 文件 -->
      <link href="https://cdn.staticfile.org/twitter-bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
    
      <!-- jQuery文件。务必在bootstrap.min.js 之前引入 -->
      <script src="https://cdn.staticfile.org/jquery/2.1.1/jquery.min.js"></script>
    
      <!-- 最新的 Bootstrap 核心 JavaScript 文件 -->
      <script src="https://cdn.staticfile.org/twitter-bootstrap/3.3.7/js/bootstrap.min.js"></script>
      <title>RTMP Web 推流Demo</title>
    </head>
    
    <body style="text-align: center;">
      <nav class="navbar navbar-light fixed-top rtc-primary-bg">
        <h5>基础推流拉流</h5>
      </nav>
      <div class="panel panel-default">
        <div class="panel-heading">
          <h3 class="panel-title">
            推流
          </h3>
        </div>
        <br>
        <object>
          <embed id="rtmp-streamer" src="../public/rtmp-streamer/RtmpStreamer.swf" bgcolor="#999999" quality="low"
                 width="320" height="240" allowScriptAccess="localhost" type="application/x-shockwave-flash"></embed>
        </object>
        <br>
        <div>
          <label for="url" class="col-sm-1 control-label">服务器地址</label>
          <div class="col-sm-10">
            <input type="text" class="form-control" id="url"
                   value="localhost">
          </div>
          <br>
          <br>
          <label for="room" class="col-sm-1 control-label">房间号</label>
          <div class="col-sm-10">
            <input type="text" class="form-control" id="room"
                   value="test">
          </div>
          <br>
          <br>
          <label for="width" class="col-sm-1 control-label">分辨率</label>
          <div class="col-sm-1">
            <input type="text" class="form-control" id="width"
                   value="320">
            *<input type="text" class="form-control" id="height"
                   value="240">
          </div>
        </div>
        <br><br><br>
        <br><br>
        <button type="button" class="btn btn-info" onclick="startPush()">开始推流</button>
        <button type="button" class="btn btn-warning" onclick="disconnectPush()">停止推流</button>
        <br><br>
      </div>
      <br>
      <hr>
      <div class="panel panel-default">
        <div class="panel-heading">
          <h3 class="panel-title">
            拉流
          </h3>
        </div>
        <br>
        <video id="videoElement" style="background:#eeeef3;"></video>
        <br>
        <div>
          <label for="playUrl" class="col-sm-1 control-label">服务器地址</label>
          <div class="col-sm-10">
            <input type="text" class="form-control" id="playUrl"
                   value="localhost:8000">
          </div>
          <br>
          <br>
        </div>
        <button type="button" class="btn btn-info" onclick="videoPlay()">开始播放</button>
        <br><br>
      </div>
    
      <script src="https://cdn.bootcss.com/flv.js/1.5.0/flv.min.js"></script>
    
      <script type="text/javascript" src="../public/require.js"></script>
      <script type="text/javascript">
        let streamer = {};
          const RtmpStreamerObj = document.getElementById('rtmp-streamer');
          require.config({
            paths:{
              "rtmp-streamer":'../public/rtmp-streamer/rtmp-streamer'
            }
          });
          require(["rtmp-streamer"], RtmpStreamer=> {
            streamer = new RtmpStreamer(RtmpStreamerObj);
            console.log(streamer);
          });
          function disconnectPush() {
            streamer.disconnect();
          }
          function startPush(){
            if(isReady){
              let url = document.getElementById('url').value;
              let room = document.getElementById('room').value;
              let width = document.getElementById('width').value;
              let height = document.getElementById('height').value;
              if(url.length==0 || room.length==0 || width.length==0 || height.length==0){
                alert("请输入配置信息");
                return false;
              }
              RtmpStreamerObj.width = width;
              RtmpStreamerObj.height = height;
              streamer.publish(`rtmp://${url}/live`,room);
              alert("已开始推流");
            }else{
              setTimeout(_=>{
                console.log('retry');
                startPush();
              },1000)
            }
          }
          function videoPlay() {
            if (flvjs.isSupported()) {
              const url = document.getElementById('playUrl').value;
              const videoElement = document.getElementById('videoElement');
              const flvPlayer = flvjs.createPlayer({
                type: 'flv',
                url
              });
              flvPlayer.attachMediaElement(videoElement);
              flvPlayer.load();
              flvPlayer.play();
              alert("已开始播放");
            }else{
              setTimeout(_=>{
                videoPlay();
              },1000)
            }
          }
      </script>
    </body>
    </html>
    
    

    三、拉流

    拉流相对来说支持的比较多,调试可以使用VLC播放器,十分强大,有兴趣自行了解。
    另外一般的都可以使用flv.js进行播放

    <script src="https://cdn.bootcss.com/flv.js/1.5.0/flv.min.js"></script>
    if (flvjs.isSupported()) {
              const url = document.getElementById('playUrl').value;
              const videoElement = document.getElementById('videoElement');
              const flvPlayer = flvjs.createPlayer({
                type: 'flv',
                url
              });
              flvPlayer.attachMediaElement(videoElement);
              flvPlayer.load();
              flvPlayer.play();
              alert("已开始播放");
            }
    

    另外在过程中了解到一个比较强大的js的video播放器,集成了片头广告,片尾广告,各种广告位的国产播放,有兴趣可以了解
    ckplayer

    整个过程感觉比较简单,就简单说说,本人造诣不深,仅供参考,如有问题可以留言,祝春节愉快

    相关文章

      网友评论

        本文标题:Nodejs Web推流拉流实现直播功能

        本文链接:https://www.haomeiwen.com/subject/kxgtzctx.html