在vue中使用zego实现拉流

最近项目有个需求,想实时观看音视频功能
大概逻辑是设备端推流,web端拉流
我们是找个第三方的服务—zego,利用他的实时音视频功能来实现这个需求
大概逻辑是设备端和web端都去服务端获取zego的token然后加入房间,然后设备端推流,web端拉流

一,首先,引入zego的包

npm i zego-express-engine-webrtc --save

或者

cnpm i zego-express-engine-webrtc --save

二,在页面中引入

import { ZegoExpressEngine } from "zego-express-engine-webrtc";

三,在页面中给一个容器,设置宽高

<div id="remote-video" style="max-width: 90%; max-height: 90%"></div>

四,在页面中渲染

想要拉流时,首先获取zego的token信息

//获取视频流token
    getStreamToken() {
      getStreamToken({
        uuid: this.uuid,
      }).then((res) => {
        this.streamQuery = res.data;
        //这里是利用websocket像服务器发请求推流指令的,大家根据实际业务情况来
        console.log("发送推流指令");
        this.websocket.send(JSON.stringify(startStreaming));
      });
    },

然后收到服务端返回的已经开始推流的信息后,拿着刚才服务端返回的token等信息初始化实例和登录房间

然后利用zego提供的监听房间流回调和广播消息回调去拉流或者停止拉流,退出房间

//web开始拉流
      else if (data.code === 8027) {
        this.$message.success("正在获取视频资源");
        // 项目唯一标识 AppID,Number 类型,请从 ZEGO 控制台获取
        let appID = this.streamQuery.appId;
        // 接入服务器地址 Server,String 类型,请从 ZEGO 控制台获取
        let server = this.streamQuery.server;

        let userID = this.$ls.get("userInfo").id + "-" + this.uuid;
        let roomID = this.videoItem.serialNum;
        let token = this.streamQuery.token;

        if (this.zg == null) {
          // 初始化实例
          this.zg = new ZegoExpressEngine(appID, server);
          //登录房间
          this.zg
            .loginRoom(
              roomID,
              token,
              { userID, userName: this.channelQueryParams.channel },
              { userUpdate: true }
            )
            .then((result) => {
              if (result == true) {
                console.log("login success");
              }
            });

          //zego token过期处理
          this.zg.on("tokenWillExpire", (roomID) => {
            // 重新请求开发者服务端获取 Token
            getStreamToken({
              uid: this.$ls.get("userInfo").id + "-" + this.uuid,
            }).then((res) => {
              this.streamQuery = res.data;
              this.zg.renewToken(this.streamQuery.token);
            });
          });

          // 流状态更新回调
          this.zg.on(
            "roomStreamUpdate",
            async (roomID, updateType, streamList, extendedData) => {
              //当updateType为ADD时,代表有音视频流新增,此时可以调用startPlayingStream接口拉取播放该音视频流
              if (updateType == "ADD") {
                //流新增
                console.log("流增加");
                //this.streamIdList加入新的流
                streamList.forEach((r) => {
                  this.streamIdList.push(r.streamID);
                });
                //这里为了使示例代码更加简洁,我们只拉取新增的音视频流列表中第的第一条流,在实际的业务中,建议开发者循环遍历 streamList ,拉取每一条音视频流
                this.startPlayingStream();
              }
              // 流删除,停止拉流
              else if (updateType == "DELETE") {
                // 流删除,通过流删除列表 streamList 中每个流的 streamID 进行停止拉流。
                // const streamID = streamList[0].streamID;
                streamList.forEach((element) => {
                  if (
                    element.streamID ===
                    roomID + "-" + this.channelQueryParams.channel
                  ) {
                    this.zg.stopPlayingStream(element.streamID);
                    this.streamIdList.splice(
                      this.streamIdList.indexOf(element.streamID),
                      1
                    );
                  }
                });
              }
            }
          );

          //收到广播消息的通知
          this.zg.on("IMRecvBroadcastMessage", (roomID, chatData) => {
            console.log("广播消息IMRecvBroadcastMessage", roomID, chatData);
            let message = JSON.parse(chatData[0].message);
            //切换流
            if (message.msgType === 0) {
              message.data.forEach(async (r) => {
                //可以拉流
                if (
                  this.streamIdList.includes(
                    roomID + "-" + this.channelQueryParams.channel
                  ) &&
                  r.channel === this.channelQueryParams.channel &&
                  r.status != 0
                ) {
                  console.log("可以拉流");
                  this.startPlayingStream();
                } else if (
                  r.channel === this.channelQueryParams.channel &&
                  r.status == 0
                ) {
                  this.$message.error(r.msg);
                }
              });
            }
            //设备在被互动占用
            else if (message.msgType === 1) {
              if (this.zg != null && this.streamID != null) {
                //停止拉流
                this.zg.stopPlayingStream(this.streamID);
                //退出房间
                this.zg.logoutRoom(roomID);
                this.streamID = null;
              }
              this.zg = null;
              this.occupied = true;
            }
          });
        }
      }
//开始拉流
    async startPlayingStream() {
      let roomID = this.videoItem.serialNum;
      for (let i = 0; i < this.streamIdList.length; i++) {
        if (this.streamIdList[i] === roomID + "-" + this.channelQueryParams.channel) {
          this.streamID = this.streamIdList[i];
          // streamList中有对应流的 streamID
          const remoteStream = await this.zg.startPlayingStream(this.streamID);
          // 创建媒体流播放组件对象,用于播放远端媒体流 。
          const remoteView = this.zg.createRemoteStreamView(remoteStream);
          document.getElementById("remote-video").innerHTML = "";
          // 将播放组件挂载到页面,"remote-video" 为组件容器 DOM 元素的 id 。
          remoteView.play("remote-video");
          break;
        }
      }
    },

写的有点潦草,如果有疑问,欢迎私信或留言评论

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值