Quellcode durchsuchen

Merge branch 'dev5.9.2' of Software/android-cloud-H5 into master

tangdehang vor 2 Monaten
Ursprung
Commit
501a7064db

+ 3 - 34
components/layout/index.vue

@@ -1,48 +1,17 @@
 <template>
   <div class="layout">
     <slot></slot>
-    <img src="@/assets/image/goBack-cion.png" alt="" class="go-back" @click="goBack" v-if="visible">
   </div>
 </template>
 
 <script>
 export default {
   name: 'layout',
-  props: {
-    isGoBack: {
-      type: Boolean,
-      default: false
-    }
-  },
   data() {
-    return {
-      visible: true,
-      isApp: null,
-      isAndroid: null
-    };
-  },
-  mounted() {
-    // 如果是安卓的需要判断一下是否显示h5内置的返回按钮
-    // 如果是H5、微信小程序,不需要显示次按钮
-    this.isApp = this.$userAgent.isSzx || this.$userAgent.isSzxBrowser
-    this.isAndroid = this.$userAgent.isAndroid;
-    if (!this.isApp) return this.visible = false
-    if (this.isApp && this.isAndroid) {
-      this.visible = !!window.native.goneBack
-      this.visible && window.native.goneBack()
-      return
-    }
+    return {};
   },
-  methods: {
-    goBack() {
-      // 如果为true是最前一页
-      if (this.isGoBack) {
-        this.isAndroid ? window.native.backClick() : window.webkit.messageHandlers.appGoBack.postMessage({})
-        return
-      }
-      this.$router.go(-1)
-    }
-  }
+  mounted() {},
+  methods: {}
 };
 </script>
 

+ 34 - 7
pages/introductionCloudPhone/components/layout.vue

@@ -33,12 +33,34 @@ export default {
     isRouterBack: {
       type: Boolean,
       default: false
+    },
+    // 用于内嵌页面,标识为最后一页
+    isGoBack: {
+      type: Boolean,
+      default: false
     }
   },
   data() {
-    return {};
+    return {
+      isApp: null,
+      isAndroid: null,
+    };
+  },
+  mounted() {
+    // 如果是安卓的需要判断一下是否显示h5内置的返回按钮
+    // 如果是H5、微信小程序,不需要显示次按钮
+    this.isApp = this.$userAgent.isSzx || this.$userAgent.isSzxBrowser
+    this.isAndroid = this.$userAgent.isAndroid;
+    // if (!this.isApp) return this.visible = false
+    // if (this.isApp && this.isAndroid) {
+    //   this.visible = !!window.native.goneBack
+    //   // 判断是否有注册goneBack方法,有就调用
+    //   if(!!window.native.goneBack){
+    //     console.log('this.visible', this.visible)
+    //     window.native.goneBack() // 安卓隐藏返回按钮
+    //   }
+    // }
   },
-  mounted() { },
   computed: {
     containerStyle() {
       // if (this.isShowApp) {
@@ -67,8 +89,8 @@ export default {
     },
     isShowNavBar() {
       // 是否是APP
-      const isApp = this.$userAgent.isSzx || this.$userAgent.isSzxBrowser;
-      const isAndroid = this.$userAgent.isAndroid;
+      const isApp = this.isApp;
+      const isAndroid = this.isAndroid;
       const isIos = this.$userAgent.isIos;
       const isWx = this.$userAgent.isWx;
       // 如果是App并且是安卓,就不显示头部, ios显示
@@ -77,9 +99,9 @@ export default {
       let bool = false;
       // bool = isApp ? (isAndroid ? !isAndroid : isIos) : (isWx ? !isWx : !isWx);
 
-      bool = (isApp && (isAndroid || isIos)) || isWx ? false : true;
+      bool = (isApp && (isAndroid || !isIos)) || isWx ? false : true;
+      // bool = isWx ? false : true;
 
-      // console.log()
       return bool || this.forceShowNavBar;
     },
 
@@ -90,7 +112,12 @@ export default {
         this.$emit('goBack');
         return;
       }
-      this.$router.go(-1);
+      // 如果为true是最前一页
+      if (this.isGoBack) {
+        this.isAndroid ? window.native.backClick() : window.webkit.messageHandlers.appGoBack.postMessage({})
+        return
+      }
+      this.$router.go(-1)
     },// 退出相关逻辑
   },
 };

+ 7 - 7
pages/introductionCloudPhone/index.vue

@@ -1,7 +1,7 @@
 <!-- @notes: 页面于2024-11-17 由判断是否为app [isShowApp] 进行背景颜色判断的需求取消,统一换成白色背景. html上直接写 布尔值的均由 [isShowApp] 替换-->
 <template>
-  <layoutBack :isGoBack='true'>
-    <layout title='推荐云手机'>
+  <layoutBack>
+    <layout title='推荐云手机' :isGoBack='true'>
       <!-- <div :class="isShowApp?'introduction':'introduction introduction-white'"> -->
       <div class="introduction" :class="{'introduction-white': !false}">
         <div class="introduction-title" v-if="isShowApp">
@@ -135,15 +135,15 @@ export default {
   computed: {
     isShowApp() {
       // 是否是APP
-      const isApp = this.$userAgent.isSzx || this.$userAgent.isSzxBrowser;
-      const isAndroid = this.$userAgent.isAndroid;
-      const isIos = this.$userAgent.isIos;
-      const isWx = this.$userAgent.isWx;
+      // const isApp = this.$userAgent.isSzx || this.$userAgent.isSzxBrowser;
+      // const isAndroid = this.$userAgent.isAndroid;
+      // const isIos = this.$userAgent.isIos;
+      // const isWx = this.$userAgent.isWx;
       // 如果是App并且是安卓,就不显示头部, ios显示
       // 如果微信小程序环境的,也不显示头部
       // 如果是h5 就显示头部
       let bool = false;
-      bool = isApp && (isAndroid || isIos) ? true : false;
+      // bool = isApp && (isAndroid || isIos) ? true : false;
       return bool;
     },
   },

+ 23 - 11
static/rtcEngine/WXtrialInterface.html

@@ -7,13 +7,13 @@
     <title>双子星云手机</title>
     <link rel="stylesheet" href="./config/css/vant.css">
     <link rel="stylesheet" href="./css/WXtrialInterface.css">
-    <!-- <script src="https://lf9-cdn-tos.bytecdntp.com/cdn/expire-1-M/vConsole/3.12.1/vconsole.min.js"></script> -->
-    <!-- <script>
+    <!-- <script src="https://lf9-cdn-tos.bytecdntp.com/cdn/expire-1-M/vConsole/3.12.1/vconsole.min.js"></script>
+    <script>
         const vConsole = new VConsole();
     </script> -->
 </head>
 
-<body @touchmove.prevent>
+<body @touchmove.prevent @mousemove.prevent>
     <div id="app" v-cloak>
         <!-- 计时卡计时 -->
         <div class="pfi flex timing" v-if="timingVisible" v-cloak>
@@ -23,24 +23,36 @@
 
         <!-- 悬浮框 -->
         <div class="levitated-sphere" :style="levitatedSpherePositionData" v-cloak
-            @click="levitatedSphereVisible = true">
-            <img src="../static/img/xuanfu_icon.png" alt="" @touchmove.prevent="touchmoveLevitatedSphere"
-                @touchend="touchendLevitatedSphere">
+            @click="onSphere">
+            <img src="../static/img/xuanfu_icon.png" alt=""
+                @mousedown.prevent="onSphereDown"
+                @mouseup.prevent.stop="onSphereUp"
+                @touchmove.prevent="touchmoveLevitatedSphere"
+                @mousemove.prevent="touchmoveLevitatedSphere"
+                @touchend="touchendLevitatedSphere"
+                @mouseup="touchendLevitatedSphere"
+                @mouseleave="touchendLevitatedSphere">
         </div>
 
-        <div class="layout" :style="{height: height + 'px'}" v-cloak  @touchmove.prevent>
+        <div class="layout" :style="{height: height + 'px'}" v-cloak  @touchmove.prevent @mousemove.prevent>
             <!-- 云机位置 -->
-            <div class="layout-view" v-cloak @touchmove.prevent>
+            <div class="layout-view" v-cloak @touchmove.prevent @mousemove.prevent>
                 <video ref="rtcMediaPlayer" :style="rtcMediaPlayerStyle" width="100%" height="100%" autoplay
                     webkit-playsinline="true" playsinline x-webkit-airplay="allow" x5-video-player-type="h5"
                     x5-video-player-fullscreen="true" x5-video-orientation="portraint" id="playerVideo"
-                    class="videoRotate" :controls="false" @touchmove.prevent="(event) => {engine.touchClick(event, 2)}"
+                    class="videoRotate" :controls="false"
+                    @touchmove.prevent="(event) => {engine.touchClick(event, 2)}"
+                    @mousemove.prevent="(event) => {engine.touchClick(event, 2)}"
                     @touchstart.prevent="(event) => {engine.touchClick(event, 0)}"
-                    @touchend.prevent="touchendRtcMediaPlayer" v-show="isShowVideo">
+                    @mousedown.prevent="(event) => {engine.touchClick(event, 0)}"
+                    @mouseup.prevent="touchendRtcMediaPlayer"
+                    @mouseleave.prevent="touchendRtcMediaPlayer"
+                    @touchend.prevent="touchendRtcMediaPlayer"
+                    v-show="isShowVideo">
                     当前浏览器暂不支持、请使用谷歌浏览器或前往双子星客户端使用</video>
             </div>
             <!-- 底部按钮 -->
-            <div class="layout-footer" v-cloak @touchmove.prevent>
+            <div class="layout-footer" v-cloak @touchmove.prevent @mousemove.prevent>
                 <template v-for="item in footerBtn">
                     <img :src="item.img" alt="" @click="footerBtnFun(item.key)">
                 </template>

Datei-Diff unterdrückt, da er zu groß ist
+ 298 - 298
static/rtcEngine/config/js/rtcEngine.min.js


+ 10 - 6
static/rtcEngine/css/WXtrialInterface.css

@@ -115,14 +115,16 @@ html {
   font-size: 0.12rem;
 }
 .layout .layout-view {
-  height: calc(100% - 0.6rem);
+  height: calc(100% - 0.4rem);
   width: 100%;
   position: relative;
+  display: flex;
+  align-content: center;
+  justify-content: center;
+  align-items: center;
+  flex-wrap: nowrap;
 }
 .layout .layout-view .videoRotate {
-  position: absolute;
-  left: 0;
-  top: 0;
   display: block;
   object-fit: fill;
 }
@@ -130,7 +132,7 @@ html {
   display: grid;
   grid-template-columns: repeat(3, 1fr);
   text-align: center;
-  height: 0.6rem;
+  height: 0.4rem;
 }
 .layout .layout-footer img {
   margin: auto;
@@ -483,4 +485,6 @@ html {
 .levitated-sphere img {
   width: 0.42rem;
   height: 0.42rem;
-}
+}
+
+/*# sourceMappingURL=WXtrialInterface.css.map */

+ 83 - 19
static/rtcEngine/js/WXtrialInterface.js

@@ -142,15 +142,18 @@ const app = new Vue({
 
         rtcMediaPlayerStyle() {
             let obj = {
-                objectFit: "fill"
+                objectFit: "fill",
+                width: `${this.layoutViewWidth}px`,
+                height: `${this.layoutViewHeight}px`,
             }
             if (this.isLandscape) {
                 obj = {
                     width: `${this.layoutViewHeight}px`,
                     height: `${this.layoutViewWidth}px`,
-                    left: '50%',
-                    top: '50%',
-                    transform: 'translate(-50%, -50%) rotate(90deg)'
+                    // left: '50%',
+                    // top: '50%',
+                    // transform: 'translate(-50%, -50%) rotate(90deg)'
+                    transform: 'rotate(90deg)'
                 }
             }
 
@@ -237,7 +240,7 @@ const app = new Vue({
             switch (event.type) {
                 case "screenChange":
                     // 0:横屏 1:竖屏
-                    // console.log("屏幕方向变化事件:" + event.val);
+                    console.log("屏幕方向变化事件:" + event.val);
                     this.isLandscape = event.val === 0;
                     break;
                 case "wsState":
@@ -246,7 +249,7 @@ const app = new Vue({
                     const status = ["TIMEOUT", "failed"]
                     if (status.includes(event.val)) {
                         // 设置日志 推流状态为失败
-                        logReportObj.setParams({plugFowStatus: 2, linkWay: 0});
+                        logReportObj.setParams({plugFowStatus: 2, linkWay: 0, linkEndTime: logReportObj.formatDate(new Date())});
                         // 日志上报
                         logReportObj.collectLog(
 `信令服务地址nats失败:
@@ -281,8 +284,9 @@ url: ${this.engine.options.url}
                         // this.pushflowPopup()
                         // this.getResidueTime()
 
-                        // 设置日志 推流状态为失败
-                        logReportObj.setParams({plugFowStatus: 1, linkWay: 1});
+                        // 设置日志 推流状态为成功
+                        let now = new Date();
+                        logReportObj.setParams({plugFowStatus: 1, linkWay: 1, timeConsuming: now.getTime() - logReportObj.timeStartTime, linkEndTime: logReportObj.formatDate(now)});
                         // 日志上报
                         logReportObj.collectLog(`推流成功`);
                         playOnBtn.bind(this)()
@@ -291,7 +295,7 @@ url: ${this.engine.options.url}
                     if (event.val === "connecting") return
                     if (event.val === 'failed') {
                         // 设置日志 推流状态为失败
-                        logReportObj.setParams({plugFowStatus: 2, linkWay: 1});
+                        logReportObj.setParams({plugFowStatus: 2, linkWay: 1, linkEndTime: logReportObj.formatDate(new Date())});
                         // 日志上报
                         logReportObj.collectLog(
 `rtc链接失败:
@@ -300,7 +304,7 @@ url: ${this.engine.options.url}
                     }
                     if(event.val === 'disconnected') {
                         // 设置日志 推流状态为失败
-                        logReportObj.setParams({plugFowStatus: 2, linkWay: 1});
+                        logReportObj.setParams({plugFowStatus: 2, linkWay: 1, linkEndTime: logReportObj.formatDate(new Date())});
                         // 日志上报
                         logReportObj.collectLog(
 `rtc链接超时:
@@ -336,19 +340,50 @@ url: ${this.engine.options.url}
             }
         },
 
+        // 悬浮球click事件
+        onSphere(e){
+            this.levitatedSphereVisible = true
+            e.preventDefault();
+        },
+        // 悬浮球按下事件
+        onSphereDown(e){
+            // 给元素设置鼠标按下状态
+            e.target.isMousedown = true;
+            e.preventDefault();
+        },
+        // 悬浮球抬起事件
+        onSphereUp(e){
+            // 给元素设置鼠标按下状态
+            e.target.isMousedown = false;
+            e.preventDefault();
+        },
         // 悬浮球移动
         touchmoveLevitatedSphere(e) {
-            let { pageX, pageY } = e.targetTouches[0]
+            // 过滤未按下时的移动事件
+            if(e.type === 'mousemove' && !e.target.isMousedown) return
+
+            let pageX,pageY;
+            if(e.type === 'mousemove' && e.target.isMousedown){
+                pageX = e.pageX;
+                pageY = e.pageY;
+            }else if(e.type === 'touchmove'){
+                // let { pageX, pageY } = e.targetTouches[0]
+                pageX = e.targetTouches[0].pageX;
+                pageY = e.targetTouches[0].pageY;
+            }
+
             let min = 20
             let MaxPageX = this.width - 20
             let MaxPageY = this.height - 20
             pageX = pageX <= min ? min : (pageX >= MaxPageX ? MaxPageX : pageX)
             pageY = pageY <= min ? min : (pageY >= MaxPageY ? MaxPageY : pageY)
+
             this.levitatedSpherePositionData = {
                 left: `${pageX}px`,
                 top: `${pageY}px`,
                 transform: 'translate(-50%, -50%)'
             }
+            e.preventDefault();
         },
         touchendLevitatedSphere(e) {
             localStorage.setItem('levitatedSpherePositionData', JSON.stringify(this.levitatedSpherePositionData))
@@ -481,7 +516,7 @@ url: ${this.engine.options.url}
             // 链接报错的回调
             this.doConnectDirectivesWs.onerror = res => {
                 // 设置日志 推流状态为失败
-                logReportObj.setParams({plugFowStatus: 1, linkWay: 0});
+                logReportObj.setParams({plugFowStatus: 1, linkWay: 0, linkEndTime: logReportObj.formatDate(new Date())});
                 // 日志上报
                 logReportObj.collectLog(
 `业务指令通道报错:
@@ -640,7 +675,7 @@ type: ${res.type}
                 try {
                     if (!res.success) {
                         // 设置日志 推流状态为失败,和链接状态
-                        logReportObj.setParams({plugFowStatus: 2, linkWay: logReportObj.RESPONSE_CODE[res.status] || 0});
+                        logReportObj.setParams({plugFowStatus: 2, linkWay: logReportObj.RESPONSE_CODE[res.status] || 0, linkEndTime: logReportObj.formatDate(new Date())});
 
                         // 日志上报
                         logReportObj.collectLog(
@@ -672,7 +707,7 @@ method: post
     
                             if (!this.isSupportRtc) {
                                 // 设置日志 推流状态为失败
-                                logReportObj.setParams({plugFowStatus: 2});
+                                logReportObj.setParams({plugFowStatus: 2, linkEndTime: logReportObj.formatDate(new Date())});
                                 // 日志上报
                                 logReportObj.collectLog(`${+isWeixin ? '微信小程序' : ''}当前版本暂不支持使用`);
     
@@ -715,7 +750,7 @@ method: get
                                     }
                                 }else{
                                     // 设置上报参数
-                                    logReportObj.setParams({linkWay: 4, plugFowStatus: 2});
+                                    logReportObj.setParams({linkWay: 4, plugFowStatus: 2, linkEndTime: logReportObj.formatDate(new Date())});
                                     // 日志上报
                                     logReportObj.collectLog(
 `webRtc连接,获取中转地址失败:
@@ -769,7 +804,7 @@ method: post
                             break
                         default:
                             // 设置上报参数
-                            logReportObj.setParams({linkWay: logReportObj.RESPONSE_CODE[res.status] || 0});
+                            logReportObj.setParams({linkWay: logReportObj.RESPONSE_CODE[res.status] || 0, linkEndTime: logReportObj.formatDate(new Date())});
                             
                             // 日志上报
                             logReportObj.collectLog(statusTips[res.status] || 
@@ -792,7 +827,7 @@ method: post
                 }
             }).catch((error) => {
                 // 设置上报参数
-                logReportObj.setParams({linkWay: 4, plugFowStatus: 2});
+                logReportObj.setParams({linkWay: 4, plugFowStatus: 2, linkEndTime: logReportObj.formatDate(new Date())});
                 // 日志上报
                 logReportObj.collectLog(
 `接口获取数据失败:
@@ -974,10 +1009,39 @@ method: post
             this.height = window.innerHeight
             this.width = window.innerWidth
             this.$nextTick(() => {
+
                 // 云机画面宽高
                 let layoutView = document.querySelector('.layout-view')
-                this.layoutViewWidth = layoutView.offsetWidth
-                this.layoutViewHeight = layoutView.offsetHeight
+                // 获取视口宽度,webRTC需要做成16:9的画面
+                let currentWidth = layoutView.clientWidth;
+                let currentHeight = layoutView.clientHeight;
+
+                // this.layoutViewWidth = layoutView.offsetWidth;
+                // this.layoutViewHeight = layoutView.offsetHeight;
+                
+                // 计算当前视口的宽高比
+                const currentRatio = currentWidth / currentHeight;
+            
+                // 9:16 的目标比例
+                const targetRatio = 9 / 16;
+                console.log(`当前视口的宽高比: ${currentRatio}`);
+                // 判断当前视口的宽高比与目标比例的关系
+                if (currentRatio > targetRatio) {
+                    // 当前视口的宽高比大于目标比例,说明宽度“过宽”,需要以高度为基准
+                    console.log("当前视口宽度过宽,应以高度为基准调整宽度");
+                    this.layoutViewWidth = currentHeight * targetRatio;
+                    this.layoutViewHeight = currentHeight;
+                    console.log(`1目标: 宽${this.layoutViewWidth},高${this.layoutViewHeight}`);
+                } else {
+                    // 当前视口的宽高比小于目标比例,说明高度“过高”,需要以宽度为基准
+                    console.log("当前视口高度过高,应以宽度为基准调整高度");
+                    this.layoutViewHeight = currentWidth / targetRatio;
+                    this.layoutViewWidth = currentWidth;
+                    console.log(`2目标: 宽${this.layoutViewWidth},高${this.layoutViewHeight}`);
+                }
+
+                // 悬浮球位置设置为默认位置
+                this.levitatedSpherePositionData = { right: '15px', top: '15px' }
             })
         },
 

+ 52 - 5
static/rtcEngine/js/logReport.js

@@ -15,6 +15,7 @@ export default class LogReport {
 
   // 上报参数
   paramsJson = {
+    'timeConsuming': '', // 进入云机耗时字段 毫秒单位
     'clientVersion': '', // 客户端版本号 // 通过$Request版本获取
     'clientType': '', // 客户端类型 // 目前判断出wx或h5
     'phoneModel': '', // 手机型号 // 无法获取
@@ -85,6 +86,8 @@ export default class LogReport {
   timer = null; // 定时器
   timerTime = 6000; // // 日志上报间隔时间
 
+  timeStartTime = 0; // 链接开始时间
+
 	/**
 	 * 构造函数,初始化 LogReport 类的实例
 	 * @param {Object} $Request - 用于发送 HTTP 请求的对象
@@ -120,6 +123,12 @@ export default class LogReport {
 
   // 初始化
   async init() {
+    const now = new Date();
+    // 开始连接的时间戳
+    this.timeStartTime = now.getTime();
+    // 设置本次日志上报时间
+    this.paramsJson.linkStartTime = this.formatDate(now);
+
     // 调用 checkSwitch 方法,检查后端上报日志开关是否打开
 		await this.checkSwitch();
 
@@ -195,11 +204,6 @@ export default class LogReport {
       let logData = this.combinativeParam();
 
       logData.logContent = log;
-
-      // 设置本次日志上报时间
-      const date = new Date();
-      let formattedDate = `${date.getFullYear()}-${('0' + (date.getMonth() + 1)).slice(-2)}-${('0' + date.getDate()).slice(-2)} ${('0' + date.getHours()).slice(-2)}:${('0' + date.getMinutes()).slice(-2)}:${('0' + date.getSeconds()).slice(-2)}`;
-      logData.linkStartTime = formattedDate;
   
       this.logs.push(logData);
   
@@ -320,4 +324,47 @@ export default class LogReport {
     // 移除事件监听
     this.netWorkChange(true);
   }
+
+  /**
+   * 格式化日期
+   * @param {Date} date - 要格式化的日期对象
+   * @param {string} format - 格式化字符串,使用以下占位符:
+   *   - 'Y' 表示年份(4 位数)
+   *   - 'm' 表示月份(2 位数)
+   *   - 'd' 表示日期(2 位数)
+   *   - 'H' 表示小时(24 小时制)
+   *   - 'h' 表示小时(12 小时制)
+   *   - 'i' 表示分钟
+   *   - 's' 表示秒数
+   *   - 'u' 表示毫秒
+   *   - 'a' 表示上午/下午标识(小写)
+   *   - 'A' 表示上午/下午标识(大写)
+   * @returns {string} 格式化后的日期字符串 
+  */
+  formatDate(date, format='Y-m-d H:i:s.u') {
+    // 判断输入是否为 Date 对象
+    if (!(date instanceof Date)) {
+        throw new TypeError('The first parameter must be a Date object.');
+    }
+
+    // 定义时间单位的获取方法
+    const formatObj = {
+        'Y': date.getFullYear(), // 年份
+        'm': date.getMonth() + 1, // 月份(+1 是因为 getMonth() 返回的月份是从 0 开始的)
+        'd': date.getDate(), // 日期
+        'H': date.getHours(), // 小时(24 小时制)
+        'h': date.getHours() % 12 || 12, // 小时(12 小时制)
+        'i': date.getMinutes(), // 分钟
+        's': date.getSeconds(), // 秒数
+        'u': date.getMilliseconds(), // 毫秒
+        'a': date.getHours() >= 12 ? 'pm' : 'am', // 上午/下午标识
+        'A': date.getHours() >= 12 ? 'PM' : 'AM' // 上午/下午标识(大写)
+    };
+
+    // 替换格式字符串中的占位符
+    return format.replace(/Y|m|d|H|h|i|s|u|a|A/g, (match) => {
+        return formatObj[match];
+    });
+}
+
 }

+ 10 - 5
static/rtcEngine/scss/WXtrialInterface.scss

@@ -119,14 +119,19 @@ html {
     font-size: toREM(12);
 
     .layout-view {
-        height: calc(100% - toREM(60));
+        height: calc(100% - toREM(40));
         width: 100%;
         position: relative;
+        display: flex;
+        align-content: center;
+        justify-content: center;
+        align-items: center;
+        flex-wrap: nowrap;
 
         .videoRotate {
-            position: absolute;
-            left: 0;
-            top: 0;
+            // position: absolute;
+            // left: 0;
+            // top: 0;
             display: block;
             object-fit: fill;
         }
@@ -136,7 +141,7 @@ html {
         display: grid;
         grid-template-columns: repeat(3, 1fr);
         text-align: center;
-        height: toREM(60);
+        height: toREM(40);
 
         img {
             margin: auto;