大小窗口画面切换
更新时间: 2024/09/18 16:26:13
移动 App 中 1 对 1 业务场景相应的音视频通话窗口的展现形式有两种,一种是 大屏幕视频(大窗口),一种是 悬浮窗视频(小窗口)。
用户如果有需求,大屏幕视频和悬浮窗视频允许切换,可通过以下示例代码实现。
<!-- 固定大窗口 -->
<view class="nertc-video-area" :style="nertcRemoteViewStyle+'margin-top:-0rpx'">
<view class="nertc-video-view" :style="nertcRemoteViewStyle" v-for="(item, index) in outterVideoList"
:key="isShowUserScreenVideo ? item.key : item">
<nertc-remote-view :style="nertcRemoteViewStyle" v-if="item" :mediaType="outterMediaType"
:userID="isShowUserScreenVideo ? item.viewID : item"
:viewID="isShowUserScreenVideo ? item.viewID : item">
</nertc-remote-view>
</view>
</view>
<!-- 悬浮窗 -->
<wrs-uts-floatPicInPicContainer v-if="floatWindowShow" ref='floatPicInPicContainer1'
:style="`width: ${floatWindowSize.width}rpx;height: ${floatWindowSize.height}rpx;`">
<wrs-uts-floatPicInPic ref='floatPicInPic1' @onLayouted="onLayouted">
<view @tap="floatPicClick">
<view class="nertc-video-area">
<view class="nertc-video-view" v-for="(item, index) in floatWindowVideoList" :key="!isShowUserScreenVideo ? item.key : item">
<nertc-remote-view
:style="`width: ${floatWindowSize.width}rpx;height: ${floatWindowSize.height}rpx;flex: 1;margin-top:0`"
v-if="item" :mediaType="floatWindowType" :userID="!isShowUserScreenVideo ? item.viewID : item" :viewID="!isShowUserScreenVideo ? item.viewID : item">
</nertc-remote-view>
</view>
</view>
</view>
</wrs-uts-floatPicInPic>
</wrs-uts-floatPicInPicContainer>
data: {
return {
outterVideoList: [], //大屏幕视频
outterMediaType: "subStreamVideo",
floatWindowVideoList: [], //悬浮窗视频
floatWindowType: "video",
}
}
//小窗的加载方法
async openPicInPic1() {
let hasPermission = FloatPicInPic.canDrawOverlays();
if (hasPermission) {
this.floatWindowShow = true
const that = this
setTimeout(() => {
let screenWidth = FloatPicInPic.getScreenWidth()
let screenHeight = FloatPicInPic.getScreenHeight()
// 宽度
let width = screenWidth / 5
// 高度
let height = screenHeight / 5
// X轴
let x = screenWidth - width
// Y轴
let y = (screenHeight - height) - 30
// 标签,用于后面小窗口删除、返回页面
this.floatWindowSize = {
width: width,
height: height
}
let tag = 1
this.$refs.floatPicInPic1.openPicInPic(x, y, width, height, tag)
console.log("this.floatWindowSize: " + JSON.stringify(this.floatWindowSize));
// this.$refs.floatPicInPicContainer1.setViewHidden(true)
}, 1000);
} else {
let res = await util.showModal(myStr.getmyStr('m0000'), "当前没有悬浮窗权限,是否去打开权限?")
if (!res.ok) {
return;
}
FloatPicInPic.goToOpenOverlaysSetting()
}
}
//小窗的点击方法
floatPicClick() {
//麻烦在所有console输出日志的地方,都使用engine.nertcPrint接口多打印一遍,比如:
// console.log('=====floatPicClick====');
// engine.nertcPrint('=====floatPicClick===='),engine为SDK初始化的实例对象,这样=====floatPicClick====这个日志出了在控制台之外,也会写入app系统日志文件中了,调试会方便很多
console.log('=====floatPicClick====');
//1.5秒之内只能点击一次
if (this.isTapBtn == true) {
return;
}
this.isTapBtn = true
setTimeout(() => {
this.isTapBtn = false
}, 1500)
//2处理视频流
this.isShowUserScreenVideo = !this.isShowUserScreenVideo
//1、uniapp SDK内部是根据 nertc-remote-view 组件的生命周期来管理canvas画布的
//2、destroyRemoteVideoCanvas仅仅是销毁画布和sdk之间的联系
//3、因此业务上想变更画布,建议是先销毁nertc-remote-view组件,然后在创建nertc-remote-view
if (this.isShowUserScreenVideo) {
this.floatWindowType = 'video'
//销毁悬浮窗视频的nertc-remote-view组件
this.floatWindowVideoList = []
this.$nextTick(() => {
console.warn('此时远端视频 nertc-remote-view 销毁完成')
//保证该组件销毁完成后,同步的执行后面的流程
//清除音视频SDK内部绑定的view,之前对应的是视频辅流
nertc.nertcUtils.destroyRemoteSubStreamVideoCanvas()
//重新渲染nertc-remote-view组件
this.floatWindowVideoList = this.remoteUserIdVideoList
//保证当前nertc-remote-view组件渲染完成,然后执行设置画布的接口
//否则可能会setupRemoteVideoCanvas时,由于此时页面上的nertc-remote-view组件还没有渲染
//底层sdk根本找不到对应的view组件,因此setupRemoteVideoCanvas设置是失败的
//如果不使用$nextTick方法,需要监听sdk的 onVideoCanvas 方法,需要在该方法中重新设置画布,可以参考云信官方文档中的示例代码
this.$nextTick(() => {
console.warn('此时远端视频 nertc-remote-view 渲染完成')
//重新设置远端Video(即摄像头)的画布
nertc.nertcUtils.setupRemoteVideoCanvas()
})
})
this.outterMediaType = 'subStreamVideo'
//销毁大屏幕视频的nertc-remote-view组件
this.outterVideoList = []
this.$nextTick(() => {
console.warn('此时远端视频辅流 nertc-remote-view 销毁完成')
//清除音视频SDK内部绑定的view,之前对应的是视频
nertc.nertcUtils.destroyRemoteVideoCanvas()
this.outterVideoList = this.remoteUserIDSubStreamVideoList
this.$nextTick(() => {
console.warn('此时远端视频辅流 nertc-remote-view 渲染完成')
//重新设置远端subStramVideo(即屏幕共享)的画布
nertc.nertcUtils.setupRemoteSubStreamVideoCanvas()
})
})
} else {
this.floatWindowType = 'subStreamVideo'
//销毁悬浮窗视频的nertc-remote-view组件
this.floatWindowVideoList = []
this.$nextTick(() => {
console.warn('此时远端视频 nertc-remote-view 销毁完成')
//清除音视频SDK内部绑定的view,之前对应的是视频
nertc.nertcUtils.destroyRemoteVideoCanvas()
//重新渲染nertc-remote-view组件
this.floatWindowVideoList = this.remoteUserIDSubStreamVideoList
this.$nextTick(() => {
console.warn('此时远端视频辅流 nertc-remote-view 渲染完成')
//重新设置远端subStramVideo(即屏幕共享)的画布
nertc.nertcUtils.setupRemoteSubStreamVideoCanvas()
})
})
this.outterMediaType = 'video'
//销毁大屏幕视频的nertc-remote-view组件
this.outterVideoList = []
this.$nextTick(() => {
console.warn('此时远端视频辅流 nertc-remote-view 销毁完成')
//清除音视频SDK内部绑定的view,之前对应的是视频辅流
nertc.nertcUtils.destroyRemoteSubStreamVideoCanvas()
this.outterVideoList = this.remoteUserIdVideoList
this.$nextTick(() => {
console.warn('此时远端视频 nertc-remote-view 渲染完成')
//重新设置远端Video(即摄像头)的画布
nertc.nertcUtils.setupRemoteVideoCanvas()
})
})
}
//不用设置定时器了,使用$nextTick方法等待nertc-remote-view渲染完成之后再设置画布
/*
setTimeout(() => {
//3.1重新设置远端Video(即摄像头)的画布
nertc.nertcUtils.setupRemoteVideoCanvas()
//3.2重新设置远端subStramVideo(即屏幕共享)的画布
nertc.nertcUtils.setupRemoteSubStreamVideoCanvas()
}, 1000);
*/
}
此文档是否对你有帮助?