在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信息
//获取视频流tokengetStreamToken() {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) => {// 重新请求开发者服务端获取 TokengetStreamToken({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中有对应流的 streamIDconst 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;}}},
写的有点潦草,如果有疑问,欢迎私信或留言评论
本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!
