shuisheng vor 2 Jahren
Ursprung
Commit
a147a25d99
3 geänderte Dateien mit 129 neuen und 33 gelöschten Zeilen
  1. 7 7
      src/hooks/use-play.ts
  2. 77 26
      src/views/home/index.vue
  3. 45 0
      src/views/pull/index.vue

+ 7 - 7
src/hooks/use-play.ts

@@ -6,7 +6,7 @@ import { onMounted, onUnmounted, ref, watch } from 'vue';
 
 import { useAppStore } from '@/store/app';
 // @ts-ignore
-const flvJs = window.flvjs;
+export const flvJs = window.flvjs;
 
 export function useFlvPlay() {
   const flvPlayer = ref();
@@ -61,14 +61,13 @@ export function useHlsPlay() {
   onMounted(() => {});
 
   onUnmounted(() => {
-    if (hlsPlayer.value) {
-      hlsPlayer.value.dispose();
-    }
+    destroyHls();
   });
 
   function destroyHls() {
     if (hlsPlayer.value) {
       hlsPlayer.value.dispose();
+      videoEl.value?.remove();
     }
   }
 
@@ -84,11 +83,12 @@ export function useHlsPlay() {
   function startHlsPlay(data: { hlsurl: string; videoEl: HTMLVideoElement }) {
     console.log('startHlsPlay', data.hlsurl);
     if (hlsPlayer.value) {
-      hlsPlayer.value.dispose();
+      destroyHls();
     }
-    const appStore = useAppStore();
     const newVideo = document.createElement('video');
-    newVideo.muted = appStore.muted;
+    newVideo.muted = true;
+    newVideo.playsInline = true;
+    newVideo.setAttribute('webkit-playsinline', 'true');
     videoEl.value = newVideo;
     data.videoEl.parentElement?.appendChild(newVideo);
     return new Promise((resolve, reject) => {

+ 77 - 26
src/views/home/index.vue

@@ -41,6 +41,14 @@
             <VideoControls></VideoControls>
           </div>
           <div
+            v-if="showTip && !clickShowTip"
+            class="tip-btn"
+            @click="handleTipBtn"
+          >
+            点击播放
+          </div>
+          <div
+            v-else
             class="join-btn"
             :style="{
               display: !isMobile() ? 'none' : showControls ? 'block' : 'none',
@@ -59,9 +67,12 @@
             </div>
             <div
               v-if="
-                currentLiveRoom.live_room?.type === LiveRoomTypeEnum.system ||
-                currentLiveRoom.live_room?.type === LiveRoomTypeEnum.user_obs ||
-                currentLiveRoom?.live_room?.type === LiveRoomTypeEnum.user_srs
+                !showTip &&
+                (currentLiveRoom.live_room?.type === LiveRoomTypeEnum.system ||
+                  currentLiveRoom.live_room?.type ===
+                    LiveRoomTypeEnum.user_obs ||
+                  currentLiveRoom?.live_room?.type ===
+                    LiveRoomTypeEnum.user_srs)
               "
               class="btn flv"
               @click="joinFlvRoom()"
@@ -129,42 +140,65 @@
 </template>
 
 <script lang="ts" setup>
-import { isMobile } from 'billd-utils';
+import { isMobile, judgeDevice } from 'billd-utils';
 import { nextTick, onMounted, ref } from 'vue';
 import { useRouter } from 'vue-router';
 
 import { fetchLiveList } from '@/api/live';
-import { useFlvPlay, useHlsPlay } from '@/hooks/use-play';
+import { flvJs, useFlvPlay, useHlsPlay } from '@/hooks/use-play';
 import { ILive, LiveRoomTypeEnum, liveTypeEnum } from '@/interface';
 import { routerName } from '@/router';
 import { useAppStore } from '@/store/app';
 
 const appStore = useAppStore();
 const router = useRouter();
+const showTip = ref(false);
+const clickShowTip = ref(false);
 const showControls = ref(false);
 const liveRoomList = ref<ILive[]>([]);
 const currentLiveRoom = ref<ILive>();
 const localVideoRef = ref<HTMLVideoElement>();
 
 const { startFlvPlay, destroyFlv } = useFlvPlay();
-const { startHlsPlay } = useHlsPlay();
+const { startHlsPlay, destroyHls } = useHlsPlay();
+
+if (!flvJs.isSupported()) {
+  showTip.value = true;
+}
+
+async function handleTipBtn() {
+  if (currentLiveRoom.value) {
+    clickShowTip.value = true;
+    await startHlsPlay({
+      hlsurl: currentLiveRoom.value.live_room!.hls_url!,
+      videoEl: localVideoRef.value!,
+    });
+  }
+}
 
 function changeLiveRoom(item: ILive) {
   currentLiveRoom.value = item;
+
   nextTick(async () => {
     if (
       item.live_room?.type === LiveRoomTypeEnum.user_srs ||
       item.live_room?.type === LiveRoomTypeEnum.user_obs ||
       item.live_room?.type === LiveRoomTypeEnum.system
     ) {
-      // await startFlvPlay({
-      //   flvurl: item.live_room.flv_url!,
-      //   videoEl: localVideoRef.value!,
-      // });
-      await startHlsPlay({
-        hlsurl: item.live_room.hls_url!,
-        videoEl: localVideoRef.value!,
-      });
+      if (flvJs.isSupported()) {
+        await startFlvPlay({
+          flvurl: item.live_room.flv_url!,
+          videoEl: localVideoRef.value!,
+        });
+      } else {
+        // showTip.value = true;
+        // clickShowTip.value = false;
+        destroyHls();
+        await startHlsPlay({
+          hlsurl: item.live_room.hls_url!,
+          videoEl: localVideoRef.value!,
+        });
+      }
     } else {
       destroyFlv();
     }
@@ -189,14 +223,17 @@ async function getLiveRoomList() {
               LiveRoomTypeEnum.user_obs ||
             currentLiveRoom.value?.live_room?.type === LiveRoomTypeEnum.system
           ) {
-            // await startFlvPlay({
-            //   flvurl: currentLiveRoom.value.live_room.flv_url!,
-            //   videoEl: localVideoRef.value!,
-            // });
-            await startHlsPlay({
-              hlsurl: currentLiveRoom.value.live_room.hls_url!,
-              videoEl: localVideoRef.value!,
-            });
+            if (judgeDevice().isIphone) {
+              await startHlsPlay({
+                hlsurl: currentLiveRoom.value.live_room.hls_url!,
+                videoEl: localVideoRef.value!,
+              });
+            } else {
+              await startFlvPlay({
+                flvurl: currentLiveRoom.value.live_room.flv_url!,
+                videoEl: localVideoRef.value!,
+              });
+            }
           } else {
             destroyFlv();
           }
@@ -237,8 +274,6 @@ function joinRoom() {
 }
 
 function joinFlvRoom() {
-  // console.log(currentLiveRoom.value?.live_room_id);
-  // return;
   router.push({
     name: routerName.pull,
     params: { roomId: currentLiveRoom.value?.live_room_id },
@@ -248,8 +283,6 @@ function joinFlvRoom() {
   });
 }
 function joinHlsRoom() {
-  // console.log(currentLiveRoom.value?.live_room_id);
-  // return;
   router.push({
     name: routerName.pull,
     params: { roomId: currentLiveRoom.value?.live_room_id },
@@ -316,6 +349,24 @@ function joinHlsRoom() {
           display: block !important;
         }
       }
+      .tip-btn {
+        position: absolute;
+        top: 50%;
+        left: 50%;
+        z-index: 1;
+        align-items: center;
+        padding: 12px 26px;
+        border: 2px solid rgba($color: papayawhip, $alpha: 0.5);
+        border-radius: 6px;
+        background-color: rgba(0, 0, 0, 0.3);
+        color: $theme-color-gold;
+        cursor: pointer;
+        transform: translate(-50%, -50%);
+        &:hover {
+          background-color: rgba($color: papayawhip, $alpha: 0.5);
+          color: white;
+        }
+      }
       .join-btn {
         position: absolute;
         top: 50%;

+ 45 - 0
src/views/pull/index.vue

@@ -51,6 +51,13 @@
               :muted="appStore.muted"
               @click="showControls = !showControls"
             ></video>
+            <div
+              v-if="showTip && !clickShowTip"
+              class="tip-btn"
+              @click="handleTipBtn"
+            >
+              点击播放
+            </div>
             <div
               class="controls"
               :style="{
@@ -60,6 +67,7 @@
               <VideoControls></VideoControls>
             </div>
           </div>
+
           <div
             v-if="showSidebar"
             class="sidebar"
@@ -219,6 +227,7 @@ import { useRoute } from 'vue-router';
 
 import { fetchGoodsList } from '@/api/goods';
 import { loginTip } from '@/hooks/use-login';
+import { flvJs, useHlsPlay } from '@/hooks/use-play';
 import { usePull } from '@/hooks/use-pull';
 import {
   DanmuMsgTypeEnum,
@@ -246,6 +255,10 @@ const bottomRef = ref<HTMLDivElement>();
 const containerRef = ref<HTMLDivElement>();
 const remoteVideoRef = ref<HTMLVideoElement>();
 const localVideoRef = ref<HTMLVideoElement[]>([]);
+const showTip = ref(false);
+const clickShowTip = ref(false);
+
+const { startHlsPlay } = useHlsPlay();
 
 const {
   initPull,
@@ -281,6 +294,20 @@ const {
   isSRS: route.query.liveType === liveTypeEnum.srsWebrtcPull,
 });
 
+if (route.query.liveType === liveTypeEnum.srsHlsPull && !flvJs.isSupported()) {
+  showTip.value = true;
+}
+
+async function handleTipBtn() {
+  if (currentLiveRoom.value) {
+    clickShowTip.value = true;
+    await startHlsPlay({
+      hlsurl: currentLiveRoom.value.live_room!.hls_url!,
+      videoEl: localVideoRef.value!,
+    });
+  }
+}
+
 async function getGoodsList() {
   try {
     giftLoading.value = true;
@@ -443,6 +470,24 @@ onMounted(() => {
         .controls {
           display: none;
         }
+        .tip-btn {
+          position: absolute;
+          top: 50%;
+          left: 50%;
+          z-index: 1;
+          align-items: center;
+          padding: 12px 26px;
+          border: 2px solid rgba($color: papayawhip, $alpha: 0.5);
+          border-radius: 6px;
+          background-color: rgba(0, 0, 0, 0.3);
+          color: $theme-color-gold;
+          cursor: pointer;
+          transform: translate(-50%, -50%);
+          &:hover {
+            background-color: rgba($color: papayawhip, $alpha: 0.5);
+            color: white;
+          }
+        }
 
         &:hover {
           .controls {