|
@@ -5,22 +5,22 @@
|
|
|
|
|
|
<!-- 三menu键 -->
|
|
|
<div id="foot-menu-wrap" :style="`height: ${footMenuWrapHeight}px`">
|
|
|
- <div @click.stop=sendKey(187)><van-icon name="wap-nav" size="24px"/></div>
|
|
|
- <div @click.stop=sendKey(3)><van-icon name="wap-home-o" size="24px"/></div>
|
|
|
- <div @click.stop=sendKey(4)><van-icon name="arrow-left" size="24px"/></div>
|
|
|
+ <div @click.stop="()=>{sendKey(187); noOperationSetTimeout}"><van-icon name="wap-nav" size="24px"/></div>
|
|
|
+ <div @click.stop="()=>{sendKey(3); noOperationSetTimeout}"><van-icon name="wap-home-o" size="24px"/></div>
|
|
|
+ <div @click.stop="()=>{sendKey(4); noOperationSetTimeout}"><van-icon name="arrow-left" size="24px"/></div>
|
|
|
</div>
|
|
|
|
|
|
<!-- 悬浮按钮 -->
|
|
|
<FloatBtn :width="pageData.width" :height="pageData.height" @onClick="levitatedSphereVisible = true"/>
|
|
|
|
|
|
<!-- 右侧popup -->
|
|
|
- <RightPopup :engine="engine" :levitatedSphereVisible.sync="levitatedSphereVisible" @shearplate="shearplate"/>
|
|
|
+ <RightPopup :engine="engine" :userCardId="this.parametersData.userCardId" :levitatedSphereVisible.sync="levitatedSphereVisible" @shearplate="shearplate" @exit="exit"/>
|
|
|
|
|
|
<!-- 输入并复制到粘贴板 -->
|
|
|
<InputCopy ref="inputCopyRef" @openPasteboard="openPasteboard"/>
|
|
|
|
|
|
<!-- 云机内部的粘贴板内容 -->
|
|
|
- <CloudPhoneClipboard ref="cloudPhoneClipboardRef"/>
|
|
|
+ <CloudPhoneClipboard ref="cloudPhoneClipboardRef" :doConnectDirectivesWs="doConnectDirectivesWs"/>
|
|
|
</div>
|
|
|
</template>
|
|
|
|
|
@@ -119,6 +119,11 @@ export default {
|
|
|
connectData: {},
|
|
|
// 云手机引擎 播放器实例
|
|
|
engine: null,
|
|
|
+ doConnectDirectivesWs: null, // 云手机指令通道
|
|
|
+ doConnectDirectivesIntervalerPing: null, // 业务通道定时标识 云手机指令通道心跳
|
|
|
+ doConnectDirectivesRequestNum: 1, // 业务通道重连次数
|
|
|
+ doConnectDirectivesRequestNumMax: 6, // 业务通道重连次数上限
|
|
|
+
|
|
|
// 右侧popup显隐
|
|
|
levitatedSphereVisible: false,
|
|
|
}
|
|
@@ -131,14 +136,6 @@ export default {
|
|
|
// http://192.168.211.37:3000/h5/rtcEngine/rtc/?record=902481&userCardId=902481&mealType=sq&sourceType=0&userCardType=0&validTime=10334&rm=tencent-ap-tianjin-1&authPhone=none&username=0EsH01666175530SZX&token=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJyYW5kb20iOiI0MTg5MyIsImNsaWVudCI6IjciLCJ1c2VyVHlwZSI6IjIiLCJtZXJjaGFudFNpZ24iOiJTWlgiLCJleHAiOjE3NDczODQ2MTgsInVzZXJuYW1lIjoiMEVzSDAxNjY2MTc1NTMwU1pYIn0.fTXawDu4SyEj4mIGr61ZXt0RSXzt3JztPq8-rFe-Zes&isTips=1&isWeixin=0&merchantSign=SZX
|
|
|
// 获取页面传递参数
|
|
|
this.parametersData = this.$route.query;
|
|
|
- // 调用接口获取卡连接数据
|
|
|
- const cardData = await this.getConnectData(this.parametersData);
|
|
|
-
|
|
|
- // 判断卡的连接方式
|
|
|
- const connectData = await this.judgeConnectType(cardData);
|
|
|
-
|
|
|
- // 保存卡连接信息
|
|
|
- this.connectData = connectData;
|
|
|
},
|
|
|
computed: {
|
|
|
// 是否为微信浏览器环境
|
|
@@ -161,9 +158,20 @@ export default {
|
|
|
document.body.style.background = '#000';
|
|
|
|
|
|
// 定义全局变量 用于监听sdk加载状态
|
|
|
- window.$_script_loadHandler = ()=> {
|
|
|
- console.log('SDK加载成功');
|
|
|
+ window.$_script_loadHandler = async ()=> {
|
|
|
+ console.log('$_script_loadHandler: SDK加载成功');
|
|
|
this.sdkLoadStatus = 'success';
|
|
|
+
|
|
|
+ // 调用接口获取卡连接数据
|
|
|
+ const cardData = await this.getConnectData(this.parametersData);
|
|
|
+
|
|
|
+ // 判断卡的连接方式
|
|
|
+ const connectData = await this.judgeConnectType(cardData);
|
|
|
+
|
|
|
+ // 保存卡连接信息
|
|
|
+ this.connectData = connectData;
|
|
|
+
|
|
|
+ this.initWebRtc();
|
|
|
};
|
|
|
window.$_script_errHandler = ()=> {
|
|
|
console.log('SDK加载失败');
|
|
@@ -179,22 +187,6 @@ export default {
|
|
|
};
|
|
|
// 初始化页面监听事件
|
|
|
this.initListener();
|
|
|
-
|
|
|
- // 定时器 监听sdk加载状态, 加载成功和失败则停止定时器, 加载中则继续监听
|
|
|
- let timer = setInterval(() => {
|
|
|
- console.log('SDK加载状态:', this.sdkLoadStatus);
|
|
|
- if (this.sdkLoadStatus === 'success' || window?.rtc_sdk?.MediaSdk) {
|
|
|
- this.sdkLoadStatus = 'success';
|
|
|
- console.log('SDK加载成功');
|
|
|
- clearInterval(timer);
|
|
|
- // 初始化webRTC
|
|
|
- this.initWebRtc();
|
|
|
- }
|
|
|
- if (this.sdkLoadStatus === 'error') {
|
|
|
- console.log('SDK加载失败');
|
|
|
- clearInterval(timer);
|
|
|
- }
|
|
|
- })
|
|
|
},
|
|
|
// 页面销毁前触发
|
|
|
beforeDestroy() {
|
|
@@ -283,7 +275,7 @@ export default {
|
|
|
// 获取卡的信息
|
|
|
async getConnectData(params) {
|
|
|
try {
|
|
|
- const res = await this.$axios.$post('/resources/user/cloud/connect', { userCardId: params. userCardId}, {
|
|
|
+ const res = await this.$axios.$post('/resources/user/cloud/connect', { userCardId: params.userCardId}, {
|
|
|
headers: {
|
|
|
merchantSign: params.merchantSign,
|
|
|
},
|
|
@@ -330,8 +322,9 @@ export default {
|
|
|
message: '当前环境不支持使用,可下载谷歌浏览器或客户端进行使用',
|
|
|
confirmButtonText: '确定',
|
|
|
confirmButtonColor: '#3cc51f',
|
|
|
- callback: () => {
|
|
|
- // TODO 关闭页面
|
|
|
+ callback: (_, done) => {
|
|
|
+ done();
|
|
|
+ this.exit();
|
|
|
}
|
|
|
})
|
|
|
return Promise.reject(new Error('当前浏览器不支持webRTC'));
|
|
@@ -361,71 +354,67 @@ export default {
|
|
|
},
|
|
|
// 初始化webRTC及相关配置
|
|
|
initWebRtc() {
|
|
|
- // 检查连接卡信息是否存在,不存在则循环等待,直到存在为止
|
|
|
- if (!Object.keys(this.connectData).length) {
|
|
|
- setTimeout(() => {
|
|
|
- this.initWebRtc();
|
|
|
- }, 50);
|
|
|
- return;
|
|
|
+ try {
|
|
|
+ // 获取挂载的容器元素
|
|
|
+ const videoRef = document.getElementById("videoRef");
|
|
|
+
|
|
|
+ // 解构connectData中的数据
|
|
|
+ const { sn: topic, cardToken: authToken, localIp, internetHttps, internetHttp, webrtcNetwork, webrtcTransferCmnet, webrtcTransferTelecom, webrtcTransferUnicom, videoCode } = this.connectData;
|
|
|
+ // 判断长连接的协议方式
|
|
|
+ const isWss = location.protocol === 'https:';
|
|
|
+
|
|
|
+ // 生成连接地址
|
|
|
+ const url = `${isWss ? 'wss://' : 'ws://'}${isWss ? internetHttps : internetHttp}/nats`;
|
|
|
+
|
|
|
+ // 统一使用三网解析地址
|
|
|
+ const ICEServerUrl = [
|
|
|
+ { "CMNET": webrtcNetwork }, // 移动
|
|
|
+ { 'CHINANET-GD': webrtcNetwork }, // 电信
|
|
|
+ { 'UNICOM-GD': webrtcNetwork }, // 联通
|
|
|
+ ];
|
|
|
+
|
|
|
+ // 配置连接参数
|
|
|
+ const connection = {
|
|
|
+ mount: videoRef,
|
|
|
+ displaySize: { // 视频在页面显示的尺寸 必填
|
|
|
+ width: this.pageData.videoWidth,
|
|
|
+ height: this.pageData.videoHeight,
|
|
|
+ },
|
|
|
+ topic, // SN号 必填
|
|
|
+ url, //信令服务地址 必填
|
|
|
+ ICEServerUrl,
|
|
|
+ forwardServerAddress: '', // 转发服务器地址
|
|
|
+ ip: localIp, // 实例ip
|
|
|
+ controlToken: '', // 控制token
|
|
|
+ width: 720, // 推流视频宽度 必填
|
|
|
+ height: 1080, // 推流视频高度 必填
|
|
|
+ cardWidth: 0, // 云机系统分辨率 宽 必填
|
|
|
+ cardHeight: 0, // 云机系统分辨率 高 必填
|
|
|
+ cardDensity: 0, // 云机系统显示 密度 必填
|
|
|
+ authToken, //拉流鉴权 token 必填
|
|
|
+ quality: '高清',// 画质(码率) 超清 | 高清 | 标清 | 流畅
|
|
|
+ fps: 30, //必填
|
|
|
+ videoCodec: videoCode, // 视频编码格式 必填
|
|
|
+ videoCodecMethod: true, // 硬编true | 软编false
|
|
|
+ isMuted: false, // 是否静音
|
|
|
+ isAllowedOpenCamera: true, // 是否允许打开摄像头
|
|
|
+ sendFollow: true, // 是否允许主控转发文本到实例
|
|
|
+ callback: (event)=> {}
|
|
|
+ };
|
|
|
+
|
|
|
+ // 获取SDK类
|
|
|
+ const MediaSdk = window.rtc_sdk.MediaSdk;
|
|
|
+ // 初始化 SDK
|
|
|
+ this.engine = new MediaSdk();
|
|
|
+ console.log('RtcEngineConfig==', connection)
|
|
|
+ // 初始化 SDK 并传入连接参数
|
|
|
+ this.engine.RtcEngine(connection);
|
|
|
+
|
|
|
+ // 监听回调方法
|
|
|
+ this.eventCallbackFunction();
|
|
|
+ } catch (error) {
|
|
|
+ console.log('webRTC初始化失败', error);
|
|
|
}
|
|
|
-
|
|
|
- // 获取挂载的容器元素
|
|
|
- const videoRef = document.getElementById("videoRef");
|
|
|
-
|
|
|
- // 解构connectData中的数据
|
|
|
- const { sn: topic, cardToken: authToken, localIp, internetHttps, internetHttp, webrtcNetwork, webrtcTransferCmnet, webrtcTransferTelecom, webrtcTransferUnicom, videoCode } = this.connectData;
|
|
|
- // 判断长连接的协议方式
|
|
|
- const isWss = location.protocol === 'https:';
|
|
|
-
|
|
|
- // 生成连接地址
|
|
|
- const url = `${isWss ? 'wss://' : 'ws://'}${isWss ? internetHttps : internetHttp}/nats`;
|
|
|
-
|
|
|
- // 统一使用三网解析地址
|
|
|
- const ICEServerUrl = [
|
|
|
- { "CMNET": webrtcNetwork }, // 移动
|
|
|
- { 'CHINANET-GD': webrtcNetwork }, // 电信
|
|
|
- { 'UNICOM-GD': webrtcNetwork }, // 联通
|
|
|
- ];
|
|
|
-
|
|
|
- // 配置连接参数
|
|
|
- const connection = {
|
|
|
- mount: videoRef,
|
|
|
- displaySize: { // 视频在页面显示的尺寸 必填
|
|
|
- width: this.pageData.videoWidth,
|
|
|
- height: this.pageData.videoHeight,
|
|
|
- },
|
|
|
- topic, // SN号 必填
|
|
|
- url, //信令服务地址 必填
|
|
|
- ICEServerUrl,
|
|
|
- forwardServerAddress: '', // 转发服务器地址
|
|
|
- ip: localIp, // 实例ip
|
|
|
- controlToken: '', // 控制token
|
|
|
- width: 720, // 推流视频宽度 必填
|
|
|
- height: 1080, // 推流视频高度 必填
|
|
|
- cardWidth: 0, // 云机系统分辨率 宽 必填
|
|
|
- cardHeight: 0, // 云机系统分辨率 高 必填
|
|
|
- cardDensity: 0, // 云机系统显示 密度 必填
|
|
|
- authToken, //拉流鉴权 token 必填
|
|
|
- quality: '高清',// 画质(码率) 超清 | 高清 | 标清 | 流畅
|
|
|
- fps: 30, //必填
|
|
|
- videoCodec: videoCode, // 视频编码格式 必填
|
|
|
- videoCodecMethod: true, // 硬编true | 软编false
|
|
|
- isMuted: false, // 是否静音
|
|
|
- isAllowedOpenCamera: true, // 是否允许打开摄像头
|
|
|
- sendFollow: true, // 是否允许主控转发文本到实例
|
|
|
- callback: (event)=> {}
|
|
|
- };
|
|
|
-
|
|
|
- // 获取SDK类
|
|
|
- const MediaSdk = window.rtc_sdk.MediaSdk;
|
|
|
- // 初始化 SDK
|
|
|
- this.engine = new MediaSdk();
|
|
|
- console.log('RtcEngineConfig==', connection)
|
|
|
- // 初始化 SDK 并传入连接参数
|
|
|
- this.engine.RtcEngine(connection);
|
|
|
-
|
|
|
- // 监听回调方法
|
|
|
- this.eventCallbackFunction();
|
|
|
},
|
|
|
// webRTC状态回调监听回调方法
|
|
|
eventCallbackFunction() {
|
|
@@ -453,6 +442,70 @@ export default {
|
|
|
console.log("webrtc异常状态====★★★★★", r);
|
|
|
});
|
|
|
},
|
|
|
+ // 业务指令通道初始化
|
|
|
+ initControlChannel() {
|
|
|
+ try {
|
|
|
+ // 初始化业务指令通道
|
|
|
+ let { internetHttps, internetHttp, localIp, cardToken } = this.connectData;
|
|
|
+ const isWss = location.protocol === 'https:';
|
|
|
+ let cUrl = `${isWss ? 'wss' : 'ws'}://${isWss ? internetHttps : internetHttp}/businessChannel?cardIp=${localIp}&token=${cardToken}&type=directives`;
|
|
|
+ this.doConnectDirectivesWs = new WebSocket(cUrl);
|
|
|
+ this.doConnectDirectivesWs.binaryType = 'arraybuffer';
|
|
|
+ // 清除定时器
|
|
|
+ if (this.doConnectDirectivesIntervalerPing) {
|
|
|
+ clearInterval(this.doConnectDirectivesIntervalerPing);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 链接成功
|
|
|
+ this.doConnectDirectivesWs.onopen = (e) => {
|
|
|
+ this.doConnectDirectivesIntervalerPing = setInterval(() => {
|
|
|
+ if (this.doConnectDirectivesWs.readyState === 1) {
|
|
|
+ this.doConnectDirectivesWs.send(JSON.stringify({ type: 'ping' }));
|
|
|
+ } else {
|
|
|
+ clearInterval(this.doConnectDirectivesIntervalerPing);
|
|
|
+ }
|
|
|
+ }, 3000);
|
|
|
+ this.doConnectDirectivesWs.send(JSON.stringify({ type: 'getVsStatus' }))
|
|
|
+ this.doConnectDirectivesWs.send(JSON.stringify({ type: 'bitRate', data: { bitRate: 1243000 } }))
|
|
|
+ // // 设置日志参数 推流质量
|
|
|
+ // logReportObj.setParams({ imageQuality: 1243000 });
|
|
|
+
|
|
|
+ this.doConnectDirectivesWs.send(JSON.stringify({ type: 'InputMethod', data: { type: 2 } }))
|
|
|
+ this.doConnectDirectivesWs.send(JSON.stringify({ type: 'getPhoneSize' }))
|
|
|
+ }
|
|
|
+
|
|
|
+ // 接受到的消息
|
|
|
+ this.doConnectDirectivesWs.onmessage = res => {
|
|
|
+ const result = typeof res.data === 'string' ? JSON.parse(res.data) : res.data;
|
|
|
+ switch (result.type) {
|
|
|
+ case 'reProduceText':
|
|
|
+ this.$native.clipboard.writeText(text);
|
|
|
+ break
|
|
|
+ case 'downAdnInstallRep':
|
|
|
+ this.$toast(result.data.msg)
|
|
|
+ break
|
|
|
+ // 接受到这个消息就自动退出云机
|
|
|
+ case 'exitPhone':
|
|
|
+ this.exit();
|
|
|
+ break
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 链接报错的回调
|
|
|
+ this.doConnectDirectivesWs.onerror = res => {
|
|
|
+ if (this.doConnectDirectivesRequestNum > this.doConnectDirectivesRequestNumMax) {
|
|
|
+ return this.exit();
|
|
|
+ }else{
|
|
|
+ // 重连次数加1
|
|
|
+ ++this.doConnectDirectivesRequestNum;
|
|
|
+ // 重连
|
|
|
+ this.initControlChannel();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } catch (error) {
|
|
|
+ console.log('initControlChannel error', error);
|
|
|
+ }
|
|
|
+ },
|
|
|
// 三键
|
|
|
sendKey (keyCode) {
|
|
|
try {
|
|
@@ -470,7 +523,40 @@ export default {
|
|
|
// 打开去取云机内的粘贴板内容
|
|
|
openPasteboard(text){
|
|
|
this.$refs.cloudPhoneClipboardRef.init(text);
|
|
|
- }
|
|
|
+ },
|
|
|
+ // 超过指定触碰时间是否提示关闭链接
|
|
|
+ async pushflowPopup() {
|
|
|
+ try {
|
|
|
+ const res = await this.$axios.get('/public/v5/pushflow/popup');
|
|
|
+ if (res.success) {
|
|
|
+ this.isFiringNoOperationSetTimeout = res.data;
|
|
|
+ this.noOperationSetTimeout();
|
|
|
+ }
|
|
|
+ } catch (error) {
|
|
|
+ console.log(error);
|
|
|
+ }
|
|
|
+ },
|
|
|
+ // 退出功能
|
|
|
+ exit() {
|
|
|
+ // 关闭日志上报
|
|
|
+ // logReportObj.destroy();
|
|
|
+ // 关闭webRTC
|
|
|
+ this.engine.disconnect && this.engine.disconnect();
|
|
|
+ // 关闭业务指令通道
|
|
|
+ this.doConnectDirectivesWs && this.doConnectDirectivesWs.close();
|
|
|
+
|
|
|
+ // 获取当前环境
|
|
|
+ const env = isBrowserEnvironment();
|
|
|
+
|
|
|
+ // ios环境下 直接使用浏览器api返回上一页
|
|
|
+ if(env.isBrowser && !env.isMiniProgramWebview && env.isIPhone && env.isTopWindow) {
|
|
|
+ // 上面的方法执行未生效就走这里
|
|
|
+ if (window.history.length > 1) {
|
|
|
+ return window.history.back();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ uni && uni.reLaunch({ url: '/pages/index/index' });
|
|
|
+ },
|
|
|
}
|
|
|
}
|
|
|
</script>
|
|
@@ -518,7 +604,7 @@ $-bg-yellow: rgb(255, 253, 241);
|
|
|
left: 0px;
|
|
|
bottom: 0px;
|
|
|
width: 100%;
|
|
|
- // height: 40px; // 通过vue动态添加
|
|
|
+ // height: 40px; // 三大功能键高度,通过vue动态添加
|
|
|
background: inherit;
|
|
|
background-color: rgba(0, 12, 23, 1);
|
|
|
border: none;
|
|
@@ -531,9 +617,5 @@ $-bg-yellow: rgb(255, 253, 241);
|
|
|
justify-content: space-evenly;
|
|
|
align-items: center;
|
|
|
color: #fff;
|
|
|
-
|
|
|
- // .foot-menu{
|
|
|
- // width: 40px;
|
|
|
- // }
|
|
|
}
|
|
|
</style>
|