Răsfoiți Sursa

fix: 优化

shuisheng 1 an în urmă
părinte
comite
a112a39b11

+ 35 - 8
src/hooks/use-play.ts

@@ -7,6 +7,7 @@ import Player from 'video.js/dist/types/player';
 import { onMounted, onUnmounted, ref, watch } from 'vue';
 
 import { SRS_CB_URL_QUERY } from '@/constant';
+import { LiveLineEnum } from '@/interface';
 import { useAppStore } from '@/store/app';
 import { useCacheStore } from '@/store/cache';
 import { useUserStore } from '@/store/user';
@@ -98,6 +99,7 @@ export function useFlvPlay() {
   // const flvPlayer = ref<flvJs.Player>();
   const flvPlayer = ref<mpegts.Player>();
   const flvVideoEl = ref<HTMLVideoElement>();
+  const appendVideoEl = ref<HTMLVideoElement>();
   const initRetryMax = 120;
   const retryMax = ref(initRetryMax);
   const retry = ref(0);
@@ -135,6 +137,15 @@ export function useFlvPlay() {
     }
   }
 
+  watch(
+    () => appStore.liveLine,
+    (newval) => {
+      if (newval !== LiveLineEnum.flv) {
+        appendVideoEl.value?.remove();
+      }
+    }
+  );
+
   watch(
     () => appStore.playing,
     (newVal) => {
@@ -202,25 +213,28 @@ export function useFlvPlay() {
             isLive: true,
             url: handlePlayUrl(data.flvurl),
           });
-          const videoEl = createVideo({
+          appendVideoEl.value = createVideo({
             appendChild: true,
             muted: appStore.pageIsClick ? cacheStore.muted : true,
             autoplay: true,
           });
-          videoEl.addEventListener('play', () => {
+          appendVideoEl.value.addEventListener('play', () => {
             console.log('flv-play');
           });
-          videoEl.addEventListener('playing', () => {
+          appendVideoEl.value.addEventListener('playing', () => {
             console.log('flv-playing');
             flvIsPlaying.value = true;
             retry.value = 0;
-            flvVideoEl.value = videoEl;
+            flvVideoEl.value = appendVideoEl.value;
+            if (flvVideoEl.value) {
+              flvVideoEl.value.muted = cacheStore.muted;
+            }
             resolve('');
           });
-          videoEl.addEventListener('loadedmetadata', () => {
+          appendVideoEl.value.addEventListener('loadedmetadata', () => {
             console.log('flv-loadedmetadata');
           });
-          flvPlayer.value.attachMediaElement(videoEl);
+          flvPlayer.value.attachMediaElement(appendVideoEl.value);
           flvPlayer.value.load();
           flvPlayer.value.on(mpegts.Events.ERROR, () => {
             console.error('mpegts消息:mpegts.Events.ERROR');
@@ -262,6 +276,7 @@ export function useHlsPlay() {
   const appStore = useAppStore();
   const hlsPlayer = ref<Player>();
   const hlsVideoEl = ref<HTMLVideoElement>();
+  const appendVideoEl = ref<HTMLVideoElement>();
   const initRetryMax = 120;
   const retryMax = ref(initRetryMax);
   const retry = ref(0);
@@ -301,6 +316,15 @@ export function useHlsPlay() {
     }
   }
 
+  watch(
+    () => appStore.liveLine,
+    (newval) => {
+      if (newval !== LiveLineEnum.hls) {
+        appendVideoEl.value?.remove();
+      }
+    }
+  );
+
   watch(
     () => appStore.playing,
     (newVal) => {
@@ -358,13 +382,13 @@ export function useHlsPlay() {
       function main() {
         console.log('startHlsPlay', data.hlsurl);
         destroyHls();
-        const videoEl = createVideo({
+        appendVideoEl.value = createVideo({
           appendChild: true,
           muted: appStore.pageIsClick ? cacheStore.muted : true,
           autoplay: true,
         });
         hlsPlayer.value = videoJs(
-          videoEl,
+          appendVideoEl.value,
           {
             sources: [
               {
@@ -400,6 +424,9 @@ export function useHlsPlay() {
           console.log('hls-playing');
           hlsIsPlaying.value = true;
           retry.value = 0;
+          if (appendVideoEl.value) {
+            appendVideoEl.value.muted = cacheStore.muted;
+          }
           // console.log(hlsPlayer.value?.videoHeight()); // 获取到的是正确的!
           const childNodes = hlsPlayer.value?.el().childNodes;
           if (childNodes) {

+ 17 - 2
src/hooks/use-pull.ts

@@ -74,6 +74,7 @@ export function usePull() {
 
   onUnmounted(() => {
     handleStopDrawing();
+    handleRtmpToRtcStop();
     destroyFlv();
     destroyHls();
   });
@@ -223,9 +224,16 @@ export function usePull() {
     }
   );
 
+  function handleRtmpToRtcStop() {
+    webRtcRtmpToRtc.close({ receiver: 'rtmpToRtc' });
+  }
+
   function handleRtmpToRtcPlay() {
     console.log('handleRtmpToRtcPlay');
     handleStopDrawing();
+    handleRtmpToRtcStop();
+    destroyFlv();
+    destroyHls();
     videoLoading.value = true;
     appStore.liveLine = LiveLineEnum['rtmp-rtc'];
     updateWebRtcRtmpToRtcConfig({
@@ -254,6 +262,9 @@ export function usePull() {
   async function handleWebRtcLivePlay(data) {
     console.log('handleWebRtcLivePlay');
     handleStopDrawing();
+    handleRtmpToRtcStop();
+    destroyFlv();
+    destroyHls();
     videoLoading.value = true;
     appStore.liveLine = LiveLineEnum.rtc;
     updateWebRtcLiveConfig({
@@ -377,8 +388,10 @@ export function usePull() {
 
   function handleHlsPlay() {
     console.log('handleHlsPlay', hlsurl.value);
-    destroyFlv();
     handleStopDrawing();
+    handleRtmpToRtcStop();
+    destroyFlv();
+    destroyHls();
     videoLoading.value = true;
     appStore.liveLine = LiveLineEnum.hls;
     startHlsPlay({
@@ -388,8 +401,10 @@ export function usePull() {
 
   function handleFlvPlay() {
     console.log('handleFlvPlay', flvurl.value);
-    destroyHls();
     handleStopDrawing();
+    handleRtmpToRtcStop();
+    destroyFlv();
+    destroyHls();
     videoLoading.value = true;
     appStore.liveLine = LiveLineEnum.flv;
     startFlvPlay({

+ 5 - 0
src/hooks/webrtc/rtmpToRtc.ts

@@ -129,6 +129,11 @@ export const useWebRtcRtmpToRtc = () => {
         console.log(error);
       }
     },
+
+    close: ({ receiver }: { receiver: string }) => {
+      const rtc = networkStore.rtcMap.get(receiver);
+      rtc?.close();
+    },
   };
 
   return { updateWebRtcRtmpToRtcConfig, webRtcRtmpToRtc };

+ 11 - 0
src/router/index.ts

@@ -21,6 +21,7 @@ export const mobileRouterName = {
   h5ShopDetail: 'h5ShopDetail',
   h5Store: 'h5Store',
   h5StoreDetail: 'h5StoreDetail',
+  h5privatizationDeployment: 'h5privatizationDeployment',
   ...commonRouterName,
 };
 
@@ -290,6 +291,11 @@ export const defaultRoutes: RouteRecordRaw[] = [
     path: '/h5/store/:id',
     component: () => import('@/views/h5/storeDetail/index.vue'),
   },
+  {
+    name: mobileRouterName.h5privatizationDeployment,
+    path: '/h5/privatizationDeployment',
+    component: () => import('@/views/h5/privatizationDeployment/index.vue'),
+  },
   // {
   //   name: mobileRouterName.h5Shop,
   //   path: '/h5/shop',
@@ -348,6 +354,11 @@ router.beforeEach((to, from, next) => {
           name: mobileRouterName.h5Store,
           query: { ...to.query },
         });
+      } else if (to.name === routerName.privatizationDeployment) {
+        return next({
+          name: mobileRouterName.h5privatizationDeployment,
+          query: { ...to.query },
+        });
       } else {
         return next({
           name: mobileRouterName.h5,

+ 4 - 1
src/store/app/index.ts

@@ -9,6 +9,7 @@ import {
 } from '@/interface';
 import { mobileRouterName } from '@/router';
 import { ILiveRoom } from '@/types/ILiveRoom';
+import { isMSESupported } from '@/utils';
 
 export type AppRootState = {
   pageIsClick: boolean;
@@ -65,6 +66,7 @@ export type AppRootState = {
     kbs?: string;
     fps?: number;
   };
+  mseSupport: boolean;
   liveLine: LiveLineEnum;
   liveRoomInfo?: ILiveRoom;
   showLoginModal: boolean;
@@ -95,7 +97,8 @@ export const useAppStore = defineStore('app', {
         { routeName: mobileRouterName.h5My, name: '我的' },
       ],
       allTrack: [],
-      liveLine: LiveLineEnum.hls,
+      mseSupport: isMSESupported(),
+      liveLine: isMSESupported() ? LiveLineEnum.flv : LiveLineEnum.hls,
       liveRoomInfo: undefined,
       showLoginModal: false,
       disableSpeaking: new Map(),

+ 4 - 0
src/utils/index.ts

@@ -2,6 +2,10 @@
 import { computeBox, getRangeRandom, judgeType } from 'billd-utils';
 import sparkMD5 from 'spark-md5';
 
+export function isMSESupported() {
+  return !!window.MediaSource;
+}
+
 /**
  * ios日期兼容
  * 2022-01-19 15:28:00 转成 2022/01/19 15:28:00

+ 577 - 0
src/views/h5/privatizationDeployment/index.vue

@@ -0,0 +1,577 @@
+<template>
+  <div class="privatizationDeployment-wrap">
+    <h2 class="title">
+      <div
+        v-for="(item, index) in detail[currentTab].slogan"
+        :key="index"
+      >
+        {{ item }}
+      </div>
+    </h2>
+    <div class="tab">
+      <div
+        v-for="(item, index) in tab"
+        :key="index"
+        class="item"
+        :class="{ active: item.id === currentTab }"
+        @click="currentTab = item.id"
+      >
+        {{ item.txt }}
+      </div>
+    </div>
+    <div class="list">
+      <div
+        class="item"
+        :class="{ [item['color']]: 1 }"
+        v-for="(item, index) in detail[currentTab].list"
+        :key="index"
+      >
+        <div class="name">{{ item.name }}</div>
+        <div class="desc">{{ item.desc }}</div>
+        <div class="price">
+          <span class="t1">{{ item.price.left }}</span>
+          <span class="t2">{{ item.price.center }}</span>
+          <span class="t3">{{ item.price.right }}</span>
+        </div>
+        <div class="feat">
+          <div
+            v-if="item.tip !== ''"
+            class="feat-item tip"
+          >
+            {{ item.tip }}
+          </div>
+          <div
+            class="feat-item"
+            v-for="(iten, indey) in item.feat"
+            :key="indey"
+          >
+            <div
+              :class="{
+                done: iten.status === 'done',
+                todo: iten.status === 'todo',
+              }"
+            ></div>
+            <div class="txt">{{ iten.txt }}</div>
+          </div>
+        </div>
+        <div
+          class="btn"
+          @click="handleClick(item.btn)"
+        >
+          {{ item.btn.txt }}
+        </div>
+      </div>
+    </div>
+  </div>
+  <n-modal v-model:show="showContach">
+    <n-card
+      style="width: 300px"
+      title="联系作者"
+      role="dialog"
+      closable
+      @close="showContach = false"
+    >
+      <div>
+        <div>微信二维码:</div>
+        <img
+          src="@/assets/img/my-wechat.webp"
+          alt=""
+          style="width: 250px"
+        />
+        <p>微信号:{{ AUTHOR_INFO.wechat }}</p>
+        <p>qq号:{{ AUTHOR_INFO.qq }}</p>
+        <p>添加时请备注:私有化部署+用途</p>
+      </div>
+    </n-card>
+  </n-modal>
+</template>
+
+<script lang="ts" setup>
+import { openToTarget } from 'billd-utils';
+import { ref } from 'vue';
+import { useRouter } from 'vue-router';
+
+import { AUTHOR_INFO, COMMON_URL, PROJECT_NAME } from '@/constant';
+import { routerName } from '@/router';
+
+const router = useRouter();
+const showContach = ref(false);
+const currentTab = ref<'personal' | 'openSource' | 'customized' | string>(
+  'openSource'
+);
+
+const tab = ref([
+  {
+    id: 'personal',
+    txt: '个人版',
+  },
+  {
+    id: 'openSource',
+    txt: '开源版',
+  },
+  {
+    id: 'customized',
+    txt: '定制版',
+  },
+]);
+
+const detail = ref({
+  personal: {
+    slogan: ['欢迎使用billd直播~'],
+    list: [
+      {
+        color: 'blue',
+        name: 'VIP',
+        desc: '适用于个人用户简单体验',
+        price: {
+          left: '¥',
+          center: '0',
+          right: '',
+        },
+        tip: '',
+        feat: [
+          {
+            status: 'done',
+            txt: 'SRS直播',
+          },
+          {
+            status: 'done',
+            txt: '打PK直播',
+          },
+          {
+            status: 'done',
+            txt: 'WebRTC直播',
+          },
+          {
+            status: 'done',
+            txt: 'WebRTC会议',
+          },
+        ],
+        btn: {
+          type: 'push',
+          link: routerName.push,
+          txt: '免费体验',
+        },
+      },
+      {
+        color: 'green',
+        name: 'SVIP',
+        desc: '适用于个人用户中度体验',
+        price: {
+          left: '¥',
+          center: '10',
+          right: '元/月',
+        },
+        tip: '涵盖VIP全部功能',
+        feat: [
+          {
+            status: 'done',
+            txt: '转推b站',
+          },
+          {
+            status: 'done',
+            txt: '转推虎牙',
+          },
+          {
+            status: 'done',
+            txt: '去广告',
+          },
+        ],
+        btn: {
+          type: 'toast',
+          link: '即将上线~',
+          txt: '立即购买',
+        },
+      },
+      {
+        color: 'orange',
+        name: 'ADMIN',
+        desc: '适用于个人用户深度体验',
+        price: {
+          left: '¥',
+          center: '50',
+          right: '元/月',
+        },
+        tip: '涵盖SVIP全部功能',
+        feat: [
+          {
+            status: 'done',
+            txt: 'Msr直播',
+          },
+          {
+            status: 'done',
+            txt: '腾讯云直播(CDN)',
+          },
+          {
+            status: 'done',
+            txt: '腾讯云打PK(CDN)',
+          },
+        ],
+        btn: {
+          type: 'toast',
+          link: '即将上线~',
+          txt: '立即购买',
+        },
+      },
+    ],
+  },
+  openSource: {
+    slogan: ['billd直播开源至今,累计收获1.3k+ star', '值得信赖,欢迎部署~'],
+    list: [
+      {
+        color: 'blue',
+        name: 'Github',
+        desc: '适用于个人学习/测试用途',
+        price: {
+          left: '¥',
+          center: '0',
+          right: '',
+        },
+        tip: '',
+        feat: [
+          {
+            status: 'done',
+            txt: '源码开源,自行部署',
+          },
+          {
+            status: 'done',
+            txt: '直播前台(Web)',
+          },
+          {
+            status: 'done',
+            txt: '直播后台(Web)',
+          },
+          {
+            status: 'done',
+            txt: '直播安卓端(Flutter)',
+          },
+          {
+            status: 'todo',
+            txt: '直播苹果端(Flutter)',
+          },
+          {
+            status: 'todo',
+            txt: '直播客户端(Electron)',
+          },
+        ],
+        btn: {
+          type: 'link',
+          link: 'https://github.com/galaxy-s10/billd-live',
+          txt: '立即部署',
+        },
+      },
+      {
+        color: 'green',
+        name: '私有化部署',
+        desc: '适用于个人/企业自建直播平台',
+        price: {
+          left: '¥',
+          center: '8000',
+          right: '起',
+        },
+        tip: '涵盖Github全部/部分功能',
+        feat: [
+          {
+            status: 'done',
+            txt: '一次部署,永久使用',
+          },
+          {
+            status: 'done',
+            txt: '无门槛,全程专人负责部署',
+          },
+          {
+            status: 'done',
+            txt: '本地服务器部署',
+          },
+          {
+            status: 'done',
+            txt: '快速上线',
+          },
+        ],
+        btn: {
+          type: 'showContact',
+          link: '',
+          txt: '立即咨询',
+        },
+      },
+    ],
+  },
+  customized: {
+    slogan: ['billd直播支持定制化', '立即定制自己的个性化直播间~'],
+    list: [
+      {
+        color: 'blue',
+        name: '在线咨询',
+        desc: '咨询/答疑服务',
+        price: {
+          left: '¥',
+          center: '100',
+          right: '元/小时',
+        },
+        tip: '',
+        feat: [
+          {
+            status: 'done',
+            txt: '一对一解答',
+          },
+        ],
+        btn: {
+          type: 'showContact',
+          link: '',
+          txt: '立即咨询',
+        },
+      },
+      {
+        color: 'green',
+        name: '付费课程',
+        desc: '适用于前端/音视频小白',
+        price: {
+          left: '¥',
+          center: '399',
+          right: '元',
+        },
+        tip: '',
+        feat: [
+          {
+            status: 'done',
+            txt: '一对一解答(4小时)',
+          },
+          {
+            status: 'done',
+            txt: '能够搭建最基础的直播间',
+          },
+          {
+            status: 'done',
+            txt: '单独的代码仓库',
+          },
+          {
+            status: 'done',
+            txt: '视频讲解',
+          },
+          {
+            status: 'done',
+            txt: `${PROJECT_NAME}付费课微信群`,
+          },
+        ],
+        btn: {
+          type: 'link',
+          link: COMMON_URL.payCoursesArticle,
+          txt: '了解详情',
+        },
+      },
+      {
+        color: 'orange',
+        name: '私有化部署',
+        desc: '适用于个人/企业自建直播平台',
+        price: {
+          left: '¥',
+          center: '9999',
+          right: '起',
+        },
+        tip: '',
+        feat: [
+          {
+            status: 'done',
+            txt: '一次部署,永久使用',
+          },
+          {
+            status: 'done',
+            txt: '无门槛,全程专人负责部署',
+          },
+          {
+            status: 'done',
+            txt: '本地服务器部署',
+          },
+          {
+            status: 'done',
+            txt: '快速上线',
+          },
+          {
+            status: 'done',
+            txt: '定制化功能',
+          },
+        ],
+        btn: {
+          type: 'showContact',
+          link: '',
+          txt: '立即咨询',
+        },
+      },
+    ],
+  },
+});
+
+function handleClick(item) {
+  if (item.type === 'link') {
+    openToTarget(item.link);
+  } else if (item.type === 'push') {
+    const url = router.resolve({
+      name: item.link,
+    });
+    openToTarget(url.href);
+  } else if (item.type === 'buy') {
+    console.log('buy');
+  } else if (item.type === 'toast') {
+    window.$message.info(item.link);
+  } else if (item.type === 'showContact') {
+    showContach.value = true;
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+.privatizationDeployment-wrap {
+  background-color: #f4f8ff;
+  .title {
+    display: flex;
+    flex-direction: column;
+    justify-content: center;
+    box-sizing: border-box;
+    margin: 0 auto;
+    width: 80%;
+    height: 160px;
+    // background-color: red;
+    text-align: center;
+    font-size: 30px;
+  }
+  .tab {
+    display: flex;
+    justify-content: center;
+    margin: 10px auto 0;
+    padding: 8px 0;
+    width: 320px;
+    border-radius: 40px;
+    background: white;
+    box-shadow: 0 3px 6px rgba(0, 0, 0, 0.05);
+
+    user-select: none;
+    .item {
+      padding: 4px 25px;
+      border-radius: 40px;
+      color: #686e88;
+      font-weight: 700;
+      font-size: 16px;
+      cursor: pointer;
+      &.active {
+        background-color: $theme-color-gold;
+        color: white;
+      }
+    }
+  }
+  .list {
+    padding-top: 20px;
+    display: flex;
+    justify-content: center;
+    flex-direction: column;
+    align-items: center;
+    .item {
+      box-sizing: border-box;
+      padding: 20px 20px;
+      width: 80%;
+      margin-bottom: 20px;
+      // border: 1px solid #dde6ed;
+      border-radius: 2px;
+      border-top-left-radius: 4px;
+      border-top-right-radius: 4px;
+      background-color: white;
+      font-size: 14px;
+      box-shadow:
+        0 0.90667vw 2.13333vw 0 rgba(0, 0, 0, 0.10196078431372549),
+        0 1px 0.53333vw 0 hsla(0, 0%, 100%, 0.5019607843137255);
+      &.blue {
+        border-top: 7px solid #38c0ff;
+      }
+      &.green {
+        border-top: 7px solid #30d1aa;
+      }
+      &.orange {
+        border-top: 7px solid #ffbd33;
+      }
+      .name {
+        padding: 10px 0 0;
+        height: 40px;
+        text-align: center;
+        font-size: 30px;
+        line-height: 1;
+      }
+      .desc {
+        margin-top: 10px;
+        height: 40px;
+        color: #88898d;
+        text-align: center;
+        // background-color: red;
+      }
+      .price {
+        display: flex;
+        align-items: flex-end;
+        justify-content: center;
+        height: 45px;
+        color: #88898d;
+        text-align: center;
+        .t1 {
+          color: #272727;
+          font-weight: 600;
+          font-size: 16px;
+        }
+        .t2 {
+          color: #272727;
+          font-size: 40px;
+          line-height: 36px;
+        }
+        .t3 {
+          color: #2c2c2c;
+          font-size: 16px;
+        }
+        // background-color: red;
+      }
+      .feat {
+        margin-top: 30px;
+        height: 180px;
+        .feat-item {
+          display: flex;
+          align-items: center;
+          margin-bottom: 10px;
+          &.tip {
+            color: #88898d;
+          }
+          .todo,
+          .done {
+            margin-right: 10px;
+            width: 18px;
+            height: 18px;
+            text-align: center;
+          }
+          .todo {
+            position: relative;
+            &::after {
+              color: #ffc049;
+              content: '-';
+              text-align: center;
+              font-size: 16px;
+            }
+          }
+          .done {
+            @include setBackground('@/assets/img/check.png');
+          }
+        }
+      }
+      .btn {
+        margin: 0 auto;
+        padding: 8px 0;
+        width: 160px;
+        border: 1px solid $theme-color-gold;
+        border-radius: 4px;
+        color: $theme-color-gold;
+        text-align: center;
+        font-size: 16px;
+        cursor: pointer;
+        transition: all 00.3s ease;
+        &:hover {
+          background-color: $theme-color-gold;
+          color: white;
+        }
+      }
+    }
+  }
+}
+</style>

+ 0 - 10
src/views/home/index.vue

@@ -251,7 +251,6 @@ import { usePull } from '@/hooks/use-pull';
 import { ILive, LiveLineEnum, SwitchEnum } from '@/interface';
 import { routerName } from '@/router';
 import { useAppStore } from '@/store/app';
-import { LiveRoomTypeEnum } from '@/types/ILiveRoom';
 
 const router = useRouter();
 const appStore = useAppStore();
@@ -384,15 +383,6 @@ function playLive(item: ILive) {
 
 function changeLive(item: ILive) {
   if (item.id === currentLive.value?.id) return;
-  if (
-    ![
-      LiveRoomTypeEnum.wertc_live,
-      LiveRoomTypeEnum.wertc_meeting_one,
-      LiveRoomTypeEnum.wertc_meeting_two,
-    ].includes(item.live_room!.type!)
-  ) {
-    appStore.liveLine = LiveLineEnum.hls;
-  }
   playLive(item);
 }
 

+ 11 - 3
src/views/privatizationDeployment/index.vue

@@ -266,11 +266,15 @@ const detail = ref({
         desc: '适用于个人/企业自建直播平台',
         price: {
           left: '¥',
-          center: 'XXXX',
+          center: '8000',
           right: '起',
         },
         tip: '涵盖Github全部/部分功能',
         feat: [
+          {
+            status: 'done',
+            txt: '一次部署,永久使用',
+          },
           {
             status: 'done',
             txt: '无门槛,全程专人负责部署',
@@ -301,7 +305,7 @@ const detail = ref({
         desc: '咨询/答疑服务',
         price: {
           left: '¥',
-          center: '50',
+          center: '100',
           right: '元/小时',
         },
         tip: '',
@@ -361,11 +365,15 @@ const detail = ref({
         desc: '适用于个人/企业自建直播平台',
         price: {
           left: '¥',
-          center: 'XXXX',
+          center: '9999',
           right: '起',
         },
         tip: '',
         feat: [
+          {
+            status: 'done',
+            txt: '一次部署,永久使用',
+          },
           {
             status: 'done',
             txt: '无门槛,全程专人负责部署',

+ 1 - 1
src/views/pull/index.vue

@@ -641,7 +641,7 @@ async function handleBilibil() {
   console.log(flv?.data?.data?.durl?.[0].url, 'flv');
   console.log(hls?.data?.data?.durl?.[0].url, 'hls');
   roomLiving.value = true;
-  appStore.liveLine = LiveLineEnum.hls;
+  appStore.liveLine = appStore.mseSupport ? LiveLineEnum.flv : LiveLineEnum.hls;
   anchorInfo.value = {
     avatar: roomInfo?.data?.data?.user_cover,
     username: roomInfo?.data?.data?.title,