gemercheung 2 rokov pred
rodič
commit
299c675573

+ 1 - 1
.env.eur

@@ -20,5 +20,5 @@ VITE_APP_APIS_URL=https://testeur.4dkankan.com/
 # VITE_TAKE_LOOK_API=https://testeur.4dkankan.com/
 VITE_USE_HTTPS=1
 VITE_PUBLIC_DIR='/livestream/'
-VITE_ROOM_MEMBER=10
+VITE_ROOM_MEMBER=4
 VITE_SHOW_CONSOLE=1

+ 108 - 0
src/components/chatRoom/camera copy.vue

@@ -0,0 +1,108 @@
+<template>
+  <teleport to=".local" v-if="(isRTCJoined || isPublished) && isLeader">
+    <div class="micBox">
+      <i class="speak_mic" v-if="!roomLeader?.IsMuted"></i>
+      <i class="speak_mic_off" v-else></i>
+    </div>
+  </teleport>
+  <teleport to=".remote" v-if="!isLeader && remoteStreams.length > 0">
+    <div class="micBox">
+      <i class="speak_mic" v-if="!roomLeader?.IsMuted"></i>
+      <i class="speak_mic_off" v-else></i>
+    </div>
+  </teleport>
+</template>
+<script lang="ts" setup>
+  //   import { ref } from 'vue';
+
+  import { computed, onMounted } from 'vue';
+  // import { useRtcSdk } from '/@/hooks/useTRTC';
+  // import { useSocket } from '/@/hooks/userSocket';
+
+  //   import { useRtcSdk } from '/@/hooks/useTRTC';
+  import { useRtcStore } from '/@/store/modules/rtc';
+
+  const rtcStore = useRtcStore();
+  // const destination = computed(() => (rtcStore.isLeader ? '.local' : '.remote'));
+  const isPublished = computed(() => rtcStore.isPublished);
+  const isRTCJoined = computed(() => rtcStore.isRTCJoined);
+  const isLeader = computed(() => rtcStore.isLeader);
+  const remoteStreams = computed(() => rtcStore.remoteStreams);
+  const roomLeader = computed(() => rtcStore.getRoomLeader());
+  // const { muteVideoLeader } = useRtcSdk();
+  // const hasVideo = computed(() => rtcStore.videoDeviceId.length > 0);
+  onMounted(() => {});
+</script>
+<style lang="scss">
+  #PageRtcLive {
+    &.leader + div.local {
+      + div.remote {
+        display: none;
+      }
+    }
+    &.customer + div.local {
+      display: none;
+    }
+  }
+  #PageRtcLive {
+    &.hideCam + div.local {
+      display: none;
+      + div.remote {
+        display: none;
+      }
+    }
+  }
+  .local,
+  .remote {
+    width: 1.94rem;
+    height: 1.94rem;
+    position: fixed;
+    top: 0.69rem;
+    left: 0.53rem;
+    overflow: hidden;
+    z-index: 10000;
+    border-radius: 50%;
+    video {
+      background: transparent;
+    }
+    .micBox {
+      width: 100%;
+      height: 0.44rem;
+      background: rgba(0, 0, 0, 0.3);
+      position: absolute;
+      left: 0;
+      bottom: 0;
+      z-index: 100;
+      display: flex;
+      align-items: center;
+      justify-content: center;
+      .speak_mic {
+        display: block;
+        background-size: 720px auto;
+        width: 12px;
+        height: 12px;
+        background-image: url(/@/assets/images/rtcLive/speed.png);
+        // width: 0.69rem;
+        // height: 0.69rem;
+        animation: myAnimation 3s steps(59) infinite;
+      }
+      .speak_mic_off {
+        display: block;
+        background-size: center center;
+        background-size: contain;
+        width: 12px;
+        height: 12px;
+        background-image: url(/@/assets/images/rtcLive/scene_mic_off@2x.png);
+      }
+    }
+  }
+  @keyframes myAnimation {
+    0% {
+      background-position: 0px 0px;
+    }
+
+    100% {
+      background-position: -708px 0px;
+    }
+  }
+</style>

+ 41 - 40
src/components/chatRoom/camera.vue

@@ -1,59 +1,47 @@
 <template>
-  <teleport to=".local" v-if="(isRTCJoined || isPublished) && isLeader">
-    <div class="micBox">
+  <div
+    :id="cameraBoxId"
+    class="camera_box"
+    v-show="isLeader && isPublished && isPanoramaMode && !muteVideoLeader"
+  >
+    <span class="micBox">
       <i class="speak_mic" v-if="!roomLeader?.IsMuted"></i>
       <i class="speak_mic_off" v-else></i>
-    </div>
-  </teleport>
-  <teleport to=".remote" v-if="!isLeader && remoteStreams.length > 0">
-    <div class="micBox">
+    </span>
+  </div>
+  <div
+    :id="cameraRemoveBoxId"
+    class="camera_box"
+    v-show="!isLeader && isPublished && roomLeader && isPanoramaMode && !muteVideoLeader"
+  >
+    <span class="micBox">
       <i class="speak_mic" v-if="!roomLeader?.IsMuted"></i>
       <i class="speak_mic_off" v-else></i>
-    </div>
-  </teleport>
+    </span>
+  </div>
 </template>
 <script lang="ts" setup>
-  //   import { ref } from 'vue';
-
   import { computed, onMounted } from 'vue';
-  // import { useRtcSdk } from '/@/hooks/useTRTC';
-  // import { useSocket } from '/@/hooks/userSocket';
-
-  //   import { useRtcSdk } from '/@/hooks/useTRTC';
+  import { useAppStore } from '/@/store/modules/app';
+  import { useRtcSdk } from '/@/hooks/useTRTC';
   import { useRtcStore } from '/@/store/modules/rtc';
 
   const rtcStore = useRtcStore();
+  const appStore = useAppStore();
   // const destination = computed(() => (rtcStore.isLeader ? '.local' : '.remote'));
   const isPublished = computed(() => rtcStore.isPublished);
-  const isRTCJoined = computed(() => rtcStore.isRTCJoined);
+  // const isRTCJoined = computed(() => rtcStore.isRTCJoined);
   const isLeader = computed(() => rtcStore.isLeader);
-  const remoteStreams = computed(() => rtcStore.remoteStreams);
+  // const remoteStreams = computed(() => rtcStore.remoteStreams);
   const roomLeader = computed(() => rtcStore.getRoomLeader());
-  // const { muteVideoLeader } = useRtcSdk();
-  // const hasVideo = computed(() => rtcStore.videoDeviceId.length > 0);
+  const cameraBoxId = computed(() => 'camera_box_' + rtcStore.userId);
+  const cameraRemoveBoxId = computed(() => 'camera_remote_box_' + rtcStore.userId);
+  const isPanoramaMode = computed(() => appStore.mode === 'panorama');
+  const { muteVideoLeader } = useRtcSdk();
   onMounted(() => {});
 </script>
 <style lang="scss">
-  #PageRtcLive {
-    &.leader + div.local {
-      + div.remote {
-        display: none;
-      }
-    }
-    &.customer + div.local {
-      display: none;
-    }
-  }
-  #PageRtcLive {
-    &.hideCam + div.local {
-      display: none;
-      + div.remote {
-        display: none;
-      }
-    }
-  }
-  .local,
-  .remote {
+  .camera_box {
     width: 1.94rem;
     height: 1.94rem;
     position: fixed;
@@ -63,7 +51,19 @@
     z-index: 10000;
     border-radius: 50%;
     video {
-      background: transparent;
+      display: none;
+    }
+    video:last-child {
+      display: block;
+    }
+    > div {
+      background-color: transparent !important;
+      position: absolute !important;
+      top: 0;
+      left: 0;
+      right: 0;
+      bottom: 0;
+      z-index: 10;
     }
     .micBox {
       width: 100%;
@@ -71,7 +71,8 @@
       background: rgba(0, 0, 0, 0.3);
       position: absolute;
       left: 0;
-      bottom: 0;
+      bottom: 0 !important;
+      top: unset;
       z-index: 100;
       display: flex;
       align-items: center;

+ 13 - 10
src/components/chatRoom/controls/actions.ts

@@ -98,7 +98,7 @@ export function handleActions({
       break;
   }
   if (members?.length) {
-    console.log('发烧的', members);
+    console.log('服务器的', members);
   }
 }
 
@@ -167,6 +167,17 @@ function handleUserJoin(members?: UserInfoType[], user?: UserInfoType) {
       Dialog.toast({ content: t('action.hosterEnterRoom') });
       socket.emit('action', { type: 'user-init' });
       socket.emit('sync-floor', { floorId: appStore.floorId });
+      rtcStore.setHosterOnline(true);
+    } else {
+      if (rtcStore.isLeader) {
+        const { socket } = useSocket();
+        console.log('进入,主持人禁音', user.UserId);
+        socket.emit('action', {
+          type: 'users-muted',
+          muted: true,
+          userId: user.UserId,
+        });
+      }
     }
     const data: ChatContentType = {
       role: user?.Role,
@@ -175,15 +186,6 @@ function handleUserJoin(members?: UserInfoType[], user?: UserInfoType) {
       UserId: user?.UserId,
       text: t('action.enterRoom'),
     };
-    // if (rtcStore.isLeader) {
-    //   rtcStore.addToChatList(data);
-    //   // const { socket } = useSocket();
-    //   // const { currentScene } = useRoom();
-    //   // socket.emit('action', {
-    //   //   type: 'changeScene',
-    //   //   data: currentScene.value,
-    //   // });
-    // }
 
     if (rtcStore.isLeader) {
       console.log('主持人看到', data);
@@ -305,6 +307,7 @@ const handleUserLeave = (user?: UserInfoType, members?: UserInfoType[]) => {
     if (user.Role == 'leader') {
       name = t('action.hoster');
       Dialog.toast({ content: t('action.hostExitRoom') });
+      rtcStore.setHosterOnline(false);
     }
     const data = {
       role: user.Role,

+ 0 - 10
src/components/chatRoom/controls/join.ts

@@ -71,11 +71,6 @@ export function handleJoin(data: any) {
       socket.emit('action', {
         type: 'ask-currentscene',
       });
-      socket.emit('action', {
-        type: 'users-muted',
-        muted: true,
-        userId: rtcStore.userId,
-      });
     } else {
       const { currentScene } = useRoom();
       console.log('currentScene', unref(currentScene));
@@ -83,11 +78,6 @@ export function handleJoin(data: any) {
         type: 'changeScene',
         data: unref(currentScene),
       });
-      socket.emit('action', {
-        type: 'users-muted',
-        muted: user.IsMuted,
-        userId: rtcStore.userId,
-      });
     }
   }, 1500);
 }

+ 7 - 2
src/components/chatRoom/index.vue

@@ -2,7 +2,11 @@
   <!-- 主区域 start  -->
   <div
     id="PageRtcLive"
-    :class="{ [role]: true, showCam: !muteVideoLeader, hideCam: muteVideoLeader }"
+    :class="{
+      [role]: true,
+      showCam: !muteVideoLeader,
+      hideCam: muteVideoLeader || !isPanoramaMode,
+    }"
   >
     <chat v-show="chatShow && isPanoramaMode" :chatList="chatList" :currentUser="currentUser" />
     <!-- 当前人数 start -->
@@ -14,7 +18,7 @@
       >
     </div>
     <!-- 视频头像 start -->
-    <Camera v-show="isPanoramaMode" />
+    <Camera />
     <!-- 视频头像 end -->
     <!-- {{ selfRoomStatus }} -->
     <!-- <div class="room_valid" v-if="isPanoramaMode && roomCounter > 0 && isNativeLeader">
@@ -265,6 +269,7 @@
     const { createRTCSocket } = useRtcSdk();
 
     (async () => {
+      await nextTick();
       await initialRoom();
       await createRTCSocket();
     })();

+ 15 - 4
src/hooks/useTRTC.ts

@@ -128,11 +128,13 @@ async function handleJoin() {
 
   await createLocalStream();
   await handlePublish();
+  await nextTick();
   //
   // setTimeout(() => {
   const playLocal = () => {
+    const playId = 'camera_box_' + rtcStore.userId;
     localStream
-      .play('local')
+      .play(playId)
       .then(() => {
         consola.info({
           message: '本地采集成功!',
@@ -394,11 +396,12 @@ async function handleStreamSubscribed(event) {
   }
   await nextTick();
   const playRemote = () => {
+    const playId = 'camera_remote_box_' + rtcStore.userId;
     remoteStream
-      .play(remoteId)
+      .play(playId)
       .then(() => {
         consola.info({
-          message: '远端采集成功!' + remoteId,
+          message: '远端采集成功 playId: ' + playId + ' remoteId:' + remoteId,
           tag: 'rtc:audio',
         });
       })
@@ -454,11 +457,19 @@ function handleStreamRemoved(event) {
   const userId = remoteStream.getUserId();
   const remoteStreamId = remoteStream.getId();
   consola.info({
-    message: `RemoteStream removed: [${userId},${remoteStreamId}]`,
+    message: `远端流删除: [${userId},${remoteStreamId}]`,
     tag: 'rtc:audio',
   });
   const rtcStore = useRtcStore();
   rtcStore.removeRemoteStreams(remoteStreamId);
+  const node = document.getElementById(`player_` + remoteStreamId);
+  consola.info({
+    message: `远端流删除:` + node,
+    tag: 'rtc:audio',
+  });
+  if (node) {
+    console.log('node', node);
+  }
 }
 
 function handleStreamUpdated(event) {

+ 2 - 2
src/main.ts

@@ -8,7 +8,7 @@ import { setupStore } from '/@/store';
 import App from './App.vue';
 import registerComponent from '/@/components/registerComponent';
 import { setupI18n } from '/@/locales/setupI18n';
-import ClickOutSide from '/@/utils/ClickOutSide';
+// import ClickOutSide from '/@/utils/ClickOutSide';
 // import Components from "./global_components";
 
 async function bootstrap() {
@@ -18,7 +18,7 @@ async function bootstrap() {
   setupStore(app);
   app.use(registerComponent);
   await setupI18n(app);
-  app.directive('click-outside', ClickOutSide);
+  // app.directive('click-outside', ClickOutSide);
   app.mount('#app');
 }
 

+ 5 - 0
src/store/modules/rtc.ts

@@ -37,6 +37,7 @@ interface RtcState {
   ifBaseDialog: boolean;
   baseDiaLogCallback?: () => void;
   connectStatus: number;
+  isHosterOnline: boolean;
 }
 
 interface DeviceListParams {
@@ -126,6 +127,7 @@ export const useRtcStore = defineStore({
     baseDialog: defaultBaseDialog,
     ifBaseDialog: false,
     connectStatus: 0,
+    isHosterOnline: true,
   }),
   persist: [
     {
@@ -319,5 +321,8 @@ export const useRtcStore = defineStore({
     setConnectStatus(status: number) {
       this.connectStatus = status;
     },
+    setHosterOnline(status: boolean) {
+      this.isHosterOnline = status;
+    },
   },
 });