shuisheng 2 rokov pred
rodič
commit
ad4defa208

+ 3 - 10
src/hooks/use-play.ts

@@ -6,6 +6,7 @@ import Player from 'video.js/dist/types/player';
 import { onMounted, onUnmounted, ref, watch } from 'vue';
 
 import { useAppStore } from '@/store/app';
+import { createVideo } from '@/utils';
 
 export * as flvJs from 'flv.js';
 
@@ -52,11 +53,7 @@ export function useFlvPlay() {
             type: 'flv',
             url: data.flvurl,
           });
-          const videoEl = document.createElement('video');
-          // videoEl.autoplay = true;
-          videoEl.muted = true;
-          videoEl.playsInline = true;
-          videoEl.setAttribute('webkit-playsinline', 'true');
+          const videoEl = createVideo({ muted: true, autoplay: true });
           flvVideoEl.value = videoEl;
           flvVideoEl.value.addEventListener('play', () => {
             console.log('flv-play');
@@ -125,11 +122,7 @@ export function useHlsPlay() {
 
   function startHlsPlay(data: { hlsurl: string }) {
     destroyHls();
-    const videoEl = document.createElement('video');
-    videoEl.autoplay = true;
-    videoEl.muted = appStore.muted;
-    videoEl.playsInline = true;
-    videoEl.setAttribute('webkit-playsinline', 'true');
+    const videoEl = createVideo({ muted: appStore.muted, autoplay: true });
     hlsVideoEl.value = videoEl;
     // document.body.appendChild(videoEl);
     return new Promise<{ width: number; height: number }>((resolve) => {

+ 5 - 13
src/hooks/use-pull.ts

@@ -1,4 +1,3 @@
-import { NODE_ENV } from 'script/constant';
 import { Ref, nextTick, ref, watch } from 'vue';
 import { useRoute } from 'vue-router';
 
@@ -15,7 +14,7 @@ import { WsMsgTypeEnum } from '@/network/webSocket';
 import { useAppStore } from '@/store/app';
 import { useNetworkStore } from '@/store/network';
 import { useUserStore } from '@/store/user';
-import { videoToCanvas } from '@/utils';
+import { createVideo, videoToCanvas } from '@/utils';
 
 export function usePull({
   localVideoRef,
@@ -96,17 +95,10 @@ export function usePull({
           });
           videoLoading.value = false;
         } else if (roomLiveType.value === liveTypeEnum.webrtcPull) {
-          const videoEl = document.createElement('video');
-          videoEl.muted = true;
-          videoEl.playsInline = true;
-          videoEl.autoplay = true;
-          videoEl.setAttribute('webkit-playsinline', 'true');
-          videoEl.oncontextmenu = (e) => {
-            e.preventDefault();
-          };
-          if (NODE_ENV === 'development') {
-            videoEl.controls = true;
-          }
+          const videoEl = createVideo({
+            muted: appStore.muted,
+            autoplay: true,
+          });
           videoEl.srcObject = stream.value;
           canvasRef.value?.childNodes?.forEach((item) => {
             item.remove();

+ 5 - 13
src/hooks/use-pull22.ts

@@ -1,5 +1,4 @@
 import { getRandomString, judgeDevice } from 'billd-utils';
-import { NODE_ENV } from 'script/constant';
 import { Ref, nextTick, onUnmounted, reactive, ref, watch } from 'vue';
 import { useRoute } from 'vue-router';
 
@@ -31,7 +30,7 @@ import {
 import { useAppStore } from '@/store/app';
 import { useNetworkStore } from '@/store/network';
 import { useUserStore } from '@/store/user';
-import { videoToCanvas } from '@/utils';
+import { createVideo, videoToCanvas } from '@/utils';
 
 export function usePull({
   localVideoRef,
@@ -48,17 +47,10 @@ export function usePull({
   const appStore = useAppStore();
   const userStore = useUserStore();
   const networkStore = useNetworkStore();
-  const videoEl = document.createElement('video');
-  videoEl.muted = true;
-  videoEl.playsInline = true;
-  videoEl.autoplay = true;
-  videoEl.setAttribute('webkit-playsinline', 'true');
-  videoEl.oncontextmenu = (e) => {
-    e.preventDefault();
-  };
-  if (NODE_ENV === 'development') {
-    videoEl.controls = true;
-  }
+  const videoEl = createVideo({
+    muted: true,
+    autoplay: true,
+  });
   const remoteVideoRef = ref(videoEl);
   const heartbeatTimer = ref();
   const roomId = ref(route.params.roomId as string);

+ 30 - 5
src/hooks/use-push.ts

@@ -11,6 +11,7 @@ import { WsMsgTypeEnum } from '@/network/webSocket';
 import { useAppStore } from '@/store/app';
 import { useNetworkStore } from '@/store/network';
 import { useUserStore } from '@/store/user';
+import { createVideo } from '@/utils';
 
 import { loginTip } from './use-login';
 import { useTip } from './use-tip';
@@ -36,6 +37,8 @@ export function usePush({
   const danmuStr = ref('');
   const isLiving = ref(false);
 
+  const videoElArr = ref<HTMLVideoElement[]>([]);
+
   const allMediaTypeList: {
     [index: string]: { type: MediaTypeEnum; txt: string };
   } = {
@@ -73,11 +76,33 @@ export function usePush({
   watch(
     () => localStream,
     (stream) => {
-      if (stream.value) {
-        localVideoRef.value!.srcObject = stream.value;
-      } else {
-        localVideoRef.value!.srcObject = null;
-      }
+      console.log('localStream变了');
+      console.log('音频轨:', stream.value?.getAudioTracks());
+      console.log('视频轨:', stream.value?.getVideoTracks());
+      videoElArr.value.forEach((dom) => {
+        dom.remove();
+      });
+      stream.value?.getVideoTracks().forEach((track) => {
+        console.log('视频轨enabled:', track.id, track.enabled);
+        const video = createVideo({});
+        video.id = track.id;
+        video.srcObject = new MediaStream([track]);
+        localVideoRef.value?.appendChild(video);
+        videoElArr.value.push(video);
+      });
+      stream.value?.getAudioTracks().forEach((track) => {
+        console.log('音频轨enabled:', track.id, track.enabled);
+        const video = createVideo({});
+        video.id = track.id;
+        video.srcObject = new MediaStream([track]);
+        localVideoRef.value?.appendChild(video);
+        videoElArr.value.push(video);
+      });
+      // if (stream.value) {
+      //   localVideoRef.value!.srcObject = stream.value;
+      // } else {
+      //   localVideoRef.value!.srcObject = null;
+      // }
     },
     { deep: true }
   );

+ 6 - 3
src/network/webRTC.ts

@@ -156,6 +156,7 @@ export class WebRTCClass {
     return new Promise((resolve) => {
       this.localStream?.getTracks().forEach((track) => {
         if (track.kind === 'video') {
+          console.log('设置分辨率ing');
           track
             .applyConstraints({
               height,
@@ -166,7 +167,7 @@ export class WebRTCClass {
               resolve(1);
             })
             .catch((error) => {
-              console.error('设置分辨率失败', error);
+              console.error('设置分辨率失败', height, error);
               resolve(0);
             });
         }
@@ -180,6 +181,7 @@ export class WebRTCClass {
     return new Promise<number>((resolve) => {
       this.peerConnection?.getSenders().forEach((sender) => {
         if (sender.track?.kind === 'video') {
+          console.log('设置最大码率ing');
           const parameters = { ...sender.getParameters() };
           if (parameters.encodings[0]) {
             const val = 1000 * maxBitrate;
@@ -192,7 +194,7 @@ export class WebRTCClass {
                 resolve(1);
               })
               .catch((error) => {
-                console.error('设置最大码率失败', error);
+                console.error('设置最大码率失败', maxBitrate, error);
                 resolve(0);
               });
           }
@@ -207,6 +209,7 @@ export class WebRTCClass {
     return new Promise<number>((resolve) => {
       this.peerConnection?.getSenders().forEach((sender) => {
         if (sender.track?.kind === 'video') {
+          console.log('设置最大帧率ing');
           const parameters = { ...sender.getParameters() };
           if (parameters.encodings[0]) {
             parameters.encodings[0].maxFramerate = maxFramerate;
@@ -218,7 +221,7 @@ export class WebRTCClass {
                 resolve(1);
               })
               .catch((error) => {
-                console.error('设置最大帧率失败', error);
+                console.error('设置最大帧率失败', maxFramerate, error);
                 resolve(0);
               });
           }

+ 19 - 18
src/utils/index.ts

@@ -1,22 +1,23 @@
-import { getRangeRandom } from 'billd-utils';
-
-export const sum = (a, b) => {
-  return a + b;
-};
-
-/**
- * @description 获取随机字符串(ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz)
- * @example: getRandomString(4) ===> abd3
- * @param {number} length
- * @return {*}
- */
-export const getRandomString = (length: number): string => {
-  const str = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
-  let res = '';
-  for (let i = 0; i < length; i += 1) {
-    res += str.charAt(getRangeRandom(0, str.length - 1));
+// TIP: ctrl+cmd+t,生成函数注释
+
+import { NODE_ENV } from 'script/constant';
+
+export const createVideo = ({ muted = true, autoplay = true }) => {
+  const videoEl = document.createElement('video');
+  videoEl.autoplay = autoplay;
+  videoEl.muted = muted;
+  videoEl.playsInline = true;
+  videoEl.setAttribute('webkit-playsinline', 'true');
+  videoEl.setAttribute('x5-video-player-type', 'h5');
+  videoEl.setAttribute('x5-video-player-fullscreen', 'true');
+  videoEl.setAttribute('x5-video-orientation', 'portraint');
+  videoEl.oncontextmenu = (e) => {
+    e.preventDefault();
+  };
+  if (NODE_ENV === 'development') {
+    videoEl.controls = true;
   }
-  return res;
+  return videoEl;
 };
 
 export function videoToCanvas(data: {

+ 16 - 7
src/views/push/index.vue

@@ -10,9 +10,13 @@
       >
         <div class="video-wrap">
           <AudioRoomTip></AudioRoomTip>
-          <video
-            id="localVideo"
+          <div
             ref="localVideoRef"
+            class="media-list"
+          ></div>
+          <!-- <video
+            id="localVideo"
+            ref="localVideo2Ref"
             autoplay
             webkit-playsinline="true"
             playsinline
@@ -23,7 +27,7 @@
             muted
             :controls="NODE_ENV === 'development' ? true : false"
             @contextmenu.prevent
-          ></video>
+          ></video> -->
           <div
             v-if="!appStore.allTrack || appStore.allTrack.length <= 0"
             class="add-wrap"
@@ -264,7 +268,6 @@
 
 <script lang="ts" setup>
 import { getRandomString } from 'billd-utils';
-import { NODE_ENV } from 'script/constant';
 import { onMounted, ref, watch } from 'vue';
 import { useRoute } from 'vue-router';
 
@@ -473,10 +476,16 @@ function handleStartMedia(item: { type: MediaTypeEnum; txt: string }) {
         justify-content: center;
         height: 100%;
         background-color: rgba($color: #000000, $alpha: 0.5);
-        #localVideo {
-          max-width: 100%;
-          max-height: 100%;
+        .media-list {
+          :deep(video) {
+            width: 50%;
+          }
         }
+
+        // #localVideo {
+        //   max-width: 100%;
+        //   max-height: 100%;
+        // }
         .add-wrap {
           position: absolute;
           top: 50%;