Browse Source

增加网速显示,调整窗口大小

caner 1 year ago
parent
commit
258fc06ece

+ 2 - 2
src-tauri/tauri.conf.json

@@ -15,8 +15,8 @@
         "center": true,
         "center": true,
         "transparent": true,
         "transparent": true,
         "decorations": false,
         "decorations": false,
-        "minWidth": 1300,
-        "minHeight": 800,
+        "minWidth": 1200,
+        "minHeight": 760,
         "shadow": false,
         "shadow": false,
         "devtools": true
         "devtools": true
       }
       }

+ 1 - 1
src/App.vue

@@ -71,7 +71,7 @@ body {
   padding: 0;
   padding: 0;
   width: 100%;
   width: 100%;
   height: 100%;
   height: 100%;
-  min-width: 1300px;
+  min-width: 1200px;
   min-height: 760px;
   min-height: 760px;
   overflow: hidden;
   overflow: hidden;
   border-radius: 8px;
   border-radius: 8px;

+ 5 - 0
src/assets/naive-theme.ts

@@ -39,6 +39,11 @@ const themeOverrides: GlobalThemeOverrides = {
     fontSizeMedium: '14px',
     fontSizeMedium: '14px',
     fontSizeLarge: '15px',
     fontSizeLarge: '15px',
     fontSizeHuge: '16px'
     fontSizeHuge: '16px'
+  },
+  Statistic: {
+    valueSuffixTextColor: 'rgba(255, 255, 255, 0.5)',
+    valueTextColor: 'rgba(255, 255, 255, 0.5)',
+    valueFontSize: '19spx'
   }
   }
 }
 }
 export default themeOverrides
 export default themeOverrides

+ 4 - 0
src/assets/native-plugin.ts

@@ -2,6 +2,8 @@ import {
   create,
   create,
   NConfigProvider,
   NConfigProvider,
   NNotificationProvider,
   NNotificationProvider,
+  NNumberAnimation,
+  NStatistic,
   NButton
   NButton
 } from 'naive-ui'
 } from 'naive-ui'
 
 
@@ -9,6 +11,8 @@ const naive = create({
   components: [
   components: [
     NConfigProvider,
     NConfigProvider,
     NNotificationProvider,
     NNotificationProvider,
+    NNumberAnimation,
+    NStatistic,
     NButton
     NButton
   ]
   ]
 })
 })

+ 18 - 0
src/pages/room/component/stats.vue

@@ -0,0 +1,18 @@
+<template>
+  <div class="stats">
+    <n-statistic tabular-nums>
+      <n-number-animation
+        ref="numberAnimationInstRef"
+        :from="0"
+        :to="value"
+      />
+      <template #suffix>
+        kb/s
+      </template>
+    </n-statistic>
+  </div>
+</template>
+<script setup lang="ts">
+const props = withDefaults(defineProps<{ value: number }>(), { value: 0 })
+
+</script>

+ 5 - 4
src/pages/room/index.vue

@@ -58,7 +58,8 @@ const menuList = shallowRef([
     callBack: (blob: Blob) => {
     callBack: (blob: Blob) => {
       console.log('发送对讲', blob)
       console.log('发送对讲', blob)
     }
     }
-  }
+  },
+  { name: '网速', vlaue: 0, component: defineAsyncComponent(() => import('./component/stats.vue')) }
 ])
 ])
 
 
 watch(() => store.mqtt_message, async (value: { type: string, data?: RTCSessionDescriptionInit }) => {
 watch(() => store.mqtt_message, async (value: { type: string, data?: RTCSessionDescriptionInit }) => {
@@ -70,9 +71,7 @@ watch(() => store.mqtt_message, async (value: { type: string, data?: RTCSessionD
     await RTC.Peer?.setLocalDescription(answerd)
     await RTC.Peer?.setLocalDescription(answerd)
   }
   }
   // 发送本地answer
   // 发送本地answer
-  if (type === 'answer') {
-    mqtt.send(value)
-  }
+  if (type === 'answer') mqtt.send(value)
   // 控制数据
   // 控制数据
   if (type === 'control') {
   if (type === 'control') {
     menuList.value[2].vlaue = data ? 1 : 0
     menuList.value[2].vlaue = data ? 1 : 0
@@ -95,6 +94,8 @@ watch(() => store.mqtt_message, async (value: { type: string, data?: RTCSessionD
     if (obj.data.rightPaddle) gauge.value.num++
     if (obj.data.rightPaddle) gauge.value.num++
     if (store.rtcConnected) mqtt.send(obj)
     if (store.rtcConnected) mqtt.send(obj)
   }
   }
+  // 网络状态
+  if (type === 'WebRtcStats') menuList.value[5].vlaue = data.bitrate || 0
 })
 })
 
 
 onMounted(() => RTC.initRTC(remoteVideo.value))
 onMounted(() => RTC.initRTC(remoteVideo.value))

+ 42 - 0
src/services/webrtc.service.ts

@@ -19,6 +19,10 @@ export default class WebRtcService {
 
 
   private store = useStore()
   private store = useStore()
 
 
+  private lastStats: RTCStatsReport | null = null
+
+  private sleep = (ms: number) => new Promise((resolve) => { setTimeout(resolve, ms) })
+
   /**
   /**
    * 初始化
    * 初始化
    * @param DOM HTMLVideoElement
    * @param DOM HTMLVideoElement
@@ -66,6 +70,9 @@ export default class WebRtcService {
         }
         }
       }
       }
 
 
+      // get stats
+      this.getStats()
+
       console.log('RTC success')
       console.log('RTC success')
     } catch (error) {
     } catch (error) {
       console.log('RTC 初始化失败', error)
       console.log('RTC 初始化失败', error)
@@ -83,6 +90,41 @@ export default class WebRtcService {
     this.audioTack!.enabled = mute
     this.audioTack!.enabled = mute
   }
   }
 
 
+  /**
+   * 比特率|丢包率
+   * @returns
+   */
+  async getStats() {
+    if (this.Peer) {
+      const stats = await this.Peer.getStats()
+      let packetLoss = 0
+      let bitrate = 0
+      if (this.lastStats) {
+        stats.forEach((report) => {
+          if (report.type === 'inbound-rtp' && report.kind === 'video') {
+            if (this.lastStats && this.lastStats.has(report.id)) {
+              const lastReport = this.lastStats.get(report.id)
+              const duration = (report.timestamp - lastReport.timestamp) / 1000
+              bitrate = (report.bytesReceived - lastReport.bytesReceived) / duration / 1000
+              const lostPackets = (report.packetsLost - lastReport.packetsLost)
+              if ((report.packetsReceived - lastReport.packetsReceived + lostPackets) === 0) {
+                packetLoss = 0
+              } else {
+                packetLoss = (lostPackets / (report.packetsReceived - lastReport.packetsReceived + lostPackets)) * 100
+              }
+            }
+          }
+        })
+      }
+      this.lastStats = stats
+      this.store.setMqttMessage({ type: 'WebRtcStats', data: { packetLoss: Math.floor(packetLoss * 100) / 100, bitrate: Math.floor(bitrate * 100) / 100 } })
+    } else {
+      this.store.setMqttMessage({ type: 'WebRtcStats', data: { packetLoss: 0, bitrate: 0 } })
+    }
+    await this.sleep(1000)
+    this.getStats()
+  }
+
   distory() {
   distory() {
     this.Peer?.close()
     this.Peer?.close()
     this.Peer = null
     this.Peer = null