NestJS搭建直播服务器

NestJS搭建直播服务器 🐱‍🏍🐱‍🏍🐱‍🏍

介绍

后端使用node-media-server搭建直播推流服务器,使用obs推流,前端可使用B站开源的flv.js来播放直播,React可使用react-player播放

一、实现原理

二、node-media-server 搭建直播流服务器

node-media-server是基于node.Js开发的一个推流服务器GitHub地址 ☞ node-media-server

  • 下载node-media-server@ffmpeg-installer/ffmpeg(对流进行处理需要用到这个工具)推荐使用pnpm

    bash 复制代码
    pnpm i node-media-server @ffmpeg-installer/ffmpeg
  • 新建一个live.js文件

    js 复制代码
    import NodeMediaServer from 'node-media-server'
    const createStream = () => {
       // 流最基础的配置文件
       const config = {
          rtmp: {
            port: 1935, // 推流端口
            chunk_size: 60000,
            gop_cache: true,
            ping: 30,
            ping_timeout: 60,
          },
          http: {
            port: 8887, // 获取流的地址
            allow_origin: '*',
          }
        }
        const avv = new NodeMediaServer(config)
        avv.run()
    }
    
    createStream()
  • 执行该文件 node live.js 控制台会打印如下则证明服务器启动成功

    bash 复制代码
    Node Media Server v2.6.2
    Node Media Rtmp Server started on port: 1935
    Node Media Http Server started on port: 8887
    Node Media WebSocket Server started on port: 8887
  • 在浏览器中访问127.0.0.1:8887/admin 可访问服务器管理端地址这里可查看更多api

三、使用obs软件进行直播推流obs软件进行直播推流

  • 下载obs 这里以windows版作为演示

  • 下载完成后依此点击 设置 => 直播 设置推流地址为 rtmp://127.0.0.1:1935/live live为app名称可自行替换,推流码也可自行替换

  • 上面我们设置了app名称为live,推流码为mylive2,然后开启直播并打开127.0.0.1:8887/admin 管理端地址(记得刷新页面~),可以看到直播参数,可以点击mylive2来预览直播

四、使用flv.js播放

  • 注意地址由app名称live加namemylive2组成
html 复制代码
<script src="https://cdn.bootcss.com/flv.js/1.5.0/flv.min.js"></script>
<video id="videoElement"></video>
<script>
    if (flvjs.isSupported()) {
        var videoElement = document.getElementById('videoElement');
        var flvPlayer = flvjs.createPlayer({
            type: 'flv',
            url: 'http://localhost:8887/live/mylive2.flv'   
        });
        flvPlayer.attachMediaElement(videoElement);
        flvPlayer.load();
        flvPlayer.play();
    }
</script>

五、对视频流进行处理(高级操作)

  • 浏览器访问http://localhost:8887/live/mylive2.flv后可以直接获取流这样并不安全,通常我们会对url进行加密 node-media-server该插件提供了方法,这里只介绍使用m3u8流来播放
  • 修改上面的createStream方法,使用ffmpeg来处理流,上面我们已经下载了
  • 完整配置如下
js 复制代码
const createStream = () => {
   // eslint-disable-next-line @typescript-eslint/no-var-requires   解决ts,eslint报错
   const ffmpegPath = require('@ffmpeg-installer/ffmpeg').path  // 获取ffmpeg工具地址
   // 流最基础的配置文件
   const config = {
      rtmp: {
        port: 1935, // 推流端口
        chunk_size: 60000,
        gop_cache: true,
        ping: 30,
        ping_timeout: 60,
      },
      http: {
        port: 8887, // 获取流的地址
        mediaroot: './media', // 经过处理的流都会放在这个目录下
        allow_origin: '*',
      },
      // 添加任务 输出两个不同分辨率的流
      fission: {
        ffmpeg: ffmpegPath,  // ffmpeg工具的地址,插件会调用ffmpeg来处理流
        tasks: [
          {
            rule: 'live/*',
            model: [
              {
                ab: '192k', // 音频码率
                vb: '10000k', // 视频码率
                vs: '1920x1080', // 决定了视频的分辨率
                vf: '60', // 刷新率60fps
              },
              {
                ab: '320k',
                vb: '20000k',
                vs: '2560x1440', // 决定了视频的分辨率 
                vf: '60',
              },
            ],
          },
        ],
      },
      //  输m3u8格式的视频  及将视频转为hls
      trans: {
        ffmpeg: ffmpegPath,
        tasks: [
          {
            app: 'live',
            hls: true,
            hlsFlags: '[hls_time=2:hls_list_size=3:hls_flags=delete_segments]',
            hlsKeep: true, // to prevent hls file delete after end the stream
            dash: true,
            dashFlags: '[f=dash:window_size=3:extra_window_size=5]',
            dashKeep: true // to prevent dash file delete after end the stream
          }
        ]
      }
    }
    const avv = new NodeMediaServer(config)
    avv.run()
}
  • 配置hlsffmpeg 会将处理的流放到media文件夹中,视频保存为以.ts为后缀的文件中其中index.m3u8决定了视频的播放顺序所以要通过http://localhost:8887/live/mylive2/index.m3u8来获取视频

六、流加密

  • node-media-server该插件确实提供了url加密但通过实践加密功能并不完善支持的范围也有限可在Issues中查看详情
  • 出于安全来讲如果应用到项目中还是建议采取其他方案来实现流加密

最后

相关推荐
y先森3 小时前
CSS3中的伸缩盒模型(弹性盒子、弹性布局)之伸缩容器、伸缩项目、主轴方向、主轴换行方式、复合属性flex-flow
前端·css·css3
前端Hardy3 小时前
纯HTML&CSS实现3D旋转地球
前端·javascript·css·3d·html
susu10830189113 小时前
vue3中父div设置display flex,2个子div重叠
前端·javascript·vue.js
IT女孩儿4 小时前
CSS查缺补漏(补充上一条)
前端·css
吃杠碰小鸡5 小时前
commitlint校验git提交信息
前端
虾球xz5 小时前
游戏引擎学习第20天
前端·学习·游戏引擎
我爱李星璇5 小时前
HTML常用表格与标签
前端·html
疯狂的沙粒6 小时前
如何在Vue项目中应用TypeScript?应该注意那些点?
前端·vue.js·typescript
小镇程序员6 小时前
vue2 src_Todolist全局总线事件版本
前端·javascript·vue.js
野槐6 小时前
前端图像处理(一)
前端