shuisheng 3 лет назад
Родитель
Сommit
0466b6f603

+ 2 - 0
src/layout/footer/index.vue

@@ -14,6 +14,8 @@ const billd: BilldHtmlWebpackPluginLog = process.env.BilldHtmlWebpackPlugin;
   position: fixed;
   bottom: 0;
   left: 50%;
+  width: 100%;
+  text-align: center;
   transform: translateX(-50%);
 }
 </style>

+ 0 - 418
src/old/srs-flv-pull/index.vue

@@ -1,418 +0,0 @@
-<template>
-  <div class="srs-flv-pull-wrap">
-    <template v-if="roomNoLive">当前房间没在直播~</template>
-    <template v-else>
-      <div class="left">
-        <div
-          ref="topRef"
-          class="head"
-        >
-          <div class="info">
-            <div class="avatar"></div>
-            <div class="detail">
-              <div class="top">房间名:{{ roomName }}</div>
-              <div class="bottom">
-                <span>你的socketId:{{ getSocketId() }}</span>
-              </div>
-            </div>
-          </div>
-        </div>
-        <div class="video-wrap">
-          <video
-            id="localVideo"
-            ref="localVideoRef"
-            autoplay
-            webkit-playsinline="true"
-            playsinline
-            x-webkit-airplay="allow"
-            x5-video-player-type="h5"
-            x5-video-player-fullscreen="true"
-            x5-video-orientation="portraint"
-            :muted="appStore.muted"
-          ></video>
-          <div class="controls">
-            <VideoControls></VideoControls>
-          </div>
-        </div>
-        <div
-          ref="bottomRef"
-          class="gift"
-        >
-          <div
-            v-for="(item, index) in giftList"
-            :key="index"
-            class="item"
-          >
-            <div class="ico"></div>
-            <div class="name">{{ item.name }}</div>
-            <div class="price">{{ item.price }}</div>
-          </div>
-        </div>
-      </div>
-      <div class="right">
-        <div class="tab">
-          <span>在线用户</span>
-          <span> | </span>
-          <span>排行榜</span>
-        </div>
-        <div class="user-list">
-          <div
-            v-for="(item, index) in liveUserList.filter((item) =>
-              userStore.userInfo ? item.socketId !== getSocketId() : true
-            )"
-            :key="index"
-            class="item"
-          >
-            <div class="info">
-              <div class="avatar"></div>
-              <div class="username">{{ item.socketId }}</div>
-            </div>
-          </div>
-          <div
-            v-if="userStore.userInfo"
-            class="item"
-          >
-            <div class="info">
-              <img
-                :src="userStore.userInfo.avatar"
-                class="avatar"
-                alt=""
-              />
-              <div class="username">{{ userStore.userInfo.username }}</div>
-            </div>
-          </div>
-        </div>
-        <div class="danmu-list">
-          <div
-            v-for="(item, index) in damuList"
-            :key="index"
-            class="item"
-          >
-            <template v-if="item.msgType === DanmuMsgTypeEnum.danmu">
-              <span class="name">
-                {{ item.userInfo?.username || item.socketId }}:
-              </span>
-              <span class="msg">{{ item.msg }}</span>
-            </template>
-            <template v-else-if="item.msgType === DanmuMsgTypeEnum.otherJoin">
-              <span class="name system">系统通知:</span>
-              <span class="msg">
-                {{ item.userInfo?.username || item.socketId }}进入直播!
-              </span>
-            </template>
-            <template v-else-if="item.msgType === DanmuMsgTypeEnum.userLeaved">
-              <span class="name system">系统通知:</span>
-              <span class="msg">
-                {{ item.userInfo?.username || item.socketId }}离开直播!
-              </span>
-            </template>
-          </div>
-        </div>
-        <div class="send-msg">
-          <textarea
-            v-model="danmuStr"
-            class="ipt"
-            @keydown="keydownDanmu"
-          ></textarea>
-          <div
-            class="btn"
-            @click="sendDanmu"
-          >
-            发送
-          </div>
-        </div>
-      </div>
-    </template>
-  </div>
-</template>
-
-<script lang="ts" setup>
-import { onMounted, onUnmounted, ref } from 'vue';
-
-import { usePull } from '@/hooks/use-pull';
-import { DanmuMsgTypeEnum } from '@/interface';
-import { useAppStore } from '@/store/app';
-import { useUserStore } from '@/store/user';
-
-const userStore = useUserStore();
-const appStore = useAppStore();
-
-const topRef = ref<HTMLDivElement>();
-const bottomRef = ref<HTMLDivElement>();
-const localVideoRef = ref<HTMLVideoElement>();
-
-const {
-  initPull,
-  closeWs,
-  closeRtc,
-  getSocketId,
-  keydownDanmu,
-  sendDanmu,
-  roomName,
-  roomNoLive,
-  damuList,
-  giftList,
-  liveUserList,
-  danmuStr,
-} = usePull({ localVideoRef });
-
-onUnmounted(() => {
-  closeWs();
-  closeRtc();
-});
-
-onMounted(() => {
-  if (topRef.value && bottomRef.value && localVideoRef.value) {
-    const res =
-      bottomRef.value.getBoundingClientRect().top -
-      (topRef.value.getBoundingClientRect().top +
-        topRef.value.getBoundingClientRect().height);
-    localVideoRef.value.style.height = `${res}px`;
-  }
-  initPull();
-});
-</script>
-
-<style lang="scss" scoped>
-.srs-flv-pull-wrap {
-  margin: 20px auto 0;
-  min-width: $large-width;
-  height: 700px;
-  text-align: center;
-  .left {
-    position: relative;
-    display: inline-block;
-    box-sizing: border-box;
-    width: $large-left-width;
-    height: 100%;
-    border-radius: 6px;
-    background-color: white;
-    color: #9499a0;
-    vertical-align: top;
-    overflow: hidden;
-    .head {
-      display: flex;
-      justify-content: space-between;
-      padding: 20px;
-      background-color: papayawhip;
-      .tag {
-        display: inline-block;
-        margin-right: 5px;
-        padding: 1px 4px;
-        border: 1px solid;
-        border-radius: 2px;
-        color: #9499a0;
-        font-size: 12px;
-      }
-
-      .info {
-        display: flex;
-        align-items: center;
-        text-align: initial;
-
-        .avatar {
-          margin-right: 20px;
-          width: 64px;
-          height: 64px;
-          border-radius: 50%;
-          background-color: skyblue;
-        }
-        .detail {
-          .top {
-            margin-bottom: 10px;
-            color: #18191c;
-          }
-          .bottom {
-            font-size: 14px;
-          }
-        }
-      }
-      .other {
-        display: flex;
-        flex-direction: column;
-        justify-content: center;
-        font-size: 12px;
-        .top {
-          display: flex;
-          align-items: center;
-          .item {
-            display: flex;
-            align-items: center;
-            margin-right: 20px;
-            .ico {
-              display: inline-block;
-              margin-right: 4px;
-              width: 10px;
-              height: 10px;
-              border-radius: 50%;
-              background-color: skyblue;
-            }
-          }
-        }
-        .bottom {
-          margin-top: 10px;
-        }
-      }
-    }
-    .video-wrap {
-      position: relative;
-      background-color: #18191c;
-      #localVideo {
-        max-width: 100%;
-        max-height: 100%;
-      }
-      .controls {
-        display: none;
-      }
-      &:hover {
-        .controls {
-          display: block;
-        }
-      }
-    }
-    .gift {
-      position: absolute;
-      right: 0;
-      bottom: 0;
-      left: 0;
-      display: flex;
-      align-items: center;
-      justify-content: space-around;
-      height: 100px;
-      background-color: papayawhip;
-      .item {
-        margin-right: 10px;
-        text-align: center;
-
-        .ico {
-          width: 50px;
-          height: 50px;
-          background-color: skyblue;
-        }
-        .name {
-          color: #18191c;
-          font-size: 12px;
-        }
-        .price {
-          color: #9499a0;
-          font-size: 12px;
-        }
-      }
-    }
-  }
-  .right {
-    position: relative;
-    display: inline-block;
-    box-sizing: border-box;
-    margin-left: 10px;
-    min-width: 300px;
-    height: 100%;
-    border-radius: 6px;
-    background-color: papayawhip;
-    color: #9499a0;
-    .tab {
-      display: flex;
-      align-items: center;
-      justify-content: space-evenly;
-      padding: 5px 0;
-      font-size: 12px;
-    }
-    .user-list {
-      overflow-y: scroll;
-      padding: 0 15px;
-      height: 100px;
-      background-color: papayawhip;
-      .item {
-        display: flex;
-        align-items: center;
-        justify-content: space-between;
-        margin-bottom: 10px;
-        font-size: 12px;
-        .info {
-          display: flex;
-          align-items: center;
-          .avatar {
-            margin-right: 5px;
-            width: 25px;
-            height: 25px;
-            border-radius: 50%;
-            background-color: skyblue;
-          }
-          .username {
-            color: black;
-          }
-        }
-      }
-    }
-    .danmu-list {
-      overflow-y: scroll;
-      padding: 0 15px;
-      height: 450px;
-      text-align: initial;
-      .item {
-        margin-bottom: 10px;
-        font-size: 12px;
-        .name {
-          color: #9499a0;
-          &.system {
-            color: red;
-          }
-        }
-        .msg {
-          color: #61666d;
-        }
-      }
-    }
-    .send-msg {
-      position: absolute;
-      bottom: 15px;
-      box-sizing: border-box;
-      padding: 0 10px;
-      width: 100%;
-      .ipt {
-        display: block;
-        box-sizing: border-box;
-        margin: 0 auto;
-        padding: 10px;
-        width: 100%;
-        height: 60px;
-        outline: none;
-        border: 1px solid hsla(0, 0%, 60%, 0.2);
-        border-radius: 4px;
-        background-color: #f1f2f3;
-        font-size: 14px;
-      }
-      .btn {
-        box-sizing: border-box;
-        margin-top: 10px;
-        margin-left: auto;
-        padding: 5px;
-        width: 80px;
-        border-radius: 4px;
-        background-color: skyblue;
-        color: white;
-        text-align: center;
-        font-size: 12px;
-        cursor: pointer;
-      }
-    }
-  }
-}
-
-// 屏幕宽度小于$large-width的时候
-@media screen and (max-width: $large-width) {
-  .srs-flv-pull-wrap {
-    .left {
-      width: $medium-left-width;
-    }
-    .right {
-      .list {
-        .item {
-          width: 150px;
-          height: 80px;
-        }
-      }
-    }
-  }
-}
-</style>

+ 0 - 418
src/old/srs-webrtc-pull/index.vue

@@ -1,418 +0,0 @@
-<template>
-  <div class="srs-webrtc-pull-wrap">
-    <template v-if="roomNoLive">当前房间没在直播~</template>
-    <template v-else>
-      <div class="left">
-        <div
-          ref="topRef"
-          class="head"
-        >
-          <div class="info">
-            <div class="avatar"></div>
-            <div class="detail">
-              <div class="top">房间名:{{ roomName }}</div>
-              <div class="bottom">
-                <span>你的socketId:{{ getSocketId() }}</span>
-              </div>
-            </div>
-          </div>
-        </div>
-        <div class="video-wrap">
-          <video
-            id="localVideo"
-            ref="localVideoRef"
-            autoplay
-            webkit-playsinline="true"
-            playsinline
-            x-webkit-airplay="allow"
-            x5-video-player-type="h5"
-            x5-video-player-fullscreen="true"
-            x5-video-orientation="portraint"
-            :muted="appStore.muted"
-          ></video>
-          <div class="controls">
-            <VideoControls></VideoControls>
-          </div>
-        </div>
-        <div
-          ref="bottomRef"
-          class="gift"
-        >
-          <div
-            v-for="(item, index) in giftList"
-            :key="index"
-            class="item"
-          >
-            <div class="ico"></div>
-            <div class="name">{{ item.name }}</div>
-            <div class="price">{{ item.price }}</div>
-          </div>
-        </div>
-      </div>
-      <div class="right">
-        <div class="tab">
-          <span>在线用户</span>
-          <span> | </span>
-          <span>排行榜</span>
-        </div>
-        <div class="user-list">
-          <div
-            v-for="(item, index) in liveUserList.filter((item) =>
-              userStore.userInfo ? item.socketId !== getSocketId() : true
-            )"
-            :key="index"
-            class="item"
-          >
-            <div class="info">
-              <div class="avatar"></div>
-              <div class="username">{{ item.socketId }}</div>
-            </div>
-          </div>
-          <div
-            v-if="userStore.userInfo"
-            class="item"
-          >
-            <div class="info">
-              <img
-                :src="userStore.userInfo.avatar"
-                class="avatar"
-                alt=""
-              />
-              <div class="username">{{ userStore.userInfo.username }}</div>
-            </div>
-          </div>
-        </div>
-        <div class="danmu-list">
-          <div
-            v-for="(item, index) in damuList"
-            :key="index"
-            class="item"
-          >
-            <template v-if="item.msgType === DanmuMsgTypeEnum.danmu">
-              <span class="name">
-                {{ item.userInfo?.username || item.socketId }}:
-              </span>
-              <span class="msg">{{ item.msg }}</span>
-            </template>
-            <template v-else-if="item.msgType === DanmuMsgTypeEnum.otherJoin">
-              <span class="name system">系统通知:</span>
-              <span class="msg">
-                {{ item.userInfo?.username || item.socketId }}进入直播!
-              </span>
-            </template>
-            <template v-else-if="item.msgType === DanmuMsgTypeEnum.userLeaved">
-              <span class="name system">系统通知:</span>
-              <span class="msg">
-                {{ item.userInfo?.username || item.socketId }}离开直播!
-              </span>
-            </template>
-          </div>
-        </div>
-        <div class="send-msg">
-          <textarea
-            v-model="danmuStr"
-            class="ipt"
-            @keydown="keydownDanmu"
-          ></textarea>
-          <div
-            class="btn"
-            @click="sendDanmu"
-          >
-            发送
-          </div>
-        </div>
-      </div>
-    </template>
-  </div>
-</template>
-
-<script lang="ts" setup>
-import { onMounted, onUnmounted, ref } from 'vue';
-
-import { usePull } from '@/hooks/use-pull';
-import { DanmuMsgTypeEnum } from '@/interface';
-import { useAppStore } from '@/store/app';
-import { useUserStore } from '@/store/user';
-
-const userStore = useUserStore();
-const appStore = useAppStore();
-
-const topRef = ref<HTMLDivElement>();
-const bottomRef = ref<HTMLDivElement>();
-const localVideoRef = ref<HTMLVideoElement>();
-
-const {
-  initPull,
-  closeWs,
-  closeRtc,
-  getSocketId,
-  keydownDanmu,
-  sendDanmu,
-  roomName,
-  roomNoLive,
-  damuList,
-  giftList,
-  liveUserList,
-  danmuStr,
-} = usePull({ localVideoRef, isFlv: false, isSRS: true });
-
-onUnmounted(() => {
-  closeWs();
-  closeRtc();
-});
-
-onMounted(() => {
-  if (topRef.value && bottomRef.value && localVideoRef.value) {
-    const res =
-      bottomRef.value.getBoundingClientRect().top -
-      (topRef.value.getBoundingClientRect().top +
-        topRef.value.getBoundingClientRect().height);
-    localVideoRef.value.style.height = `${res}px`;
-  }
-  initPull();
-});
-</script>
-
-<style lang="scss" scoped>
-.srs-webrtc-pull-wrap {
-  margin: 20px auto 0;
-  min-width: $large-width;
-  height: 700px;
-  text-align: center;
-  .left {
-    position: relative;
-    display: inline-block;
-    box-sizing: border-box;
-    width: $large-left-width;
-    height: 100%;
-    border-radius: 6px;
-    background-color: white;
-    color: #9499a0;
-    vertical-align: top;
-    overflow: hidden;
-    .head {
-      display: flex;
-      justify-content: space-between;
-      padding: 20px;
-      background-color: papayawhip;
-      .tag {
-        display: inline-block;
-        margin-right: 5px;
-        padding: 1px 4px;
-        border: 1px solid;
-        border-radius: 2px;
-        color: #9499a0;
-        font-size: 12px;
-      }
-
-      .info {
-        display: flex;
-        align-items: center;
-        text-align: initial;
-
-        .avatar {
-          margin-right: 20px;
-          width: 64px;
-          height: 64px;
-          border-radius: 50%;
-          background-color: skyblue;
-        }
-        .detail {
-          .top {
-            margin-bottom: 10px;
-            color: #18191c;
-          }
-          .bottom {
-            font-size: 14px;
-          }
-        }
-      }
-      .other {
-        display: flex;
-        flex-direction: column;
-        justify-content: center;
-        font-size: 12px;
-        .top {
-          display: flex;
-          align-items: center;
-          .item {
-            display: flex;
-            align-items: center;
-            margin-right: 20px;
-            .ico {
-              display: inline-block;
-              margin-right: 4px;
-              width: 10px;
-              height: 10px;
-              border-radius: 50%;
-              background-color: skyblue;
-            }
-          }
-        }
-        .bottom {
-          margin-top: 10px;
-        }
-      }
-    }
-    .video-wrap {
-      position: relative;
-      background-color: #18191c;
-      #localVideo {
-        max-width: 100%;
-        max-height: 100%;
-      }
-      .controls {
-        display: none;
-      }
-      &:hover {
-        .controls {
-          display: block;
-        }
-      }
-    }
-    .gift {
-      position: absolute;
-      right: 0;
-      bottom: 0;
-      left: 0;
-      display: flex;
-      align-items: center;
-      justify-content: space-around;
-      height: 100px;
-      background-color: papayawhip;
-      .item {
-        margin-right: 10px;
-        text-align: center;
-
-        .ico {
-          width: 50px;
-          height: 50px;
-          background-color: skyblue;
-        }
-        .name {
-          color: #18191c;
-          font-size: 12px;
-        }
-        .price {
-          color: #9499a0;
-          font-size: 12px;
-        }
-      }
-    }
-  }
-  .right {
-    position: relative;
-    display: inline-block;
-    box-sizing: border-box;
-    margin-left: 10px;
-    min-width: 300px;
-    height: 100%;
-    border-radius: 6px;
-    background-color: papayawhip;
-    color: #9499a0;
-    .tab {
-      display: flex;
-      align-items: center;
-      justify-content: space-evenly;
-      padding: 5px 0;
-      font-size: 12px;
-    }
-    .user-list {
-      overflow-y: scroll;
-      padding: 0 15px;
-      height: 100px;
-      background-color: papayawhip;
-      .item {
-        display: flex;
-        align-items: center;
-        justify-content: space-between;
-        margin-bottom: 10px;
-        font-size: 12px;
-        .info {
-          display: flex;
-          align-items: center;
-          .avatar {
-            margin-right: 5px;
-            width: 25px;
-            height: 25px;
-            border-radius: 50%;
-            background-color: skyblue;
-          }
-          .username {
-            color: black;
-          }
-        }
-      }
-    }
-    .danmu-list {
-      overflow-y: scroll;
-      padding: 0 15px;
-      height: 450px;
-      text-align: initial;
-      .item {
-        margin-bottom: 10px;
-        font-size: 12px;
-        .name {
-          color: #9499a0;
-          &.system {
-            color: red;
-          }
-        }
-        .msg {
-          color: #61666d;
-        }
-      }
-    }
-    .send-msg {
-      position: absolute;
-      bottom: 15px;
-      box-sizing: border-box;
-      padding: 0 10px;
-      width: 100%;
-      .ipt {
-        display: block;
-        box-sizing: border-box;
-        margin: 0 auto;
-        padding: 10px;
-        width: 100%;
-        height: 60px;
-        outline: none;
-        border: 1px solid hsla(0, 0%, 60%, 0.2);
-        border-radius: 4px;
-        background-color: #f1f2f3;
-        font-size: 14px;
-      }
-      .btn {
-        box-sizing: border-box;
-        margin-top: 10px;
-        margin-left: auto;
-        padding: 5px;
-        width: 80px;
-        border-radius: 4px;
-        background-color: skyblue;
-        color: white;
-        text-align: center;
-        font-size: 12px;
-        cursor: pointer;
-      }
-    }
-  }
-}
-
-// 屏幕宽度小于$large-width的时候
-@media screen and (max-width: $large-width) {
-  .srs-webrtc-pull-wrap {
-    .left {
-      width: $medium-left-width;
-    }
-    .right {
-      .list {
-        .item {
-          width: 150px;
-          height: 80px;
-        }
-      }
-    }
-  }
-}
-</style>

+ 0 - 413
src/old/srs-webrtc-push/index.vue

@@ -1,413 +0,0 @@
-<template>
-  <div class="srs-webrtc-push-wrap">
-    <div
-      ref="topRef"
-      class="left"
-    >
-      <div class="video-wrap">
-        <video
-          id="localVideo"
-          ref="localVideoRef"
-          autoplay
-          webkit-playsinline="true"
-          playsinline
-          x-webkit-airplay="allow"
-          x5-video-player-type="h5"
-          x5-video-player-fullscreen="true"
-          x5-video-orientation="portraint"
-          muted
-        ></video>
-        <div
-          v-if="!currMediaTypeList || currMediaTypeList.length <= 0"
-          class="add-wrap"
-        >
-          <n-space>
-            <n-button
-              class="item"
-              @click="startGetUserMedia"
-            >
-              摄像头
-            </n-button>
-            <n-button
-              class="item"
-              @click="startGetDisplayMedia"
-            >
-              窗口
-            </n-button>
-          </n-space>
-        </div>
-      </div>
-      <div
-        ref="bottomRef"
-        class="control"
-      >
-        <div class="info">
-          <div
-            class="avatar"
-            :style="{ backgroundImage: `url(${userStore.userInfo?.avatar})` }"
-          ></div>
-          <div class="detail">
-            <div class="top">
-              <n-input-group>
-                <n-input
-                  v-model:value="roomName"
-                  size="small"
-                  placeholder="输入房间名"
-                  :style="{ width: '50%' }"
-                  :disabled="disabled"
-                />
-                <n-button
-                  size="small"
-                  type="primary"
-                  :disabled="disabled"
-                  @click="confirmRoomName"
-                >
-                  确定
-                </n-button>
-              </n-input-group>
-            </div>
-            <div class="bottom">
-              <span>socketId:{{ getSocketId() }}</span>
-            </div>
-          </div>
-        </div>
-        <div class="other">
-          <div class="top">
-            <span class="item">
-              <i class="ico"></i>
-              <span>正在观看人数:{{ liveUserList.length }}</span>
-            </span>
-          </div>
-          <div class="bottom">
-            <n-space>
-              <n-button
-                type="info"
-                size="small"
-                @click="startLive"
-              >
-                开始直播
-              </n-button>
-              <n-button
-                type="info"
-                size="small"
-                @click="endLive"
-              >
-                结束直播
-              </n-button>
-            </n-space>
-          </div>
-        </div>
-      </div>
-    </div>
-    <div class="right">
-      <div class="resource-card">
-        <div class="title">素材列表</div>
-        <div class="list">
-          <div
-            v-for="(item, index) in currMediaTypeList"
-            :key="index"
-            class="item"
-          >
-            <span class="name">{{ item.txt }}</span>
-          </div>
-        </div>
-      </div>
-      <div class="danmu-card">
-        <div class="title">弹幕互动</div>
-        <div class="list-wrap">
-          <div class="list">
-            <div
-              v-for="(item, index) in damuList"
-              :key="index"
-              class="item"
-            >
-              <template v-if="item.msgType === DanmuMsgTypeEnum.danmu">
-                <span class="name">{{ item.socketId }}:</span>
-                <span class="msg">{{ item.msg }}</span>
-              </template>
-              <template v-else-if="item.msgType === DanmuMsgTypeEnum.otherJoin">
-                <span class="name system">系统通知:</span>
-                <span class="msg">{{ item.socketId }}进入直播!</span>
-              </template>
-              <template
-                v-else-if="item.msgType === DanmuMsgTypeEnum.userLeaved"
-              >
-                <span class="name system">系统通知:</span>
-                <span class="msg">{{ item.socketId }}离开直播!</span>
-              </template>
-            </div>
-          </div>
-        </div>
-        <div class="send-msg">
-          <input
-            v-model="danmuStr"
-            class="ipt"
-            @keydown="keydownDanmu"
-          />
-          <n-button
-            type="info"
-            size="small"
-            @click="sendDanmu"
-          >
-            发送
-          </n-button>
-        </div>
-      </div>
-    </div>
-  </div>
-</template>
-
-<script lang="ts" setup>
-import { onMounted, onUnmounted, ref } from 'vue';
-
-import { usePush } from '@/hooks/use-push';
-import { DanmuMsgTypeEnum } from '@/interface';
-import { useUserStore } from '@/store/user';
-
-const userStore = useUserStore();
-
-const topRef = ref<HTMLDivElement>();
-const bottomRef = ref<HTMLDivElement>();
-const localVideoRef = ref<HTMLVideoElement>();
-
-const {
-  initPush,
-  confirmRoomName,
-  getSocketId,
-  startGetDisplayMedia,
-  startGetUserMedia,
-  startLive,
-  endLive,
-  closeWs,
-  closeRtc,
-  sendDanmu,
-  keydownDanmu,
-  disabled,
-  danmuStr,
-  roomName,
-  damuList,
-  liveUserList,
-  currMediaTypeList,
-} = usePush({
-  localVideoRef,
-  isSRS: true,
-});
-
-onUnmounted(() => {
-  closeWs();
-  closeRtc();
-});
-
-onMounted(() => {
-  initPush();
-  if (topRef.value && bottomRef.value && localVideoRef.value) {
-    const res =
-      bottomRef.value.getBoundingClientRect().top -
-      topRef.value.getBoundingClientRect().top;
-    localVideoRef.value.style.height = `100px`;
-    localVideoRef.value.style.height = `${res}px`;
-  }
-});
-</script>
-
-<style lang="scss" scoped>
-.srs-webrtc-push-wrap {
-  margin: 20px auto 0;
-  min-width: $large-width;
-  height: 700px;
-  text-align: center;
-  .left {
-    position: relative;
-    display: inline-block;
-    box-sizing: border-box;
-    width: $large-left-width;
-    height: 100%;
-    border-radius: 6px;
-    overflow: hidden;
-    background-color: white;
-    color: #9499a0;
-    vertical-align: top;
-
-    .video-wrap {
-      position: relative;
-      background-color: #18191c;
-      #localVideo {
-        max-width: 100%;
-        max-height: 100%;
-      }
-      .add-wrap {
-        position: absolute;
-        top: 50%;
-        left: 50%;
-        display: flex;
-        align-items: center;
-        justify-content: space-around;
-        padding: 0 20px;
-        height: 50px;
-        border-radius: 5px;
-        background-color: white;
-        transform: translate(-50%, -50%);
-      }
-    }
-    .control {
-      position: absolute;
-      right: 0;
-      bottom: 0;
-      left: 0;
-      display: flex;
-      justify-content: space-between;
-      padding: 20px;
-      background-color: papayawhip;
-
-      .info {
-        display: flex;
-        align-items: center;
-
-        .avatar {
-          margin-right: 20px;
-          width: 64px;
-          height: 64px;
-          border-radius: 50%;
-          background-color: skyblue;
-          background-position: center center;
-          background-size: cover;
-          background-repeat: no-repeat;
-        }
-        .detail {
-          display: flex;
-          flex-direction: column;
-          text-align: initial;
-          .top {
-            margin-bottom: 10px;
-            color: #18191c;
-            .btn {
-              margin-left: 10px;
-            }
-          }
-          .bottom {
-            font-size: 14px;
-          }
-        }
-      }
-      .other {
-        display: flex;
-        flex-direction: column;
-        justify-content: center;
-        font-size: 12px;
-        .top {
-          display: flex;
-          align-items: center;
-          .item {
-            display: flex;
-            align-items: center;
-            margin-right: 20px;
-            .ico {
-              display: inline-block;
-              margin-right: 4px;
-              width: 10px;
-              height: 10px;
-              border-radius: 50%;
-              background-color: skyblue;
-            }
-          }
-        }
-        .bottom {
-          margin-top: 10px;
-        }
-      }
-    }
-  }
-  .right {
-    position: relative;
-    display: inline-block;
-    box-sizing: border-box;
-    margin-left: 10px;
-    width: 240px;
-    height: 100%;
-    border-radius: 6px;
-    background-color: white;
-    color: #9499a0;
-
-    .resource-card {
-      box-sizing: border-box;
-      margin-bottom: 5%;
-      margin-bottom: 10px;
-      padding: 10px;
-      width: 100%;
-      height: 290px;
-      border-radius: 6px;
-      background-color: papayawhip;
-      .title {
-        text-align: initial;
-      }
-      .item {
-        display: flex;
-        align-items: center;
-        justify-content: space-between;
-        margin: 5px 0;
-        font-size: 12px;
-      }
-    }
-    .danmu-card {
-      box-sizing: border-box;
-      padding: 10px;
-      width: 100%;
-      height: 400px;
-      border-radius: 6px;
-      background-color: papayawhip;
-      text-align: initial;
-      .title {
-        margin-bottom: 10px;
-      }
-      .list {
-        margin-bottom: 10px;
-        height: 300px;
-        .item {
-          margin-bottom: 10px;
-          font-size: 12px;
-          .name {
-            color: #9499a0;
-          }
-          .msg {
-            color: #61666d;
-          }
-        }
-      }
-
-      .send-msg {
-        display: flex;
-        align-items: center;
-        box-sizing: border-box;
-        .ipt {
-          display: block;
-          box-sizing: border-box;
-          margin: 0 auto;
-          margin-right: 10px;
-          padding: 10px;
-          width: 80%;
-          height: 30px;
-          outline: none;
-          border: 1px solid hsla(0, 0%, 60%, 0.2);
-          border-radius: 4px;
-          background-color: #f1f2f3;
-          font-size: 14px;
-        }
-      }
-    }
-  }
-}
-// 屏幕宽度小于$large-width的时候
-@media screen and (max-width: $large-width) {
-  .srs-webrtc-push-wrap {
-    .left {
-      width: $medium-left-width;
-    }
-    .right {
-      .list {
-        .item {
-        }
-      }
-    }
-  }
-}
-</style>

+ 0 - 621
src/old/webrtc-pull/index.vue

@@ -1,621 +0,0 @@
-<template>
-  <div class="webrtc-pull-wrap">
-    <template v-if="roomNoLive">当前房间没在直播~</template>
-    <template v-else>
-      <div class="left">
-        <div
-          ref="topRef"
-          class="head"
-        >
-          <div class="info">
-            <div class="avatar"></div>
-            <div class="detail">
-              <div class="top">房间名:{{ roomName }}</div>
-              <div class="bottom">
-                <span>你的socketId:{{ getSocketId() }}</span>
-              </div>
-            </div>
-          </div>
-        </div>
-        <div class="video-wrap">
-          <video
-            id="localVideo"
-            ref="localVideoRef"
-            autoplay
-            webkit-playsinline="true"
-            playsinline
-            x-webkit-airplay="allow"
-            x5-video-player-type="h5"
-            x5-video-player-fullscreen="true"
-            x5-video-orientation="portraint"
-            muted
-          ></video>
-        </div>
-        <div
-          ref="bottomRef"
-          class="gift"
-        >
-          <div
-            v-for="(item, index) in giftList"
-            :key="index"
-            class="item"
-          >
-            <div class="ico"></div>
-            <div class="name">{{ item.name }}</div>
-            <div class="price">{{ item.price }}</div>
-          </div>
-        </div>
-      </div>
-      <div class="right">
-        <div class="tab">
-          <span>在线用户</span>
-          <span> | </span>
-          <span>排行榜</span>
-        </div>
-        <div class="user-list">
-          <div
-            v-for="(item, index) in liveUserList"
-            :key="index"
-            class="item"
-          >
-            <div class="info">
-              <div class="avatar"></div>
-              <div class="username">{{ item.socketId }}</div>
-            </div>
-            <div class="expr">{{ item.expr }}</div>
-          </div>
-        </div>
-        <div class="danmu-list">
-          <div
-            v-for="(item, index) in damuList"
-            :key="index"
-            class="item"
-          >
-            <template v-if="item.msgType === DanmuMsgTypeEnum.danmu">
-              <span class="name">{{ item.socketId }}:</span>
-              <span class="msg">{{ item.msg }}</span>
-            </template>
-            <template v-else-if="item.msgType === DanmuMsgTypeEnum.otherJoin">
-              <span class="name system">系统通知:</span>
-              <span class="msg">{{ item.socketId }}进入直播!</span>
-            </template>
-            <template v-else-if="item.msgType === DanmuMsgTypeEnum.userLeaved">
-              <span class="name system">系统通知:</span>
-              <span class="msg">{{ item.socketId }}离开直播!</span>
-            </template>
-          </div>
-        </div>
-        <div class="send-msg">
-          <textarea
-            v-model="danmuStr"
-            class="ipt"
-          ></textarea>
-          <div
-            class="btn"
-            @click="sendDanmu"
-          >
-            发送
-          </div>
-        </div>
-      </div>
-    </template>
-  </div>
-</template>
-
-<script lang="ts" setup>
-import { onMounted, onUnmounted, ref } from 'vue';
-import { useRoute } from 'vue-router';
-
-import {
-  DanmuMsgTypeEnum,
-  IAdminIn,
-  ICandidate,
-  IDanmu,
-  ILiveUser,
-  IOffer,
-} from '@/interface';
-import { WebRTCClass } from '@/network/webRtc';
-import {
-  WebSocketClass,
-  WsConnectStatusEnum,
-  WsMsgTypeEnum,
-} from '@/network/webSocket';
-import { useNetworkStore } from '@/store/network';
-
-const networkStore = useNetworkStore();
-const route = useRoute();
-
-const topRef = ref<HTMLDivElement>();
-const bottomRef = ref<HTMLDivElement>();
-const localVideoRef = ref<HTMLVideoElement>();
-const roomNoLive = ref(false);
-const roomId = ref('');
-const roomName = ref('');
-const danmuStr = ref('');
-const websocketInstant = ref<WebSocketClass>();
-const damuList = ref<IDanmu[]>([]);
-const liveUserList = ref<ILiveUser[]>([]);
-const giftList = ref([
-  { name: '鲜花', ico: '', price: '免费' },
-  { name: '肥宅水', ico: '', price: '2元' },
-  { name: '小鸡腿', ico: '', price: '3元' },
-  { name: '大鸡腿', ico: '', price: '5元' },
-  { name: '一杯咖啡', ico: '', price: '10元' },
-]);
-
-function closeWs() {
-  const instance = networkStore.wsMap.get(roomId.value);
-  if (!instance) return;
-  instance.close();
-}
-
-function closeRtc() {
-  networkStore.rtcMap.forEach((rtc) => {
-    rtc.close();
-  });
-}
-
-function getSocketId() {
-  return networkStore.wsMap.get(roomId.value!)?.socketIo?.id || '-1';
-}
-
-function sendJoin() {
-  const instance = networkStore.wsMap.get(roomId.value);
-  if (!instance) return;
-  instance.send({ msgType: WsMsgTypeEnum.join, data: {} });
-}
-
-function sendDanmu() {
-  if (!danmuStr.value.length) {
-    alert('请输入弹幕内容!');
-  }
-  if (!websocketInstant.value) return;
-  websocketInstant.value.send({
-    msgType: WsMsgTypeEnum.message,
-    data: { msg: danmuStr.value },
-  });
-  damuList.value.push({
-    socketId: getSocketId(),
-    msgType: DanmuMsgTypeEnum.danmu,
-    msg: danmuStr.value,
-  });
-  danmuStr.value = '';
-}
-
-function startNewWebRtc(receiver: string) {
-  console.warn('开始new WebRTCClass', receiver);
-  const rtc = new WebRTCClass({ roomId: `${roomId.value}___${receiver}` });
-  rtc.rtcStatus.joined = true;
-  rtc.update();
-  return rtc;
-}
-
-function initReceive() {
-  const instance = websocketInstant.value;
-  if (!instance?.socketIo) return;
-  // websocket连接成功
-  instance.socketIo.on(WsConnectStatusEnum.connect, () => {
-    console.log('【websocket】websocket连接成功', instance.socketIo?.id);
-    if (!instance) return;
-    instance.status = WsConnectStatusEnum.connect;
-    instance.update();
-  });
-
-  // websocket连接断开
-  instance.socketIo.on(WsConnectStatusEnum.disconnect, () => {
-    console.log('【websocket】websocket连接断开', instance);
-    if (!instance) return;
-    instance.status = WsConnectStatusEnum.disconnect;
-    instance.update();
-  });
-
-  // 当前所有在线用户
-  instance.socketIo.on(WsMsgTypeEnum.roomLiveing, (data: IAdminIn) => {
-    console.log('【websocket】收到管理员正在直播', data);
-  });
-
-  // 当前所有在线用户
-  instance.socketIo.on(WsMsgTypeEnum.roomNoLive, (data: IAdminIn) => {
-    console.log('【websocket】收到管理员不在直播', data);
-    roomNoLive.value = true;
-    closeRtc();
-  });
-
-  // 当前所有在线用户
-  instance.socketIo.on(WsMsgTypeEnum.liveUser, (data) => {
-    console.log('【websocket】当前所有在线用户', data);
-    if (!instance) return;
-    liveUserList.value = data.map((item) => ({
-      avatar: 'red',
-      socketId: item.id,
-      expr: 1,
-    }));
-  });
-
-  // 收到offer
-  instance.socketIo.on(WsMsgTypeEnum.offer, async (data: IOffer) => {
-    console.warn('【websocket】收到offer', data);
-    if (!instance) return;
-    if (data.data.receiver === getSocketId()) {
-      console.log('收到offer,这个offer是发给我的');
-      const rtc = startNewWebRtc(data.data.sender);
-      await rtc.setRemoteDescription(data.data.sdp);
-      const sdp = await rtc.createAnswer();
-      await rtc.setLocalDescription(sdp);
-      websocketInstant.value?.send({
-        msgType: WsMsgTypeEnum.answer,
-        data: { sdp, sender: getSocketId(), receiver: data.data.sender },
-      });
-    } else {
-      console.log('收到offer,但是这个offer不是发给我的');
-    }
-  });
-
-  // 收到answer
-  instance.socketIo.on(WsMsgTypeEnum.answer, async (data: IOffer) => {
-    console.warn('【websocket】收到answer', data);
-    if (!instance) return;
-    const rtc = networkStore.getRtcMap(`${roomId.value}___${data.socketId}`);
-    console.log(rtc, '收到answer收到answer');
-    if (!rtc) return;
-    rtc.rtcStatus.answer = true;
-    rtc.update();
-    if (data.data.receiver === getSocketId()) {
-      console.log('收到answer,这个answer是发给我的');
-      await rtc.setRemoteDescription(data.data.sdp);
-    } else {
-      console.log('收到answer,但这个answer不是发给我的');
-    }
-  });
-
-  // 收到candidate
-  instance.socketIo.on(WsMsgTypeEnum.candidate, (data: ICandidate) => {
-    console.warn('【websocket】收到candidate', data);
-    if (!instance) return;
-    const rtc =
-      networkStore.getRtcMap(`${roomId.value}___${data.socketId}`) ||
-      networkStore.getRtcMap(roomId.value);
-    if (!rtc) return;
-    if (data.socketId !== getSocketId()) {
-      console.log('不是我发的candidate');
-      const candidate = new RTCIceCandidate({
-        sdpMid: data.data.sdpMid,
-        sdpMLineIndex: data.data.sdpMLineIndex,
-        candidate: data.data.candidate,
-      });
-      rtc.peerConnection
-        ?.addIceCandidate(candidate)
-        .then(() => {
-          console.log('candidate成功');
-        })
-        .catch((err) => {
-          console.error('candidate失败', err);
-        });
-    } else {
-      console.log('是我发的candidate');
-    }
-  });
-
-  // 收到用户发送消息
-  instance.socketIo.on(WsMsgTypeEnum.message, (data) => {
-    console.log('【websocket】收到用户发送消息', data);
-    if (!instance) return;
-    damuList.value.push({
-      socketId: data.socketId,
-      msgType: DanmuMsgTypeEnum.danmu,
-      msg: data.data.msg,
-    });
-  });
-
-  // 用户加入房间完成
-  instance.socketIo.on(WsMsgTypeEnum.joined, (data) => {
-    console.log('【websocket】用户加入房间完成', data);
-    roomName.value = data.data.roomName;
-  });
-
-  // 其他用户加入房间
-  instance.socketIo.on(WsMsgTypeEnum.otherJoin, (data) => {
-    console.log('【websocket】其他用户加入房间', data);
-    damuList.value.push({
-      socketId: data.data.socketId,
-      msgType: DanmuMsgTypeEnum.otherJoin,
-      msg: '',
-    });
-  });
-
-  // 用户离开房间
-  instance.socketIo.on(WsMsgTypeEnum.leave, (data) => {
-    console.log('【websocket】用户离开房间', data);
-    if (!instance) return;
-    instance.socketIo?.emit(WsMsgTypeEnum.leave, {
-      roomId: instance.roomId,
-    });
-  });
-
-  // 用户离开房间完成
-  instance.socketIo.on(WsMsgTypeEnum.leaved, (data) => {
-    console.log('【websocket】用户离开房间完成', data);
-    if (!instance) return;
-    const res = liveUserList.value.filter(
-      (item) => item.socketId !== data.socketId
-    );
-    liveUserList.value = res;
-    damuList.value.push({
-      socketId: data.socketId,
-      msgType: DanmuMsgTypeEnum.userLeaved,
-      msg: '',
-    });
-  });
-}
-
-onUnmounted(() => {
-  closeWs();
-});
-
-onMounted(() => {
-  if (topRef.value && bottomRef.value && localVideoRef.value) {
-    const res =
-      bottomRef.value.getBoundingClientRect().top -
-      (topRef.value.getBoundingClientRect().top +
-        topRef.value.getBoundingClientRect().height);
-    localVideoRef.value.style.height = `${res}px`;
-  }
-  roomId.value = route.params.roomId as string;
-  console.warn('开始new WebSocketClass');
-  websocketInstant.value = new WebSocketClass({
-    roomId: roomId.value,
-    url:
-      process.env.NODE_ENV === 'development'
-        ? 'ws://localhost:4300'
-        : 'wss://live.hsslive.cn',
-    isAdmin: false,
-  });
-  websocketInstant.value.update();
-  initReceive();
-  sendJoin();
-
-  localVideoRef.value?.addEventListener('loadstart', () => {
-    console.warn('视频流-loadstart');
-    const rtc = networkStore.getRtcMap(roomId.value);
-    if (!rtc) return;
-    rtc.rtcStatus.loadstart = true;
-    rtc.update();
-  });
-
-  localVideoRef.value?.addEventListener('loadedmetadata', () => {
-    console.warn('视频流-loadedmetadata');
-    const rtc = networkStore.getRtcMap(roomId.value);
-    if (!rtc) return;
-    rtc.rtcStatus.loadedmetadata = true;
-    rtc.update();
-  });
-});
-</script>
-
-<style lang="scss" scoped>
-.webrtc-pull-wrap {
-  margin: 20px auto 0;
-  min-width: $large-width;
-  height: 700px;
-  text-align: center;
-  .left {
-    position: relative;
-    display: inline-block;
-    overflow: hidden;
-    box-sizing: border-box;
-    width: $large-left-width;
-    height: 100%;
-    border-radius: 6px;
-    background-color: white;
-    color: #9499a0;
-    vertical-align: top;
-    .head {
-      display: flex;
-      justify-content: space-between;
-      padding: 20px;
-      background-color: papayawhip;
-
-      .info {
-        display: flex;
-        align-items: center;
-        text-align: initial;
-
-        .avatar {
-          margin-right: 20px;
-          width: 64px;
-          height: 64px;
-          border-radius: 50%;
-          background-color: skyblue;
-        }
-        .detail {
-          .top {
-            margin-bottom: 10px;
-            color: #18191c;
-          }
-          .bottom {
-            font-size: 14px;
-          }
-        }
-      }
-      .other {
-        display: flex;
-        flex-direction: column;
-        justify-content: center;
-        font-size: 12px;
-        .top {
-          display: flex;
-          align-items: center;
-          .item {
-            display: flex;
-            align-items: center;
-            margin-right: 20px;
-            .ico {
-              display: inline-block;
-              margin-right: 4px;
-              width: 10px;
-              height: 10px;
-              border-radius: 50%;
-              background-color: skyblue;
-            }
-          }
-        }
-        .bottom {
-          margin-top: 10px;
-        }
-      }
-    }
-    .video-wrap {
-      // height: 100px;
-      // height: 550px;
-      background-color: #18191c;
-      #localVideo {
-        max-width: 100%;
-        max-height: 100%;
-      }
-    }
-    .gift {
-      position: absolute;
-      right: 0;
-      bottom: 0;
-      left: 0;
-      display: flex;
-      align-items: center;
-      justify-content: space-around;
-      height: 100px;
-      background-color: papayawhip;
-      .item {
-        margin-right: 10px;
-        text-align: center;
-
-        .ico {
-          width: 50px;
-          height: 50px;
-          background-color: skyblue;
-        }
-        .name {
-          color: #18191c;
-          font-size: 12px;
-        }
-        .price {
-          color: #9499a0;
-          font-size: 12px;
-        }
-      }
-    }
-  }
-  .right {
-    position: relative;
-    display: inline-block;
-    box-sizing: border-box;
-    margin-left: 10px;
-    min-width: 300px;
-    height: 100%;
-    border-radius: 6px;
-    background-color: papayawhip;
-    color: #9499a0;
-    .tab {
-      display: flex;
-      align-items: center;
-      justify-content: space-evenly;
-      padding: 5px 0;
-      font-size: 12px;
-    }
-    .user-list {
-      overflow-y: scroll;
-      padding: 0 15px;
-      height: 100px;
-      background-color: papayawhip;
-      .item {
-        display: flex;
-        align-items: center;
-        justify-content: space-between;
-        margin-bottom: 10px;
-        font-size: 12px;
-        .info {
-          display: flex;
-          align-items: center;
-          .avatar {
-            margin-right: 5px;
-            width: 25px;
-            height: 25px;
-            border-radius: 50%;
-            background-color: skyblue;
-          }
-          .username {
-            color: black;
-          }
-        }
-      }
-    }
-    .danmu-list {
-      overflow-y: scroll;
-      padding: 0 15px;
-      height: 450px;
-      text-align: initial;
-      .item {
-        margin-bottom: 10px;
-        font-size: 12px;
-        .name {
-          color: #9499a0;
-          &.system {
-            color: red;
-          }
-        }
-        .msg {
-          color: #61666d;
-        }
-      }
-    }
-    .send-msg {
-      position: absolute;
-      bottom: 15px;
-      box-sizing: border-box;
-      padding: 0 10px;
-      width: 100%;
-      .ipt {
-        display: block;
-        box-sizing: border-box;
-        margin: 0 auto;
-        padding: 10px;
-        width: 100%;
-        height: 60px;
-        outline: none;
-        border: 1px solid hsla(0, 0%, 60%, 0.2);
-        border-radius: 4px;
-        background-color: #f1f2f3;
-        font-size: 14px;
-      }
-      .btn {
-        box-sizing: border-box;
-        margin-top: 10px;
-        margin-left: auto;
-        padding: 5px;
-        width: 80px;
-        border-radius: 4px;
-        background-color: skyblue;
-        color: white;
-        text-align: center;
-        font-size: 12px;
-        cursor: pointer;
-      }
-    }
-  }
-}
-
-// 屏幕宽度小于$large-width的时候
-@media screen and (max-width: $large-width) {
-  .webrtc-pull-wrap {
-    .left {
-      width: $medium-left-width;
-    }
-    .right {
-      .list {
-        .item {
-          width: 150px;
-          height: 80px;
-        }
-      }
-    }
-  }
-}
-</style>

+ 0 - 415
src/old/webrtc-push/index.vue

@@ -1,415 +0,0 @@
-<template>
-  <div class="webrtc-push-wrap">
-    <div
-      ref="topRef"
-      class="left"
-    >
-      <div class="video-wrap">
-        <video
-          id="localVideo"
-          ref="localVideoRef"
-          autoplay
-          webkit-playsinline="true"
-          playsinline
-          x-webkit-airplay="allow"
-          x5-video-player-type="h5"
-          x5-video-player-fullscreen="true"
-          x5-video-orientation="portraint"
-          muted
-        ></video>
-        <div
-          v-if="!currMediaTypeList || currMediaTypeList.length <= 0"
-          class="add-wrap"
-        >
-          <n-space>
-            <n-button
-              class="item"
-              @click="startGetUserMedia"
-            >
-              摄像头
-            </n-button>
-            <n-button
-              class="item"
-              @click="startGetDisplayMedia"
-            >
-              窗口
-            </n-button>
-          </n-space>
-        </div>
-      </div>
-      <div
-        ref="bottomRef"
-        class="control"
-      >
-        <div class="info">
-          <div
-            class="avatar"
-            :style="{ backgroundImage: `url(${userStore.userInfo?.avatar})` }"
-          ></div>
-          <div class="detail">
-            <div class="top">
-              <n-input-group>
-                <n-input
-                  v-model:value="roomName"
-                  size="small"
-                  placeholder="输入房间名"
-                  :style="{ width: '50%' }"
-                  :disabled="disabled"
-                />
-                <n-button
-                  size="small"
-                  type="primary"
-                  :disabled="disabled"
-                  @click="confirmRoomName"
-                >
-                  确定
-                </n-button>
-              </n-input-group>
-            </div>
-            <div class="bottom">
-              <span>socketId:{{ getSocketId() }}</span>
-            </div>
-          </div>
-        </div>
-        <div class="other">
-          <div class="top">
-            <span class="item">
-              <i class="ico"></i>
-              <span>正在观看人数:{{ liveUserList.length }}</span>
-            </span>
-          </div>
-          <div class="bottom">
-            <n-space>
-              <n-button
-                type="info"
-                size="small"
-                @click="startLive"
-              >
-                开始直播
-              </n-button>
-              <n-button
-                type="info"
-                size="small"
-                @click="endLive"
-              >
-                结束直播
-              </n-button>
-            </n-space>
-          </div>
-        </div>
-      </div>
-    </div>
-    <div class="right">
-      <div class="resource-card">
-        <div class="title">素材列表</div>
-        <div class="list">
-          <div
-            v-for="(item, index) in currMediaTypeList"
-            :key="index"
-            class="item"
-          >
-            <span class="name">{{ item.txt }}</span>
-          </div>
-        </div>
-      </div>
-      <div class="danmu-card">
-        <div class="title">弹幕互动</div>
-        <div class="list-wrap">
-          <div class="list">
-            <div
-              v-for="(item, index) in damuList"
-              :key="index"
-              class="item"
-            >
-              <template v-if="item.msgType === DanmuMsgTypeEnum.danmu">
-                <span class="name">{{ item.socketId }}:</span>
-                <span class="msg">{{ item.msg }}</span>
-              </template>
-              <template v-else-if="item.msgType === DanmuMsgTypeEnum.otherJoin">
-                <span class="name system">系统通知:</span>
-                <span class="msg">{{ item.socketId }}进入直播!</span>
-              </template>
-              <template
-                v-else-if="item.msgType === DanmuMsgTypeEnum.userLeaved"
-              >
-                <span class="name system">系统通知:</span>
-                <span class="msg">{{ item.socketId }}离开直播!</span>
-              </template>
-            </div>
-          </div>
-        </div>
-        <div class="send-msg">
-          <input
-            v-model="danmuStr"
-            class="ipt"
-            @keydown="keydownDanmu"
-          />
-          <n-button
-            type="info"
-            size="small"
-            @click="sendDanmu"
-          >
-            发送
-          </n-button>
-        </div>
-      </div>
-    </div>
-  </div>
-</template>
-
-<script lang="ts" setup>
-import { onMounted, onUnmounted, ref } from 'vue';
-import { useRoute } from 'vue-router';
-
-import { usePush } from '@/hooks/use-push';
-import { DanmuMsgTypeEnum, liveTypeEnum } from '@/interface';
-import { useUserStore } from '@/store/user';
-
-const route = useRoute();
-const userStore = useUserStore();
-
-const topRef = ref<HTMLDivElement>();
-const bottomRef = ref<HTMLDivElement>();
-const localVideoRef = ref<HTMLVideoElement>();
-const liveType = route.query.liveType;
-
-const {
-  initPush,
-  confirmRoomName,
-  getSocketId,
-  startGetDisplayMedia,
-  startGetUserMedia,
-  startLive,
-  endLive,
-  closeWs,
-  closeRtc,
-  sendDanmu,
-  keydownDanmu,
-  disabled,
-  danmuStr,
-  roomName,
-  damuList,
-  liveUserList,
-  currMediaTypeList,
-} = usePush({
-  localVideoRef,
-  isSRS: liveType === liveTypeEnum.srsPush,
-});
-
-onUnmounted(() => {
-  closeWs();
-  closeRtc();
-});
-
-onMounted(() => {
-  initPush();
-  if (topRef.value && bottomRef.value && localVideoRef.value) {
-    const res =
-      bottomRef.value.getBoundingClientRect().top -
-      topRef.value.getBoundingClientRect().top;
-    localVideoRef.value.style.height = `${res}px`;
-  }
-});
-</script>
-
-<style lang="scss" scoped>
-.webrtc-push-wrap {
-  margin: 20px auto 0;
-  min-width: $large-width;
-  height: 700px;
-  text-align: center;
-  .left {
-    position: relative;
-    display: inline-block;
-    box-sizing: border-box;
-    width: $large-left-width;
-    height: 100%;
-    border-radius: 6px;
-    overflow: hidden;
-    background-color: white;
-    color: #9499a0;
-    vertical-align: top;
-
-    .video-wrap {
-      position: relative;
-      background-color: #18191c;
-      #localVideo {
-        max-width: 100%;
-        max-height: 100%;
-      }
-      .add-wrap {
-        position: absolute;
-        top: 50%;
-        left: 50%;
-        display: flex;
-        align-items: center;
-        justify-content: space-around;
-        padding: 0 20px;
-        height: 50px;
-        border-radius: 5px;
-        background-color: white;
-        transform: translate(-50%, -50%);
-      }
-    }
-    .control {
-      position: absolute;
-      right: 0;
-      bottom: 0;
-      left: 0;
-      display: flex;
-      justify-content: space-between;
-      padding: 20px;
-      background-color: papayawhip;
-
-      .info {
-        display: flex;
-        align-items: center;
-
-        .avatar {
-          margin-right: 20px;
-          width: 64px;
-          height: 64px;
-          border-radius: 50%;
-          background-color: skyblue;
-          background-position: center center;
-          background-size: cover;
-          background-repeat: no-repeat;
-        }
-        .detail {
-          display: flex;
-          flex-direction: column;
-          text-align: initial;
-          .top {
-            margin-bottom: 10px;
-            color: #18191c;
-            .btn {
-              margin-left: 10px;
-            }
-          }
-          .bottom {
-            font-size: 14px;
-          }
-        }
-      }
-      .other {
-        display: flex;
-        flex-direction: column;
-        justify-content: center;
-        font-size: 12px;
-        .top {
-          display: flex;
-          align-items: center;
-          .item {
-            display: flex;
-            align-items: center;
-            margin-right: 20px;
-            .ico {
-              display: inline-block;
-              margin-right: 4px;
-              width: 10px;
-              height: 10px;
-              border-radius: 50%;
-              background-color: skyblue;
-            }
-          }
-        }
-        .bottom {
-          margin-top: 10px;
-        }
-      }
-    }
-  }
-  .right {
-    position: relative;
-    display: inline-block;
-    box-sizing: border-box;
-    margin-left: 10px;
-    width: 240px;
-    height: 100%;
-    border-radius: 6px;
-    background-color: white;
-    color: #9499a0;
-
-    .resource-card {
-      box-sizing: border-box;
-      margin-bottom: 5%;
-      margin-bottom: 10px;
-      padding: 10px;
-      width: 100%;
-      height: 290px;
-      border-radius: 6px;
-      background-color: papayawhip;
-      .title {
-        text-align: initial;
-      }
-      .item {
-        display: flex;
-        align-items: center;
-        justify-content: space-between;
-        margin: 5px 0;
-        font-size: 12px;
-      }
-    }
-    .danmu-card {
-      box-sizing: border-box;
-      padding: 10px;
-      width: 100%;
-      height: 400px;
-      border-radius: 6px;
-      background-color: papayawhip;
-      text-align: initial;
-      .title {
-        margin-bottom: 10px;
-      }
-      .list {
-        margin-bottom: 10px;
-        height: 300px;
-        .item {
-          margin-bottom: 10px;
-          font-size: 12px;
-          .name {
-            color: #9499a0;
-          }
-          .msg {
-            color: #61666d;
-          }
-        }
-      }
-
-      .send-msg {
-        display: flex;
-        align-items: center;
-        box-sizing: border-box;
-        .ipt {
-          display: block;
-          box-sizing: border-box;
-          margin: 0 auto;
-          margin-right: 10px;
-          padding: 10px;
-          width: 80%;
-          height: 30px;
-          outline: none;
-          border: 1px solid hsla(0, 0%, 60%, 0.2);
-          border-radius: 4px;
-          background-color: #f1f2f3;
-          font-size: 14px;
-        }
-      }
-    }
-  }
-}
-// 屏幕宽度小于$large-width的时候
-@media screen and (max-width: $large-width) {
-  .webrtc-push-wrap {
-    .left {
-      width: $medium-left-width;
-    }
-    .right {
-      .list {
-        .item {
-        }
-      }
-    }
-  }
-}
-</style>