xgplayer + SRS 实现直播方案

简介: 直播作为近几年比较火的方向,吸引了像我这样的小白不断在音视频的边缘不断试探。“宇宙的尽头是直播”,不论是娱乐直播还是直播带货,都已经成为现在人们生活中不可获取的一部分。 今天我们就来实现一个直播的 demo,我们来看一下整个直播的过程

1682517228(1).png

直播作为近几年比较火的方向,吸引了像我这样的小白不断在音视频的边缘不断试探。“宇宙的尽头是直播”,不论是娱乐直播还是直播带货,都已经成为现在人们生活中不可获取的一部分。 今天我们就来实现一个直播的 demo,我们来看一下整个直播的过程:

1682517249(1).png

SRS 流媒体服务器


为了方便我推荐使用云 SRS,可以基于宝塔一键部署,如果没有云服务器可以根据官方 github 自行编译(难度较大,不推荐新手选择此方式)。 在宝塔的软件商店中搜索 SRS(免费的,如果显示购买直接点击购买即可),点击安装

插件包安装完成之后打开,安装云 SRS,这个过程比较耗时,耐心等待……

1682517310(1).png

安装完成之后需要等待几分钟,云 SRS 内部的依赖启动需要一定的时间,等启动完成之后打开管理面板,设置管理员密码之后,进入系统设置菜单,找到 OpenAPI 选项,我们的后端服务需要根据这两个接口来获取串流秘钥。

1682517326(1).png

1682517410(1).png

后端服务


这边的业务服务器我们使用 Node 来实现,在这个过程中负责客户端鉴权以及获取串流秘钥,这里我选用 Midway(全凭个人喜好,可以选择任何其他的框架 Express、Koa、nest 等)。 我们这里提供两个接口:

  1. 主播获取推流地址和串流秘钥;
  2. 获取房间信息(最主要是 streamKey)

获取串流秘钥

使用 ApiSecret 从云 SRS 的 OpenAPI来获取秘钥,过程如下1682517377(1).png

以下是代码实现(忽略实体、配置等部分,只展示流程)

@Controller('/anchor')  
export class AnchorController {  
  @Inject()  
  ctx: Context;
  @Inject()  
  roomService: RoomService;  
  @Inject()  
  anchorService: AnchorService;  
  @Inject('short-uuid')  
  short;
  @Config('srs')  
  srs; //  配置了服务器 IP 和 ApiSecret
  // 判断主播身份  
  validateAnchor(user: UserModel) {  
    if (!user || user.role !== UserRole.ANCHOR)  
      // 如果没有用户(可能被冻结或者注销)或者没有权限抛出异常  
      throw new CustomError(  
        INSUFFICIENT_PERMISSIONS.CODE_1,  
        INSUFFICIENT_PERMISSIONS.MSG_1  
      );  
  }  
  // 生成向直播间串流秘钥(限制主播身份)  
  @Post('/streamKey')  
  async createStreamKey() {  
    const userId = this.ctx.state.user.uid;  
    const user = await this.anchorService.getAnchorWithRoom(userId);  
    // 身份判断  
    this.validateAnchor(user);  
    // 将主播关联的直播间进行串流秘钥重置  
    const key = this.short.generate();  
    const room = user.liveRoom;  
    room.streamKey = key;  
    // 保存新的串流秘钥  
    await this.roomService.saveRoom(room);  
    // 获取 token (makeHttpRequest 相当于 fetch, 做请求用)
    const token = await makeHttpRequest(  
      'http://' + this.srs.url + '/terraform/v1/mgmt/secret/token',  
      {  
        method: 'POST',  
        dataType: 'json',  
        contentType: 'json',  
        data: {  
          apiSecret: this.srs.apiSecret,  
        },  
      }  
    );  
    // 使用 token 获取 secret   
    const srsSecret = await makeHttpRequest(  
      'http://' + this.srs.url + '/terraform/v1/hooks/srs/secret/query',  
      {  
        method: 'POST',  
        dataType: 'json',  
        contentType: 'json',  
        data: {  
          token: token.data.data.token,  
        },  
      }  
    );  
    return {  
      url: 'rtmp://' + this.srs.url + '/live/',  
      key,  
      secret: srsSecret.data.data.publish,  
    };  
  }
}
复制代码

主播每次获取串流密钥会进行重置,防止泄露。

获取直播间信息

获取直播间信息相对简单,只需要查询数据返回即可

@Controller('/live')  
export class LiveController {  
  @Inject()  
  ctx: Context;  
  @Inject()  
  roomService: RoomService;  
  // 获取直播间相关数据  
  @Get('/room/:roomId')  
  async getRoomById(@Param('roomId') room: string) {  
    const res: any = await this.roomService.getRoomById(room);  
    if (!res) {  
      throw new CustomError(ROOM_NOT_FOUND.CODE, ROOM_NOT_FOUND.MSG);  
    }  
    // 粉丝数量取值  
    res.fans = res.fans.length;  
    return res;  
  }
}
复制代码


xgplayer(西瓜播放器)


播放器我当初对比过 MuiPlayer 和 xgPlayer,最终选择了西瓜(背靠大厂、集成度更高)。 我们使用 http-flv 的形式来进行推拉流,所以我们需要同时安装 xgplayer 和 xgplayer-flv

$ pnpm add xgplayer xgplayer-flv
复制代码

前端框架层面我使用了 Vue3,代码如下(只是播放器相关部分,不是最终成品的代码)

<template>
  <div class="room-video" id="mse"></div>
</template>
<script setup lang="ts">
import "xgplayer";
import FlvPlayer from "xgplayer-flv";
// 播放器
const playerRef = ref<FlvPlayer>();
onMounted(async () => {
  room.info = await getRoomInfo(props.roomId);
  if (room.info.isLiving) {
    initPlayer();
  }
});
// 初始化播放器
function initPlayer() {
  if (playerRef.value) {
    playerRef.value.destroy();
  }
  playerRef.value = new FlvPlayer({
    id: "mse", // 容器元素 ID
    url: import.meta.env.VITE_VIDEO_URL + room.info.streamKey + ".flv", // 拉流地址
    isLive: true, // 直播模式
    autoplay: true, // 自动播放
    height: 500, // 高
    width: 888, // 宽
    pip: true, // 画中画
    lang: "zh-cn",
    ignores: ["replay"], // 忽略内置控件
    danmu: {
      // danmu 配置
      comments: [],
    },
  });
}
// socket 收到消息之后通过 player 实例调用 instace.danmu.sendComment 即可动态添加弹幕
</script>
复制代码


成品展示


主播面板获取推流码,复制到 OBS 中开始推流

1682517483(1).png

观众进入直播间获取直播流进行播放

1682517501(1).png



相关文章
|
28天前
|
编解码 开发工具 Android开发
Android平台RTMP直播推送模块技术接入说明
大牛直播SDK跨平台RTMP直播推送模块,始于2015年,支持Windows、Linux(x64_64架构|aarch64)、Android、iOS平台,支持采集推送摄像头、屏幕、麦克风、扬声器、编码前、编码后数据对接,功能强大,性能优异,配合大牛直播SDK的SmartPlayer播放器,轻松实现毫秒级的延迟体验,满足大多数行业的使用场景。RTMP直播推送模块数据源,支持编码前、编码后数据对接
|
Web App开发 数据采集 物联网
Android平台基于RTMP或RTSP的一对一音视频互动技术方案探讨
随着智能门禁等物联网产品的普及,越来越多的开发者对音视频互动体验提出了更高的要求。目前市面上大多一对一互动都是基于WebRTC,优点不再赘述,我们这里先说说可能需要面临的问题:WebRTC的服务器部署非常复杂,可以私有部署,但是非常复杂。传输基于UDP,很难保证传输质量,由于UDP是不可靠的传输协议,在复杂的公网网络环境下,各种突发流量、偶尔的传输错误、网络抖动、超时等等都会引起丢包异常,都会在一定程度上影响音视频通信的质量,难以应对复杂的互联网环境,如跨区跨运营商、低带宽、高丢包等场景,行话说的好:从demo到实用,中间还差1万个WebRTC。
130 0
|
存储 Kubernetes 应用服务中间件
当SRS遇到K8s:快速构建高并发直播集群
流媒体服务和流媒体服务器的关键差异是什么?高效的运维能力是其中极其关键的差异之一,云计算 +Docker+K8s 让开源项目也能拥有这种能力,让每个人都能具备互联网流媒体服务能力,正如:旧时王谢堂前燕,飞入寻常百姓家!
1170 0
当SRS遇到K8s:快速构建高并发直播集群
|
1月前
|
缓存 视频直播 Linux
FFmpeg开发笔记(四十三)使用SRS开启SRT协议的视频直播服务
《FFmpeg开发实战》书中介绍了轻量级流媒体服务器MediaMTX,适合测试但不适用于生产环境。SRS是一款国产开源服务器,支持RTMP、SRT等协议,适合生产使用。要启用SRS的SRT推流,需配置`srt.conf`,开启SRT服务并配置端口。在确保FFmpeg集成libsrt后,拉流则使用类似但带有`m=request`的地址。在Windows上,同样需要集成libsrt的FFmpeg来使用ffplay拉流。SRS的日志确认了推拉流的成功。书中提供更深入的FFmpeg开发知识。
73 2
FFmpeg开发笔记(四十三)使用SRS开启SRT协议的视频直播服务
|
1月前
|
视频直播 Linux Windows
FFmpeg开发笔记(四十二)使用ZLMediaKit开启SRT视频直播服务
《FFmpeg开发实战》书中介绍了使用MediaMTX测试RTSP/RTMP,但该工具简单,不适合生产环境。ZLMediaKit,一个支持RTSP/RTMP/SRT的国产流媒体服务器,是更好的选择。要通过ZLMediaKit和FFmpeg实现SRT推流,需确保FFmpeg已集成libsrt。ZLMediaKit默认配置文件中,SRT监听9000端口。日志显示推流和拉流成功。ZLMediaKit支持多种音视频编码,如H264、AAC等。要了解更多FFmpeg开发信息,可参考该书。
51 0
FFmpeg开发笔记(四十二)使用ZLMediaKit开启SRT视频直播服务
|
2月前
|
域名解析 监控 CDN
搭建SRS直播服务器
搭建SRS直播服务器涉及下载安装包,解压后运行`./INSTALL`安装。配置`srs.conf`文件调整服务器参数,如端口和带宽。使用OBS等工具推流,VLC等播放器或浏览器拉流。配置域名解析和CDN以优化访问。监控服务器状态并进行调优确保稳定性。参照官方文档和社区资源可获取详细指导。祝搭建成功!
94 8
|
4月前
|
Web App开发 移动开发 前端开发
web端实现rtsp实时推流视频播放可行性方案
总之,要在Web端实现RTSP实时推流视频播放,需要使用适当的前端技术(如HTML5 Video或WebRTC),以及媒体服务器或流转换器来处理RTSP流。这需要一些开发和配置工作,但是可以实现实时视频流的播放。具体的实现方案可能会根据您的需求和技术栈而有所不同,所以需要仔细评估和选择适合您的解决方案。
352 0
|
缓存 监控 算法
开发个好的RTMP播放器到底难在哪里?RTMP播放器对标和考察指标
好多开发者提到,RTMP播放器,不知道有哪些对标和考察指标,以下大概聊聊我们的一点经验,感兴趣的,可以关注 github: 1. 低延迟:大多数RTMP的播放都面向直播场景,如果延迟过大,严重影响体验,所以,低延迟是衡量一个好的RTMP播放器非常重要的指标,目前大牛直播SDK的RTMP直播播放延迟比开源播放器更优异(大牛直播SDK延迟在1秒左右,开源播放器如VLC,延迟在5-7秒),而且长时间运行下,大牛直播SDK播放端不会造成延迟累积,开源或第三方播放器,长时间运行,容易产生延迟累积;
158 0
|
弹性计算 移动开发 Ubuntu
阿里云上搭建HLS直播服务器
通过将摄像头的rtmp视频流推送到服务器,转换成HLS(HTTP Live Streaming)格式,用户可以通过H5浏览器直接打开直播视频。
764 0
|
编解码 移动开发 小程序
视频直播技术干货:一文读懂主流视频直播系统的推拉流架构、传输协议等
本文将通过介绍实时视频直播技术体系,包括常用的推拉流架构、传输协议等,让你对现今主流的视频直播技术有一个基本的认知。
421 1
视频直播技术干货:一文读懂主流视频直播系统的推拉流架构、传输协议等