index.vue 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. <template>
  2. <div class="room">
  3. <topBar class="room-bar">
  4. <template
  5. v-for="(item, index) in menuList"
  6. :key="index"
  7. >
  8. <component
  9. :is="item.component"
  10. :value="item.value"
  11. @callBack="item.callBack"
  12. />
  13. </template>
  14. </topBar>
  15. <video
  16. ref="remoteVideo"
  17. autoplay
  18. playsinline
  19. />
  20. <div class="room-gauge">
  21. <Gauge
  22. :value="gauge.speed"
  23. :gears="gauge.num % 2 ? '倒档' : '前进'"
  24. />
  25. </div>
  26. </div>
  27. </template>
  28. <script setup lang='ts'>
  29. import {
  30. ref, onMounted, inject, watch,
  31. onUnmounted,
  32. shallowRef,
  33. defineAsyncComponent
  34. } from 'vue'
  35. import topBar from '@/components/topBar.vue'
  36. import Gauge from '@/components/gauge.vue'
  37. import WebRtcService from '@/services/webrtc.service'
  38. import useStore from '@/store/index'
  39. const remoteVideo = ref(null as unknown as HTMLVideoElement)
  40. const RTC = new WebRtcService()
  41. const store = useStore()
  42. const mqtt = inject('MQTT') as Any
  43. const menuList = shallowRef([ { name: '信号', value: 0, component: defineAsyncComponent(() => import('@/components/signal.vue')) },
  44. { name: '电量', value: 0, component: defineAsyncComponent(() => import('@/components/battery.vue')) },
  45. {
  46. name: '录音',
  47. value: 0,
  48. callBack: (blob: Blob) => {
  49. console.log('send audio', blob)
  50. },
  51. component: defineAsyncComponent(() => import('@/components/mic.vue'))
  52. },
  53. {
  54. name: '静音', value: 0, callBack: (mute: boolean) => RTC.muteRemoteAudio(mute), component: defineAsyncComponent(() => import('@/components/audio.vue'))
  55. } ])
  56. const gauge = ref({ speed: 0, num: 0 })
  57. watch(() => store.mqtt_message, async (value: { type: string, data?: RTCSessionDescriptionInit }) => {
  58. const { type, data } = value
  59. console.log('二级监听', value)
  60. // 接收远程offer
  61. if (type === 'offer') {
  62. console.log('offer', data)
  63. await RTC.Peer?.setRemoteDescription(data!)
  64. const answerd = await RTC.Peer?.createAnswer()
  65. await RTC.Peer?.setLocalDescription(answerd)
  66. }
  67. // 发送本地answer
  68. if (type === 'answer') {
  69. console.log('send answer', data)
  70. mqtt.send(JSON.stringify(data))
  71. }
  72. })
  73. onMounted(() => RTC.initRTC(remoteVideo.value))
  74. onUnmounted(() => RTC.distory())
  75. </script>
  76. <style lang="scss" scoped>
  77. .room {
  78. width: 100%;
  79. height: 100%;
  80. position: relative;
  81. &-bar {
  82. :deep(.topBar-content) {
  83. display: flex;
  84. align-items: flex-end;
  85. &>* {
  86. margin: 0 0 0 10px;
  87. }
  88. }
  89. }
  90. video {
  91. width: 100%;
  92. height: 100%;
  93. background: black;
  94. object-fit: fill;
  95. font-size: 0;
  96. z-index: 1;
  97. }
  98. &-gauge {
  99. width: 30vw;
  100. height: 15vw;
  101. max-width: 460px;
  102. max-height: 230px;
  103. position: absolute;
  104. bottom: 0;
  105. left: 50%;
  106. transform: translateX(-50%);
  107. z-index: 2;
  108. }
  109. }
  110. </style>