Răsfoiți Sursa

fix: 分辨率

shuisheng 2 ani în urmă
părinte
comite
011b654144
5 a modificat fișierele cu 123 adăugiri și 64 ștergeri
  1. 66 37
      src/hooks/use-pull.ts
  2. 47 27
      src/utils/index.ts
  3. 4 0
      src/views/h5/room/index.vue
  4. 4 0
      src/views/home/index.vue
  5. 2 0
      src/views/pull/index.vue

+ 66 - 37
src/hooks/use-pull.ts

@@ -30,6 +30,7 @@ export function usePull(roomId: string) {
   const isPlaying = ref(false);
   const flvurl = ref('');
   const hlsurl = ref('');
+  const videoWrapRef = ref<HTMLDivElement>();
   const videoHeight = ref();
   const sidebarList = ref<
     {
@@ -74,34 +75,47 @@ export function usePull(roomId: string) {
       console.log(
         networkStore.getRtcMap(`${mySocketId.value}___${roomId}`)?.videoEl!
       );
+      if (videoWrapRef.value) {
+        const rect = videoWrapRef.value.getBoundingClientRect();
+        const { canvas, stopDrawing } = videoToCanvas({
+          wrapSize: {
+            width: rect.width,
+            height: rect.height,
+          },
+          videoEl: networkStore.getRtcMap(`${mySocketId.value}___${roomId}`)
+            ?.videoEl!,
+          videoResize: ({ w, h }) => {
+            videoHeight.value = `${w}x${h}`;
+          },
+        });
+        document.body.appendChild(canvas);
+        stopDrawingArr.value.push(stopDrawing);
+        remoteVideo.value.push(canvas);
+        roomLiving.value = true;
+        videoLoading.value = false;
+      }
+    }
+  );
+
+  watch(hlsVideoEl, () => {
+    stopDrawingArr.value = [];
+    stopDrawingArr.value.forEach((cb) => cb());
+    if (videoWrapRef.value) {
+      const rect = videoWrapRef.value.getBoundingClientRect();
       const { canvas, stopDrawing } = videoToCanvas({
-        videoEl: networkStore.getRtcMap(`${mySocketId.value}___${roomId}`)
-          ?.videoEl!,
-        resize: ({ w, h }) => {
+        wrapSize: {
+          width: rect.width,
+          height: rect.height,
+        },
+        videoEl: hlsVideoEl.value!,
+        videoResize: ({ w, h }) => {
           videoHeight.value = `${w}x${h}`;
         },
       });
-      console.log(canvas);
-      document.body.appendChild(canvas);
       stopDrawingArr.value.push(stopDrawing);
       remoteVideo.value.push(canvas);
-      roomLiving.value = true;
       videoLoading.value = false;
     }
-  );
-
-  watch(hlsVideoEl, () => {
-    stopDrawingArr.value = [];
-    stopDrawingArr.value.forEach((cb) => cb());
-    const { canvas, stopDrawing } = videoToCanvas({
-      videoEl: hlsVideoEl.value!,
-      resize: ({ w, h }) => {
-        videoHeight.value = `${w}x${h}`;
-      },
-    });
-    stopDrawingArr.value.push(stopDrawing);
-    remoteVideo.value.push(canvas);
-    videoLoading.value = false;
   });
 
   function handleHlsPlay(url: string) {
@@ -117,15 +131,22 @@ export function usePull(roomId: string) {
   watch(flvVideoEl, () => {
     stopDrawingArr.value = [];
     stopDrawingArr.value.forEach((cb) => cb());
-    const { canvas, stopDrawing } = videoToCanvas({
-      videoEl: flvVideoEl.value!,
-      resize: ({ w, h }) => {
-        videoHeight.value = `${w}x${h}`;
-      },
-    });
-    stopDrawingArr.value.push(stopDrawing);
-    remoteVideo.value.push(canvas);
-    videoLoading.value = false;
+    if (videoWrapRef.value) {
+      const rect = videoWrapRef.value.getBoundingClientRect();
+      const { canvas, stopDrawing } = videoToCanvas({
+        wrapSize: {
+          width: rect.width,
+          height: rect.height,
+        },
+        videoEl: flvVideoEl.value!,
+        videoResize: ({ w, h }) => {
+          videoHeight.value = `${w}x${h}`;
+        },
+      });
+      stopDrawingArr.value.push(stopDrawing);
+      remoteVideo.value.push(canvas);
+      videoLoading.value = false;
+    }
   });
 
   function handleFlvPlay() {
@@ -268,14 +289,21 @@ export function usePull(roomId: string) {
       if (appStore.liveRoomInfo?.type === LiveRoomTypeEnum.user_wertc) {
         newVal.forEach((item) => {
           videoLoading.value = false;
-          const { canvas } = videoToCanvas({
-            videoEl: item.videoEl,
-            resize: ({ w, h }) => {
-              videoHeight.value = `${w}x${h}`;
-            },
-          });
-          videoElArr.value.push(item.videoEl);
-          remoteVideo.value.push(canvas);
+          if (videoWrapRef.value) {
+            const rect = videoWrapRef.value.getBoundingClientRect();
+            const { canvas } = videoToCanvas({
+              wrapSize: {
+                width: rect.width,
+                height: rect.height,
+              },
+              videoEl: item.videoEl,
+              videoResize: ({ w, h }) => {
+                videoHeight.value = `${w}x${h}`;
+              },
+            });
+            videoElArr.value.push(item.videoEl);
+            remoteVideo.value.push(canvas);
+          }
         });
       }
     },
@@ -427,6 +455,7 @@ export function usePull(roomId: string) {
   }
 
   return {
+    videoWrapRef,
     handlePlay,
     handleStopDrawing,
     initPull,

+ 47 - 27
src/utils/index.ts

@@ -1,5 +1,5 @@
 // TIP: ctrl+cmd+t,生成函数注释
-import { getRangeRandom } from 'billd-utils';
+import { computeBox, getRangeRandom } from 'billd-utils';
 import sparkMD5 from 'spark-md5';
 
 export const formatTimeHour = (timestamp: number) => {
@@ -335,8 +335,9 @@ export const createVideo = ({
 };
 
 export function videoToCanvas(data: {
+  wrapSize: { width: number; height: number };
   videoEl: HTMLVideoElement;
-  resize?: (data: { w: number; h: number }) => void;
+  videoResize?: (data: { w: number; h: number }) => void;
 }) {
   const { videoEl } = data;
   if (!videoEl) {
@@ -351,36 +352,55 @@ export function videoToCanvas(data: {
   function handleResize() {
     w = videoEl.videoWidth;
     h = videoEl.videoHeight;
-    data.resize?.({ w, h });
+    data.videoResize?.({ w, h });
+    setVideoSize({ width: w, height: h });
   }
-  data.resize?.({ w, h });
+  function setVideoSize({ width, height }) {
+    const res = computeBox({
+      width,
+      height,
+      maxHeight: data.wrapSize.height,
+      minHeight: data.wrapSize.height,
+      maxWidth: data.wrapSize.width,
+      minWidth: data.wrapSize.width,
+    });
+    canvas.style.width = `${res.width as number}px`;
+    canvas.style.height = `${res.height as number}px`;
+  }
+  setVideoSize({ width: w, height: h });
+  data.videoResize?.({ w, h });
   videoEl.addEventListener('resize', handleResize);
-  const defaultRatio = 16 / 9;
+  // const defaultRatio = 16 / 9;
   function drawCanvas() {
     canvas.width = w;
     canvas.height = h;
-    const videoRatio = w / h;
-    // 比率的值越大,说明高的值越小
-    // 如果视频的比率比默认dom的比率大,则说明同等宽度的情况下,视频的高度会比默认dom的高度值低
-    if (w > h) {
-      if (videoRatio > defaultRatio) {
-        // 视频的比率比dom比率大
-        canvas.style.minWidth = '100%';
-        canvas.style.maxHeight = '100%';
-      } else {
-        canvas.style.minHeight = '100%';
-        canvas.style.maxWidth = '100%';
-      }
-    } else {
-      if (videoRatio > defaultRatio) {
-        // 视频的比率比dom比率大
-        canvas.style.minHeight = '100%';
-        canvas.style.maxWidth = '100%';
-      } else {
-        canvas.style.minWidth = '100%';
-        canvas.style.maxHeight = '100%';
-      }
-    }
+    // const videoRatio = w / h;
+    // if (w > h) {
+    //   // 视频宽大于高
+    //   // 比率的值越大,说明高的值越小
+    //   // 如果视频的比率比默认dom的比率大,则说明同等宽度的情况下,视频的高度会比默认dom的高度值低
+    //   if (videoRatio > defaultRatio) {
+    //     // 视频的比率比dom比率大
+    //     canvas.style.minWidth = '100%';
+    //     canvas.style.maxHeight = '100%';
+    //   } else {
+    //     canvas.style.minHeight = '100%';
+    //     canvas.style.maxWidth = '100%';
+    //   }
+    // } else {
+    //   // 视频宽小于高
+    //   // 比率的值越大,说明高的值越小
+    //   // 如果视频的比率比默认dom的比率大,则说明同等宽度的情况下,视频的高度会比默认dom的高度值低
+
+    //   if (videoRatio > defaultRatio) {
+    //     // 视频的比率比dom比率大
+    //     canvas.style.minHeight = '100%';
+    //     canvas.style.maxWidth = '100%';
+    //   } else {
+    //     canvas.style.minWidth = '100%';
+    //     canvas.style.maxHeight = '100%';
+    //   }
+    // }
     ctx.drawImage(videoEl, 0, 0, w, h);
     timer = requestAnimationFrame(drawCanvas);
   }

+ 4 - 0
src/views/h5/room/index.vue

@@ -24,6 +24,7 @@
     <div
       v-loading="videoLoading"
       class="video-wrap"
+      ref="videoWrapTmpRef"
       :style="{
         height: videoWrapHeight + 'px',
         '--max-height': videoWrapHeight + 'px',
@@ -234,6 +235,7 @@ const route = useRoute();
 const cacheStore = usePiniaCacheStore();
 const appStore = useAppStore();
 
+const videoWrapTmpRef = ref<HTMLDivElement>();
 const bottomRef = ref<HTMLDivElement>();
 const danmuListRef = ref<HTMLDivElement>();
 const showPlayBtn = ref(false);
@@ -245,6 +247,7 @@ const frontendWechatQrcode = ref('');
 const remoteVideoRef = ref<HTMLDivElement>();
 
 const {
+  videoWrapRef,
   handlePlay,
   initPull,
   keydownDanmu,
@@ -269,6 +272,7 @@ onUnmounted(() => {
 });
 
 onMounted(() => {
+  videoWrapRef.value = videoWrapTmpRef.value;
   getWechatQrcode();
   setTimeout(() => {
     scrollTo(0, 0);

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

@@ -41,6 +41,7 @@
         <div
           v-loading="videoLoading"
           class="left"
+          ref="videoWrapTmpRef"
           @click="showJoinBtn = !showJoinBtn"
         >
           <div
@@ -229,10 +230,12 @@ const topLiveRoomList = ref<ILive[]>([]);
 const otherLiveRoomList = ref<ILive[]>([]);
 const currentLiveRoom = ref<ILive>();
 const interactionList = ref<any[]>([]);
+const videoWrapTmpRef = ref<HTMLDivElement>();
 const remoteVideoRef = ref<HTMLDivElement>();
 const docW = document.documentElement.clientWidth;
 
 const {
+  videoWrapRef,
   videoLoading,
   remoteVideo,
   roomLiving,
@@ -245,6 +248,7 @@ onMounted(() => {
   handleSlideList();
   getLiveRoomList();
   getBg();
+  videoWrapRef.value = videoWrapTmpRef.value;
 });
 
 watch(

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

@@ -400,6 +400,7 @@ const containerRef = ref<HTMLDivElement>();
 const uploadRef = ref<HTMLInputElement>();
 const danmuIptRef = ref<HTMLTextAreaElement>();
 const {
+  videoWrapRef,
   initPull,
   closeWs,
   closeRtc,
@@ -419,6 +420,7 @@ const {
 } = usePull(roomId.value);
 
 onMounted(() => {
+  videoWrapRef.value = containerRef.value;
   setTimeout(() => {
     scrollTo(0, 0);
   }, 100);