Browse Source

测试webrtc

caner 1 year ago
parent
commit
408d20cbf3

+ 10 - 15
src/App.vue

@@ -1,5 +1,4 @@
 <template>
-  <loading v-if="show" />
   <n-config-provider
     preflight-style-disabled
     inline-theme-disabled
@@ -9,36 +8,32 @@
   >
     <n-notification-provider>
       <router-view />
-      <GlobalNotif />
     </n-notification-provider>
   </n-config-provider>
 </template>
 <script setup lang='ts'>
-import { computed, provide, watch } from 'vue'
+import { provide, watch } from 'vue'
 import { zhCN, dateZhCN } from 'naive-ui'
 import { useRouter } from 'vue-router'
-import loading from '@/components/loading.vue'
 import useStore from './store/index'
 import Theme from '@/assets/naive-theme'
-import GlobalNotif from '@/components/notifaiction.vue'
 import MqttService from '@/services/mqtt.service'
 
 const mqtt = new MqttService()
 const store = useStore()
 const router = useRouter()
-const show = computed(() => store.loading)
 const themeOverrides = Theme
-router.push('/room')
+
 watch(() => store.mqtt_message, (val) => {
   console.log('顶级监听', val)
-
-  // if (val.type === 'leave' || val.type === 'disconnect') {
-  //   router.push('/')
-  // }
-
-  // if (val.type === 'connect') {
-  //   router.push('/room')
-  // }
+  if (val.type === 'connect') {
+    router.push('/room')
+  }
+  // mqtt断开连接
+  if (val.type === 'disconnect' || val.type === 'leave') {
+    router.push('/')
+    mqtt.disconnect()
+  }
 })
 
 provide('MQTT', mqtt)

+ 2 - 2
src/components/audio.vue

@@ -8,8 +8,8 @@
 
 <script setup lang='ts'>
 const props = withDefaults(defineProps<{
-    state: number,
-    size?: number
+  state: number,
+  size?: number
 }>(), {
   state: 0,
   size: 22

+ 70 - 70
src/components/battery.vue

@@ -19,7 +19,7 @@
 import { computed } from 'vue'
 
 const props = withDefaults(defineProps<{
-    quantity: number
+  quantity: number
 }>(), {
   quantity: 0
 })
@@ -35,90 +35,90 @@ const bgClass = computed(() => {
 })
 </script>
 
-  <style scoped lang="scss">
-  .electric {
-    display: inline-flex;
-    justify-content: center;
-    align-items: center;
+<style scoped lang="scss">
+.electric {
+  display: inline-flex;
+  justify-content: center;
+  align-items: center;
+  position: relative;
+  color: white;
+
+  &-panel {
+    box-sizing: border-box;
+    width: 25px;
+    height: 15px;
     position: relative;
-    color: white;
+    border: 2px solid #ccc;
+    padding: 1px;
+    border-radius: 3px;
+    margin-right: 5px;
+
+    &::before {
+      content: "";
+      border-radius: 0 1px 1px 0;
+      height: 8px;
+      background: #ccc;
+      width: 3px;
+      position: absolute;
+      top: 50%;
+      right: -4px;
+      transform: translateY(-50%);
+      overflow: hidden;
+    }
 
-    &-panel {
-      box-sizing: border-box;
-      width: 25px;
-      height: 15px;
+    &-remainder {
+      border-radius: 1px;
       position: relative;
-      border: 2px solid #ccc;
-      padding: 1px;
-      border-radius: 3px;
-      margin-right: 5px;
-
-      &::before {
-        content: "";
-        border-radius: 0 1px 1px 0;
-        height: 8px;
-        background: #ccc;
-        width: 3px;
-        position: absolute;
-        top: 50%;
-        right: -4px;
-        transform: translateY(-50%);
-        overflow: hidden;
-      }
-
-      &-remainder {
-        border-radius: 1px;
-        position: relative;
-        height: 100%;
-        width: 0%;
-        left: 0;
-        top: 0;
-        background: #fff;
-      }
+      height: 100%;
+      width: 0%;
+      left: 0;
+      top: 0;
+      background: #fff;
     }
+  }
 
-    &-berText {
-      font-size: 15px;
-    }
+  &-berText {
+    font-size: 15px;
   }
+}
 
-  .success {
-    color: #40d7c1;
+.success {
+  color: #40d7c1;
 
-    &>div:first-child::before,
-    &>div:first-child>div {
-      background-color: #40d7c1;
-    }
-
-    &>div:first-child {
-      border-color: #40d7c1;
-    }
+  &>div:first-child::before,
+  &>div:first-child>div {
+    background-color: #40d7c1;
   }
 
-  .warning {
-    color: #f90;
+  &>div:first-child {
+    border-color: #40d7c1;
+  }
+}
 
-    &>div:first-child::before,
-    &>div:first-child>div {
-      background-color: #f90;
-    }
+.warning {
+  color: #f90;
 
-    &>div:first-child {
-      border-color: #f90;
-    }
+  &>div:first-child::before,
+  &>div:first-child>div {
+    background-color: #f90;
   }
 
-  .danger {
-    color: #ed4014;
+  &>div:first-child {
+    border-color: #f90;
+  }
+}
 
-    &>div:first-child::before,
-    &>div:first-child>div {
-      background-color: #ed4014;
-    }
+.danger {
+  color: #ed4014;
 
-    &>div:first-child {
-      border-color: #ed4014;
-    }
+  &>div:first-child::before,
+  &>div:first-child>div {
+    background-color: #ed4014;
+  }
 
+  &>div:first-child {
+    border-color: #ed4014;
   }
-  </style>
+
+}
+</style>

+ 0 - 38
src/components/loading.vue

@@ -1,38 +0,0 @@
-<template>
-  <div class="bg">
-    <div class="loader" />
-  </div>
-</template>
-<style lang="scss" scoped>
-    .bg{
-        width: 100vw;
-        height: 100vh;
-        position: fixed;
-        top: 0;
-        left: 0;
-        display: flex;
-        align-items: center;
-        justify-content: center;
-        background: rgba(0, 0, 0, 0.5);
-    }
-    .loader {
-
-        border: 5px solid #f3f3f3;
-        border-radius: 50%;
-        border-top: 5px solid #3498db;
-        width: 30px;
-        height: 30px;
-        -webkit-animation: spin 2s linear infinite;
-        animation: spin 2s linear infinite;
-    }
-
-    @-webkit-keyframes spin {
-        0% { -webkit-transform: rotate(0deg); }
-        100% { -webkit-transform: rotate(360deg); }
-    }
-
-    @keyframes spin {
-        0% { transform: rotate(0deg); }
-        100% { transform: rotate(360deg); }
-    }
-</style>

+ 0 - 10
src/components/notifaiction.vue

@@ -1,10 +0,0 @@
-<template>
-  <div />
-</template>
-
-<script setup lang="ts">
-import { useNotification } from 'naive-ui'
-
-window.$notification = useNotification()
-
-</script>

+ 40 - 40
src/components/signal.vue

@@ -14,7 +14,7 @@
 import { ref, watch } from 'vue'
 
 const props = withDefaults(defineProps<{
-    signalValue: number
+  signalValue: number
 }>(), {
   signalValue: 0
 })
@@ -59,52 +59,52 @@ watch(() => props.signalValue, (v: number) => {
 }, { immediate: true })
 </script>
 
-  <style scoped lang="scss">
-  .signal-box {
-    display: inline-flex;
-    align-items: flex-start;
-    justify-content: center;
-    height: 23px;
-    width: 23px;
-    position: relative;
-    z-index: 3;
+<style scoped lang="scss">
+.signal-box {
+  display: inline-flex;
+  align-items: flex-start;
+  justify-content: center;
+  height: 23px;
+  width: 23px;
+  position: relative;
+  z-index: 3;
 
-    ul {
-      height: 21px;
-      margin: 0;
-      padding: 0;
-      display: flex;
-      align-items: flex-end;
-    }
+  ul {
+    height: 21px;
+    margin: 0;
+    padding: 0;
+    display: flex;
+    align-items: flex-end;
+  }
 
-    li {
-      width: 4px;
-      height: 5px;
-      border-radius: 10px;
-      list-style: none;
-      margin: 0 0.5px;
+  li {
+    width: 4px;
+    height: 5px;
+    border-radius: 10px;
+    list-style: none;
+    margin: 0 0.5px;
 
-      @for $i from 1 through 5 {
-        &:nth-child(#{$i}) {
-          height:#{ $i * 5 - ($i - 1) }px;
-        }
+    @for $i from 1 through 5 {
+      &:nth-child(#{$i}) {
+        height:#{ $i * 5 - ($i - 1) }px;
       }
     }
+  }
 
-    .signal-default {
-      background: rgba(0, 0, 0, 0.3);
-    }
+  .signal-default {
+    background: rgba(0, 0, 0, 0.3);
+  }
 
-    .signal-red {
-      background-color: #ed4014;
-    }
+  .signal-red {
+    background-color: #ed4014;
+  }
 
-    .signal-yellow {
-      background-color: #f90;
-    }
+  .signal-yellow {
+    background-color: #f90;
+  }
 
-    .signal-green {
-      background-color: #00CED1;
-    }
+  .signal-green {
+    background-color: #00CED1;
   }
-  </style>
+}
+</style>

+ 2 - 4
src/pages/login/index.vue

@@ -57,14 +57,12 @@
   </div>
 </template>
 <script setup lang="ts">
-import {
-  computed, onUnmounted, ref, watch, inject
-} from 'vue'
+import { computed, ref, inject } from 'vue'
 import topBar from '@/components/topBar.vue'
 import useStore from '@/store/index'
 
 const store = useStore()
-const mqtt = inject('MQTT')
+const mqtt = inject('MQTT') as Any
 const name = ref(localStorage.getItem('NAME') || '')
 const room = ref(localStorage.getItem('ROOM') || '')
 const url = ref(localStorage.getItem('URL') || '')

+ 28 - 36
src/pages/room/index.vue

@@ -5,71 +5,63 @@
       <audiod :state="audioValue" />
       <battery :quantity="batteryValue" />
     </topBar>
-    <video ref="remoteVideo" autoplay playsinline />
+    <video
+      ref="remoteVideo"
+      autoplay
+      playsinline
+    />
     <div class="room-gauge">
-      <gauge :value="SpeedValue" :gears="conctrlNum % 2 ? '倒档' : '前进'" />
+      <gauge
+        :value="SpeedValue"
+        :gears="conctrlNum % 2 ? '倒档' : '前进'"
+      />
     </div>
   </div>
 </template>
 
 <script setup lang='ts'>
-import { ref, onMounted, inject } from 'vue'
+import {
+  ref, onMounted, inject, watch
+} from 'vue'
 import topBar from '@/components/topBar.vue'
 import signal from '@/components/signal.vue'
 import battery from '@/components/battery.vue'
 import gauge from '@/components/gauge.vue'
 import audiod from '@/components/audio.vue'
 import WebRtcService from '@/services/webrtc.service'
-import useStore from './store/index'
+import useStore from '@/store/index'
 
 const signalValue = ref(5)
 const batteryValue = ref(50)
 const SpeedValue = ref(60)
 const conctrlNum = ref(0)
 const audioValue = ref(3)
-const remoteVideo = ref<HTMLVideoElement | null>(null)
+const remoteVideo = ref(null as unknown as HTMLVideoElement)
 const RTC = new WebRtcService()
 const store = useStore()
-const mqtt = inject('MQTT')
+const mqtt = inject('MQTT') as Any
 
-onMounted(() => RTC.initRTC(remoteVideo, (event) => {
-  console.log(1111, event)
-  const { msg, code, data } = event
-  // 把自己的answer发送给对方
-  if (code === 200 && msg === 'answer') {
-    mqtt.send(JSON.stringify(data))
+onMounted(() => RTC.initRTC(remoteVideo.value, (event) => {
+  const { type, data } = event
+  if (type === 'connected') {
+    console.log('可以发送控制数据')
   }
-
-  // 连接成功
-  if(code === 200 && msg === 'connected') {
-   console.log('可以发送控制数据');
+  if (type === 'answer') {
+    mqtt.send(JSON.stringify(data))
   }
-
-  // 连接失败
-  if(code === 500) {
-    console.log('连接失败');
+  if (type === 'disconnected') {
     RTC.distory()
     mqtt.disconnect()
   }
-
 }))
 
-watch(() => store.mqtt_message, (val) => {
-  // mqtt断开连接
-  if (val.type === 'leave' || val.type === 'disconnect') {
-    router.push('/')
-  }
-
-  // 对方加入告诉对方开始推流
-  if (val.type === 'join') {
-    mqtt.send(JSON.stringify({ type: 'startRTC' }))
-  }
-
-  // 对方发的offer
+watch(() => store.mqtt_message, async (val) => {
+  // 接收offer
   if (val.type === 'offer') {
-    await Peer.value?.setRemoteDescription(msg)
-    const answerd = await Peer.value?.createAnswer()
-    await Peer.value?.setLocalDescription(answerd)
+    console.log('offer', val)
+    await RTC.Peer?.setRemoteDescription(val.data)
+    const answerd = await RTC.Peer?.createAnswer()
+    await RTC.Peer?.setLocalDescription(answerd)
   }
 })
 

+ 10 - 4
src/services/mqtt.service.ts

@@ -41,6 +41,7 @@ export default class MqttService extends Service {
    * @returns
    */
   async send(params: string, qos = 0) {
+    console.log('发送', this.client_channel, this.client_id)
     if (!this.client_channel || !this.client_id) return null
     return await publish(this.client_id, this.client_channel, qos, false, params)
   }
@@ -68,18 +69,23 @@ export default class MqttService extends Service {
       // 断开连接
       if (event.disconnect) {
         console.log('已断开服务器,插件未自动断开已提is')
-        this.store.setMqttMessage({ type: 'disconnect', data: '服务器断开' })
+        this.store.setMqttMessage({ type: 'disconnect' })
       }
 
       // 收到消息
       if (event.message) {
         try {
-          const { payload, topic } = event.message
-          this.client_channel = topic
+          const { payload } = event.message
           const data = JSON.parse(Buffer.from(payload).toString())
-          this.store.setMqttMessage({ ...data })
+          // 订阅对方,通知对方开始RTC
+          if (data.type === 'join') {
+            this.client_channel = data.channel
+            this.send(JSON.stringify({ type: 'startRTC' }))
+          }
           // 离开就退出mqtt
           if (data.type === 'leave') this.disconnect()
+
+          this.store.setMqttMessage({ ...data })
         } catch (error) {
           this.throw('mqtt消息解析失败')
         }

+ 5 - 5
src/services/webrtc.service.ts

@@ -22,7 +22,7 @@ export default class WebRtcService extends Service {
 
   initRTC(DOM: HTMLVideoElement, callBack: (event: Any) => void) {
     try {
-      if (!DOM) { callBack({ msg: 'DOM不存在', code: 500, data: null }); return }
+      if (!DOM) { callBack({ type: 'disconnected' }); return }
       console.log('start initRTC')
 
       // create Peer
@@ -37,7 +37,7 @@ export default class WebRtcService extends Service {
         if (this.Peer?.iceGatheringState === 'complete') {
           const answer = this.Peer?.localDescription
           console.log('send answer', answer)
-          callBack({ msg: 'answer', code: 200, data: answer?.toJSON() })
+          callBack({ type: 'answer', data: answer?.toJSON() })
         }
       }
 
@@ -53,21 +53,21 @@ export default class WebRtcService extends Service {
         console.log('StateChange', state)
         if (state === 'failed' || state === 'disconnected' || state === 'closed') {
           console.log('P2P通信失败')
-          callBack({ msg: 'P2P通信失败', code: 500, data: null })
+          callBack({ type: 'disconnected' })
         }
 
         // ICE连接成功
         if (state === 'connected') {
           await this.sleep(3000)
           console.log('P2P通信成功, 开始发送控制数据')
-          callBack({ msg: 'connected', code: 200, data: null })
+          callBack({ type: 'connected', data: null })
         }
       }
 
       console.log('RTC success')
     } catch (error) {
       console.log('RTC 初始化失败', error)
-      callBack({ msg: `RTC 初始化失败${error}`, code: 500, data: null })
+      callBack({ type: 'disconnected' })
     }
   }