|
|
@@ -1,41 +1,48 @@
|
|
|
<template>
|
|
|
<view class="video_box" :style="'height:' + phoneHeight + 'px'">
|
|
|
<!-- 本地预览视图 -->
|
|
|
- <view class="video_me">
|
|
|
- <zego-local-view :viewMode="publisherViewModeIndex"
|
|
|
- style="width: 100%; flex: 1; border: 1px solid #0000; z-index: 20">
|
|
|
+ <view class="video_me" v-show="allUserViewObjectList.length > 0">
|
|
|
+ <zego-local-view v-show="videoShow" :viewMode="publisherViewModeIndex"
|
|
|
+ style="width: 600px; height: 400px; flex: 1; margin: 0 auto;">
|
|
|
</zego-local-view>
|
|
|
</view>
|
|
|
|
|
|
<!-- 服务器传来的预览图 -->
|
|
|
- <view class="video_you">
|
|
|
- <zego-remote-view :viewMode="publisherViewModeIndex"
|
|
|
- style="height: 403.84rpx;flex: 1; border: 1px solid #0000;">
|
|
|
+ <view class="video_you" v-for="(item, index) in allUserViewObjectList" :key="item.streamID">
|
|
|
+ <!-- <view class="video_you"> -->
|
|
|
+ <zego-remote-view v-if="item.streamID" :streamID="item.streamID" :viewMode="item.viewMode"
|
|
|
+ style="width: 600px; height: 400px; flex: 1;">
|
|
|
</zego-remote-view>
|
|
|
</view>
|
|
|
|
|
|
<view class="video_btn">
|
|
|
<view class="video_imgList">
|
|
|
<view class="video_imgList1">
|
|
|
- <view class="video_view">
|
|
|
- <image src="../../static/image/9.png" mode=""></image>
|
|
|
+ <view class="video_view" @click="turn">
|
|
|
+ <image class="video_view_img" src="../../static/image/9.png" mode=""></image>
|
|
|
</view>
|
|
|
- <view class="">翻转镜头</view>
|
|
|
+ <text class="video_view_txt">翻转镜头</text>
|
|
|
</view>
|
|
|
- <view class="video_imgList2">
|
|
|
- <view class="video_view">
|
|
|
- <image src="../../static/image/8.png" mode=""></image>
|
|
|
+ <view class="video_imgList2" v-if="CameraShow">
|
|
|
+ <view class="video_view" @click="closeCamera">
|
|
|
+ <image class="video_view_img" src="../../static/image/11.png" mode=""></image>
|
|
|
</view>
|
|
|
- <view class="">切换语音通话</view>
|
|
|
+ <text class="video_view_txt" style="margin: 0 0 0 30rpx;">静音</text>
|
|
|
+ </view>
|
|
|
+
|
|
|
+ <view class="video_imgList2" v-else>
|
|
|
+ <view class="video_view" @click="openCamera">
|
|
|
+ <image class="video_view_img" src="../../static/image/12.png" mode=""></image>
|
|
|
+ </view>
|
|
|
+ <text class="video_view_txt" style="margin: 0 0 0 30rpx;">开启</text>
|
|
|
</view>
|
|
|
</view>
|
|
|
|
|
|
- <u-button type="error" @click="offVideo()" style="margin: 0 auto; border-radius: 50px; width: 50px; height: 50px;" size="mini" text="关闭">
|
|
|
- </u-button>
|
|
|
+ <image @click="offVideo()" style="width: 50px; height: 50px; margin: 0 0 0 330rpx;"
|
|
|
+ src="../../static/image/10.png" mode=""></image>
|
|
|
</view>
|
|
|
-
|
|
|
+
|
|
|
<!-- 消息提醒 -->
|
|
|
- <!-- <u-toast ref="uToast" type="typeVide" :message="videoMsg"></u-toast> -->
|
|
|
<u-toast ref="uToast"></u-toast>
|
|
|
</view>
|
|
|
</template>
|
|
|
@@ -59,24 +66,42 @@
|
|
|
data() {
|
|
|
return {
|
|
|
phoneHeight: '', // 获取当前的屏幕高度
|
|
|
-
|
|
|
+
|
|
|
// 即构
|
|
|
publisherViewModeIndex: 0, // 本地预览图
|
|
|
+ viewModeA: 0, // 服务器预览图
|
|
|
+ serveViewModeIndex: "", // 服务器拉流预览图
|
|
|
engine: undefined,
|
|
|
videoObj: null,
|
|
|
userid: "Uni" + Math.floor(Math.random() * 1000000).toString(),
|
|
|
isPublishingStream: false,
|
|
|
-
|
|
|
- // 消息提醒
|
|
|
- // typeVide: '',
|
|
|
- // videoMsg: "",
|
|
|
+ shotShow: false, // 翻转镜头
|
|
|
+ videoShow: false, // 切换视频显示
|
|
|
+
|
|
|
+ allStreamList: [],
|
|
|
+ allUserViewObjectList: [],
|
|
|
+
|
|
|
+ CameraShow: true, // 镜头开启关闭
|
|
|
}
|
|
|
},
|
|
|
components: {
|
|
|
ZegoLocalView: ZegoLocalView,
|
|
|
ZegoRemoteView: ZegoRemoteView
|
|
|
},
|
|
|
-
|
|
|
+
|
|
|
+ watch: {
|
|
|
+ allUserViewObjectList(val) {
|
|
|
+ if (val.length > 0) {
|
|
|
+ val.forEach((item) => {
|
|
|
+ if (item.streamID) {
|
|
|
+ this.tensile(item)
|
|
|
+ return true
|
|
|
+ }
|
|
|
+ })
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+
|
|
|
methods: {
|
|
|
// 即构 - 视频通话 初始化
|
|
|
async setup() {
|
|
|
@@ -88,7 +113,7 @@
|
|
|
scenario: ZegoScenario.General
|
|
|
}
|
|
|
this.engine = await ZegoExpressEngine.createEngineWithProfile(profile);
|
|
|
- this.engine.useFrontCamera(false); // 设置前后摄像头
|
|
|
+ this.engine.useFrontCamera(this.shotShow); // 设置前后摄像头
|
|
|
// console.log(this.engine)
|
|
|
this.addListeners();
|
|
|
// console.log('>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>' + that.videoObj.room_id)
|
|
|
@@ -99,89 +124,227 @@
|
|
|
isUserStatusNotify: true
|
|
|
});
|
|
|
},
|
|
|
-
|
|
|
+
|
|
|
+ // 即构 - 翻转镜头
|
|
|
+ turn() {
|
|
|
+ this.shotShow = !this.shotShow
|
|
|
+ this.engine.useFrontCamera(this.shotShow)
|
|
|
+ },
|
|
|
+
|
|
|
+ // 即构 - 关闭镜头 - 停止拉流 、推流
|
|
|
+ closeCamera() {
|
|
|
+ console.log('关闭摄像头')
|
|
|
+ this.allStreamList.forEach((item) => {
|
|
|
+ // this.notTensile(item.streamID); // 停止拉流
|
|
|
+ item.muteAudio = !item.muteAudio;
|
|
|
+ this.engine.mutePlayStreamAudio(item.streamID, item.muteAudio);
|
|
|
+ })
|
|
|
+ // // 停止推流
|
|
|
+ // this.engine.stopPreview();
|
|
|
+ // this.engine.stopPublishingStream();
|
|
|
+ this.CameraShow = false
|
|
|
+ },
|
|
|
+ // 即构 - 开启镜头 - 开启拉流、推流
|
|
|
+ openCamera() {
|
|
|
+ console.log('开启摄像头')
|
|
|
+ this.allStreamList.forEach((item) => {
|
|
|
+ // this.engine.startPlayingStream(item.streamID); // 开始拉流
|
|
|
+ item.muteAudio = !item.muteAudio;
|
|
|
+ this.engine.mutePlayStreamAudio(item.streamID, item.muteAudio);
|
|
|
+ })
|
|
|
+ // // 开始推流
|
|
|
+ // this.engine.startPreview();
|
|
|
+ // this.engine.startPublishingStream(this.videoObj.room_id);
|
|
|
+ this.CameraShow = true
|
|
|
+ },
|
|
|
+
|
|
|
+ // 切换视频显示
|
|
|
+ changeShow() {
|
|
|
+ this.videoShow = !this.videoShow
|
|
|
+ // this.onPublish()
|
|
|
+ this.engine.startPreview();
|
|
|
+ this.engine.startPublishingStream(this.videoObj.room_id);
|
|
|
+ this.publishBtnName = "Stop Publishing";
|
|
|
+ console.log(this.videoShow)
|
|
|
+ },
|
|
|
+
|
|
|
// 即构 - 视频通话 监听房间
|
|
|
addListeners() {
|
|
|
+ console.log('开始监听房间了啊')
|
|
|
+ // console.log(this.allStreamList, '------------------')
|
|
|
+
|
|
|
// 房间状态变化通知
|
|
|
this.engine.on("roomStateUpdate", (roomID, state, errorCode, extendedData) => {
|
|
|
- console.log('房间状态变化')
|
|
|
+ // console.log('房间状态变化')
|
|
|
+ if (state == "CONNECTED") {
|
|
|
+ // 与房间连接成功,只有当房间状态是连接成功时,才能进行推流、拉流等操作。
|
|
|
+ // 接下来的“预览并推流”的代码写在这里
|
|
|
+ console.log("房间连接成功");
|
|
|
+ }
|
|
|
+ if (state == "DISCONNECTED") {
|
|
|
+ // 与房间断开了连接
|
|
|
+ console.log("与房间断开连接");
|
|
|
+ }
|
|
|
+
|
|
|
+ if (state == "CONNECTING") {
|
|
|
+ // 与房间尝试连接中
|
|
|
+ console.log("与房间尝试连接中");
|
|
|
+ }
|
|
|
});
|
|
|
-
|
|
|
+
|
|
|
// 房间用户变化通知
|
|
|
this.engine.on("roomUserUpdate", (roomID, updateType, userList) => {
|
|
|
- console.log('房间用户变化通知')
|
|
|
console.log(updateType)
|
|
|
console.log(userList)
|
|
|
+ console.log("有其他用户进出房间");
|
|
|
+ if (updateType == ZegoUpdateType.Add) {
|
|
|
+ console.log('进入了啊AAAAAAAAAA')
|
|
|
+ for (let user of userList) {
|
|
|
+ for (let stream of this.allStreamList) {
|
|
|
+ if (user.userID == stream.user.userID) {
|
|
|
+ user.streamID = stream.streamID;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ this.allUserViewObjectList.push(user);
|
|
|
+ }
|
|
|
+ } else if (updateType == ZegoUpdateType.Delete) {
|
|
|
+ this.allUserViewObjectList = this.allUserViewObjectList.filter((object) => {
|
|
|
+ for (let user of userList) {
|
|
|
+ if (user.userID == object.userID) {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return true;
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ if (updateType == "1") {
|
|
|
+ // 有其他用户退出房间
|
|
|
+ this.offVideo()
|
|
|
+ }
|
|
|
});
|
|
|
-
|
|
|
+
|
|
|
// 房间内其他用户推的流变化通知
|
|
|
this.engine.on("roomStreamUpdate", (roomID, updateType, streamList) => {
|
|
|
- console.log('房间内其他用户推的流变化通知')
|
|
|
- });
|
|
|
-
|
|
|
- // 房间内在线用户数量回调
|
|
|
- this.engine.on("roomOnlineUserCountUpdate", (roomID, count) => {
|
|
|
- console.log(roomID)
|
|
|
- console.log(count)
|
|
|
- console.log('>?>>>>>>>>>>>>>>>>>>>>>>>在线用户有变化')
|
|
|
+ // if (updateType == "0") {
|
|
|
+ // // 流新增,开始拉流
|
|
|
+ // this.tensile(streamList[0].streamID)
|
|
|
+ // } else if (updateType == "1") {
|
|
|
+ // // 流删除,停止拉流
|
|
|
+ // this.notTensile(streamList[0].streamID);
|
|
|
+ // }
|
|
|
+ console.log('进入了啊BBBBBBBBBBBBBBBBBBBBBBB')
|
|
|
+ console.log('---------updateType-----------', updateType)
|
|
|
+ console.log('---------streamList-----------', streamList)
|
|
|
+ console.log('---------ZegoUpdateType-----------', ZegoUpdateType)
|
|
|
+ console.log('---------ZegoUpdateType.Add-----------', ZegoUpdateType.Add)
|
|
|
+ console.log('---------ZegoUpdateType.Delete-----------', ZegoUpdateType.Delete)
|
|
|
+ console.log('---------allUserViewObjectList-----------', this.allUserViewObjectList)
|
|
|
+
|
|
|
+ if (updateType == ZegoUpdateType.Add) {
|
|
|
+ for (let object of this.allUserViewObjectList) {
|
|
|
+ for (let stream of streamList) {
|
|
|
+ if (object.userID == stream.user.userID) {
|
|
|
+ object.streamID = stream.streamID;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ this.allStreamList = this.allStreamList.concat(streamList);
|
|
|
+ console.log(this.allStreamList, '-------------')
|
|
|
+ } else if (updateType == ZegoUpdateType.Delete) {
|
|
|
+ for (let object of this.allUserViewObjectList) {
|
|
|
+ for (let stream of streamList) {
|
|
|
+ if (object.streamID == stream.streamID) {
|
|
|
+ object.streamID = undefined;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ this.allStreamList = this.allStreamList.filter((object) => {
|
|
|
+ for (let stream of streamList) {
|
|
|
+ if (object.streamID == stream.streamID) {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return true;
|
|
|
+ });
|
|
|
+ }
|
|
|
});
|
|
|
-
|
|
|
+
|
|
|
// 拉流质量回调
|
|
|
this.engine.on("playerQualityUpdate", (streamID, quality) => {
|
|
|
console.log('拉流质量回调')
|
|
|
});
|
|
|
-
|
|
|
- // 推流质量回调
|
|
|
- this.engine.on("publisherQualityUpdate", (streamID, quality) => {
|
|
|
- console.log('推流质量回调')
|
|
|
- });
|
|
|
-
|
|
|
- // 采集视频大小变更回调
|
|
|
- this.engine.on("publisherVideoSizeChanged", (width, height, channel) => {
|
|
|
- console.log('采集视频大小变更回调')
|
|
|
- });
|
|
|
-
|
|
|
- // 拉流分辨率变更通知
|
|
|
- this.engine.on("playerVideoSizeChanged", (streamID, width, height) => {
|
|
|
- console.log('拉流分辨率变更通知')
|
|
|
- });
|
|
|
+
|
|
|
+ // 拉流后的事件回调
|
|
|
+ this.engine.on("playerStateUpdate", (streamID, state, errorCode, extendedData) => {
|
|
|
+ console.log('>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>' + '拉流后的事件触发了')
|
|
|
+ })
|
|
|
+ },
|
|
|
+
|
|
|
+ tensile(item) {
|
|
|
+ console.log(this.allStreamList)
|
|
|
+ console.log(item)
|
|
|
+ console.log(this.allUserViewObjectList)
|
|
|
+ this.engine.startPlayingStream(item.streamID)
|
|
|
},
|
|
|
-
|
|
|
+
|
|
|
+ // 停止拉流
|
|
|
+ notTensile(roomId) {
|
|
|
+ this.serveViewModeIndex = roomId
|
|
|
+ this.engine.stopPlayingStream(roomId)
|
|
|
+ },
|
|
|
+
|
|
|
// 推流 - 展示视图 - 本地视频流
|
|
|
onPublish() {
|
|
|
- // 设置视频配置
|
|
|
- ZegoExpressEngine.instance().setVideoConfig(this.videoObj.room_id);
|
|
|
-
|
|
|
if (this.isPublishingStream) {
|
|
|
+ // 停止推流
|
|
|
this.engine.stopPreview();
|
|
|
this.engine.stopPublishingStream();
|
|
|
- this.publishBtnName = "Start Publishing";
|
|
|
} else {
|
|
|
+ console.log('开始推流了啊', this.isPublishingStream)
|
|
|
+ // 开始推流
|
|
|
this.engine.startPreview();
|
|
|
this.engine.startPublishingStream(this.videoObj.room_id);
|
|
|
- this.publishBtnName = "Stop Publishing";
|
|
|
+ this.videoShow = true
|
|
|
}
|
|
|
this.isPublishingStream = !this.isPublishingStream;
|
|
|
},
|
|
|
-
|
|
|
+
|
|
|
// 挂断退出
|
|
|
- offVideo() {
|
|
|
- this.engine.logoutRoom(this.videoObj.room_id)
|
|
|
- this.$refs.uToast.show({
|
|
|
+ async offVideo() {
|
|
|
+ console.log('进入了啊')
|
|
|
+ var that = this
|
|
|
+ that.engine.logoutRoom(that.videoObj.room_id); // 退出房间
|
|
|
+ that.$refs.uToast.show({
|
|
|
type: 'default',
|
|
|
message: '结束视频通话!',
|
|
|
- url: '/pages/response/index',
|
|
|
})
|
|
|
- // uni.navigateTo({
|
|
|
+ setTimeout(() => {
|
|
|
+ that.videoShow = true
|
|
|
+ that.allStreamList = [];
|
|
|
+ that.allUserViewObjectList = [];
|
|
|
+ uni.navigateBack({
|
|
|
+ delta: 1
|
|
|
+ })
|
|
|
+ }, 1500)
|
|
|
+ // uni.redirectTo({
|
|
|
// url: "/pages/response/index"
|
|
|
// })
|
|
|
+
|
|
|
+ },
|
|
|
+
|
|
|
+
|
|
|
+ // 删除this.engine对象, 删除即构
|
|
|
+ async destroyEngine() {
|
|
|
+ this.engine = undefined;
|
|
|
+ ZegoExpressEngine.destroyEngine();
|
|
|
},
|
|
|
},
|
|
|
|
|
|
async onLoad(optinos) {
|
|
|
var that = this
|
|
|
- // that.videoObj = JSON.parse(optinos.videoObj)
|
|
|
- // console.log(that.videoObj)
|
|
|
+ that.videoObj = JSON.parse(optinos.videoObj)
|
|
|
+ console.log(that.videoObj)
|
|
|
// 即构 - 视频通话
|
|
|
// 获取系统信息同步接口
|
|
|
if (uni.getSystemInfoSync().platform === 'android') {
|
|
|
@@ -197,112 +360,110 @@
|
|
|
}
|
|
|
});
|
|
|
},
|
|
|
-
|
|
|
+ async onShow() {
|
|
|
+ // await this.setup();
|
|
|
+ },
|
|
|
+
|
|
|
// 监听页面返回
|
|
|
onBackPress() {
|
|
|
console.log('返回了!')
|
|
|
+ this.offVideo(); // 挂断退出
|
|
|
+ this.destroyEngine(); // 删除this.engine对象,删除即构
|
|
|
+ },
|
|
|
+
|
|
|
+ // 页面卸载 - 生命周期
|
|
|
+ onUnload() {
|
|
|
+ this.destroyEngine();
|
|
|
+ console.log('onUnload');
|
|
|
},
|
|
|
}
|
|
|
</script>
|
|
|
|
|
|
-<style lang="scss" scoped>
|
|
|
+<style lang="scss">
|
|
|
.video_box {
|
|
|
- // height: 1667px;
|
|
|
- // border: 1px solid red;
|
|
|
- // 视频通话
|
|
|
- .video_you {
|
|
|
- background: #fff;
|
|
|
- position: relative;
|
|
|
- // border: 1px solid #000;
|
|
|
- width: 400px;
|
|
|
- height: 840px;
|
|
|
- overflow: hidden;
|
|
|
- }
|
|
|
+ background: #000;
|
|
|
+ width: 1200rpx;
|
|
|
+ position: relative;
|
|
|
|
|
|
+ // .video_you {
|
|
|
.video_me {
|
|
|
- // border: 1px solid #000;
|
|
|
+ // background: #f00;
|
|
|
+ width: 600px;
|
|
|
+ height: 400px;
|
|
|
+ position: absolute;
|
|
|
+ right: 100rpx;
|
|
|
+ top: 400px;
|
|
|
+ flex: 1;
|
|
|
+ // overflow: hidden;
|
|
|
+ // z-index: 210;
|
|
|
+ }
|
|
|
+
|
|
|
+ .video_you {
|
|
|
// z-index: 100;
|
|
|
- background: #fff;
|
|
|
- // width: 200rpx;
|
|
|
- // height: 300rpx;
|
|
|
- width: 200px;
|
|
|
- height: 300px;
|
|
|
+ // background: #ff0;
|
|
|
+ width: 600px;
|
|
|
+ height: 400px;
|
|
|
position: absolute;
|
|
|
- right: 10px;
|
|
|
- top: 10px;
|
|
|
+ right: 100rpx;
|
|
|
+ top: 0;
|
|
|
}
|
|
|
|
|
|
.video_btn {
|
|
|
- border: 1px solid #fff;
|
|
|
position: absolute;
|
|
|
bottom: 35rpx;
|
|
|
left: 0;
|
|
|
- // width: 100%;
|
|
|
- width: 400px;
|
|
|
+ width: 750rpx;
|
|
|
|
|
|
.video_imgList {
|
|
|
- // display: flex;
|
|
|
- // justify-content: space-evenly;
|
|
|
- /* #ifndef APP-NVUE */
|
|
|
display: flex;
|
|
|
flex-direction: row;
|
|
|
- justify-content: space-evenly;
|
|
|
- //建议:在用到该属性或者你觉得可以不加时不管水平还是垂直,均最好加上,方便后期编译到不同平台减少后期修改布局样式造成的差异
|
|
|
-
|
|
|
+ justify-content: space-around;
|
|
|
|
|
|
+ // 翻转
|
|
|
.video_imgList1 {
|
|
|
-
|
|
|
- // border: 1px solid;
|
|
|
- // background: rgba(0, 0, 0, .5);
|
|
|
.video_view {
|
|
|
background: rgba(0, 0, 0, .5);
|
|
|
- border: 1px solid;
|
|
|
border-radius: 50px;
|
|
|
width: 50px;
|
|
|
height: 50px;
|
|
|
margin: 0 auto;
|
|
|
|
|
|
- image {
|
|
|
- // width: 50rpx;
|
|
|
- // height: 50rpx;
|
|
|
- height: 30px;
|
|
|
- width: 30px;
|
|
|
+ .video_view_img {
|
|
|
+ height: 25px;
|
|
|
+ width: 25px;
|
|
|
margin: 24rpx 0 0 25rpx;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- view {
|
|
|
- line-height: 30px;
|
|
|
+ .video_view_txt {
|
|
|
color: #fff;
|
|
|
- font-size: 20rpx;
|
|
|
+ font-size: 14px;
|
|
|
+ line-height: 30px;
|
|
|
+ text-align: center;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ // 语音通话
|
|
|
.video_imgList2 {
|
|
|
-
|
|
|
- // border: 1px solid;
|
|
|
- // background: rgba(0, 0, 0, .5);
|
|
|
.video_view {
|
|
|
- border: 1px solid;
|
|
|
background: rgba(0, 0, 0, .5);
|
|
|
- margin: 0 auto;
|
|
|
border-radius: 50px;
|
|
|
width: 50px;
|
|
|
height: 50px;
|
|
|
+ margin: 0 0 0 30rpx;
|
|
|
|
|
|
- image {
|
|
|
- // width: 50rpx;
|
|
|
- // height: 50rpx;
|
|
|
- width: 50px;
|
|
|
- height: 50px;
|
|
|
+ .video_view_img {
|
|
|
+ height: 25px;
|
|
|
+ width: 25px;
|
|
|
margin: 24rpx 0 0 25rpx;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- view {
|
|
|
- line-height: 30px;
|
|
|
+ .video_view_txt {
|
|
|
color: #fff;
|
|
|
- font-size: 20rpx;
|
|
|
+ font-size: 14px;
|
|
|
+ line-height: 30px;
|
|
|
+ text-align: center;
|
|
|
}
|
|
|
}
|
|
|
}
|