Procházet zdrojové kódy

fix: 修复已知问题

shuisheng před 2 roky
rodič
revize
4f75756cf8

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

@@ -98,6 +98,7 @@ export function useFlvPlay() {
             console.log('flv-playing');
             retry.value = 0;
             setMuted(cacheStore.muted);
+            setVolume(cacheStore.volume);
             flvVideoEl.value = videoEl;
             resolve('');
           });
@@ -175,6 +176,7 @@ export function useHlsPlay() {
     }
   }
   function setVolume(val: number) {
+    console.log('setVolumesetVolume', val);
     if (hlsVideoEl.value) {
       hlsVideoEl.value.volume = val / 100;
     }
@@ -262,6 +264,7 @@ export function useHlsPlay() {
         hlsPlayer.value?.on('playing', () => {
           console.log('hls-playing');
           setMuted(cacheStore.muted);
+          setVolume(cacheStore.volume);
           retry.value = 0;
           // console.log(hlsPlayer.value?.videoHeight()); // 获取到的是正确的!
           const childNodes = hlsPlayer.value?.el().childNodes;

+ 15 - 3
src/hooks/use-pull.ts

@@ -120,13 +120,25 @@ export function usePull() {
     hlsurl.value = data.hls_url!;
     switch (data.type) {
       case LiveRoomTypeEnum.user_srs:
-        handleHlsPlay(data.hls_url);
+        if (appStore.liveLine === LiveLineEnum.flv) {
+          handleFlvPlay();
+        } else if (appStore.liveLine === LiveLineEnum.hls) {
+          handleHlsPlay(data.hls_url);
+        }
         break;
       case LiveRoomTypeEnum.user_obs:
-        handleHlsPlay(data.hls_url);
+        if (appStore.liveLine === LiveLineEnum.flv) {
+          handleFlvPlay();
+        } else if (appStore.liveLine === LiveLineEnum.hls) {
+          handleHlsPlay(data.hls_url);
+        }
         break;
       case LiveRoomTypeEnum.system:
-        handleHlsPlay(data.hls_url);
+        if (appStore.liveLine === LiveLineEnum.flv) {
+          handleFlvPlay();
+        } else if (appStore.liveLine === LiveLineEnum.hls) {
+          handleHlsPlay(data.hls_url);
+        }
         break;
       case LiveRoomTypeEnum.user_wertc:
         appStore.setLiveLine(LiveLineEnum.rtc);

+ 6 - 5
src/hooks/use-rtc-params.ts → src/hooks/use-rtcParams.ts

@@ -23,17 +23,14 @@ export const useRTCParams = () => {
     {
       label: '3000',
       value: 3000,
-      disabled: true,
     },
     {
       label: '4000',
       value: 4000,
-      disabled: true,
     },
     {
       label: '5000',
       value: 5000,
-      disabled: true,
     },
     {
       label: '6000',
@@ -61,8 +58,8 @@ export const useRTCParams = () => {
       value: 10,
     },
     {
-      label: '24帧',
-      value: 24,
+      label: '20帧',
+      value: 20,
     },
     {
       label: '30帧',
@@ -71,6 +68,10 @@ export const useRTCParams = () => {
     {
       label: '60帧',
       value: 60,
+    },
+    {
+      label: '120帧',
+      value: 120,
       disabled: true,
     },
   ]);

+ 3 - 3
src/hooks/use-srs-ws.ts

@@ -37,7 +37,7 @@ import { useNetworkStore } from '@/store/network';
 import { useUserStore } from '@/store/user';
 import { createVideo } from '@/utils';
 
-import { useRTCParams } from './use-rtc-params';
+import { useRTCParams } from './use-rtcParams';
 
 export const useSrsWs = () => {
   const appStore = useAppStore();
@@ -56,9 +56,9 @@ export const useSrsWs = () => {
   const anchorSocketId = ref('');
   const canvasVideoStream = ref<MediaStream>();
   const lastCoverImg = ref('');
-  const currentMaxBitrate = ref(maxBitrate.value[2].value);
-  const currentResolutionRatio = ref(resolutionRatio.value[3].value);
+  const currentMaxBitrate = ref(maxBitrate.value[3].value);
   const currentMaxFramerate = ref(maxFramerate.value[2].value);
+  const currentResolutionRatio = ref(resolutionRatio.value[3].value);
 
   const damuList = ref<IDanmu[]>([]);
 

+ 18 - 45
src/network/webRTC.ts

@@ -1,5 +1,4 @@
 import { getRandomString } from 'billd-utils';
-import browserTool from 'browser-tool';
 
 import { MediaTypeEnum } from '@/interface';
 import { WsCandidateType } from '@/interface-ws';
@@ -27,19 +26,6 @@ export class WebRTCClass {
 
   isSRS: boolean;
 
-  browser: {
-    device: string;
-    language: string;
-    engine: string;
-    browser: string;
-    system: string;
-    systemVersion: string;
-    platform: string;
-    isWebview: boolean;
-    isBot: boolean;
-    version: string;
-  };
-
   constructor(data: {
     roomId: string;
     videoEl: HTMLVideoElement;
@@ -63,15 +49,12 @@ export class WebRTCClass {
     }
     this.isSRS = data.isSRS;
     console.warn('new webrtc参数:', data);
-    this.browser = browserTool();
     this.createPeerConnection();
   }
 
   prettierLog = (msg: string, type?: 'log' | 'warn' | 'error', ...args) => {
     console[type || 'log'](
-      `${new Date().toLocaleString()},${this.roomId},${
-        this.browser.browser
-      }浏览器,${msg}`,
+      `${new Date().toLocaleString()},${this.roomId},${msg}`,
       ...args
     );
   };
@@ -168,29 +151,17 @@ export class WebRTCClass {
       appStore.setAllTrack([...appStore.allTrack, ...addTrack]);
     }
     this.localStream = stream;
-
-    // if (this.maxBitrate !== -1) {
-    //   this.setMaxBitrate(this.maxBitrate);
-    // }
-    // if (this.maxFramerate !== -1) {
-    //   this.setMaxFramerate(this.maxFramerate);
-    // }
-    // if (this.resolutionRatio !== -1) {
-    //   this.setResolutionRatio(this.resolutionRatio);
-    // }
   };
 
   /** 设置分辨率 */
   setResolutionRatio = (height: number) => {
     console.log('开始设置分辨率', height);
-    console.log('旧的分辨率', this.resolutionRatio);
     return new Promise((resolve) => {
       this.localStream?.getTracks().forEach((track) => {
         if (track.kind === 'video') {
-          console.log('设置分辨率ing', track.id);
           track
             .applyConstraints({
-              height,
+              height: { ideal: height },
             })
             .then(() => {
               console.log('设置分辨率成功');
@@ -209,11 +180,9 @@ export class WebRTCClass {
   /** 设置最大帧率 */
   setMaxFramerate = (maxFramerate: number) => {
     console.log('开始设置最大帧率', maxFramerate);
-    console.log('旧的最大帧率', this.maxFramerate);
     return new Promise<number>((resolve) => {
       this.peerConnection?.getSenders().forEach((sender) => {
         if (sender.track?.kind === 'video') {
-          console.log('设置最大帧率ing', sender.track.id);
           const parameters = { ...sender.getParameters() };
           if (parameters.encodings[0]) {
             if (parameters.encodings[0].maxFramerate === maxFramerate) {
@@ -242,11 +211,9 @@ export class WebRTCClass {
   /** 设置最大码率 */
   setMaxBitrate = (maxBitrate: number) => {
     console.log('开始设置最大码率', maxBitrate);
-    console.log('旧的最大码率', this.maxBitrate);
     return new Promise<number>((resolve) => {
       this.peerConnection?.getSenders().forEach((sender) => {
         if (sender.track?.kind === 'video') {
-          console.log('设置最大码率ing', sender.track.id);
           const parameters = { ...sender.getParameters() };
           if (parameters.encodings[0]) {
             const val = 1000 * maxBitrate;
@@ -440,15 +407,21 @@ export class WebRTCClass {
         if (connectionState === 'connected') {
           // 表示每一个 ICE 连接要么正在使用(connected 或 completed 状态),要么已被关闭(closed 状态);并且,至少有一个连接处于 connected 或 completed 状态。
           console.warn(this.roomId, 'connectionState:connected');
-          // if (this.maxBitrate !== -1) {
-          //   this.setMaxBitrate(this.maxBitrate);
-          // }
-          // if (this.maxFramerate !== -1) {
-          //   this.setMaxFramerate(this.maxFramerate);
-          // }
-          // if (this.resolutionRatio !== -1) {
-          //   this.setResolutionRatio(this.resolutionRatio);
-          // }
+          if (this.maxBitrate !== -1) {
+            this.setMaxBitrate(this.maxBitrate);
+          }
+          if (this.maxFramerate !== -1) {
+            this.setMaxFramerate(this.maxFramerate);
+          }
+          if (this.resolutionRatio !== -1) {
+            this.setResolutionRatio(this.resolutionRatio);
+          }
+          console.log(
+            this.maxBitrate,
+            this.maxFramerate,
+            this.resolutionRatio,
+            '配置'
+          );
         }
         if (connectionState === 'disconnected') {
           // 表示至少有一个 ICE 连接处于 disconnected 状态,并且没有连接处于 failed、connecting 或 checking 状态。
@@ -497,7 +470,7 @@ export class WebRTCClass {
 
   // 手动关闭webrtc连接
   close = () => {
-    console.warn(`${new Date().toLocaleString()},手动关闭webrtc连接`);
+    this.prettierLog('手动关闭webrtc连接', 'warn');
     this.peerConnection?.getSenders().forEach((sender) => {
       this.peerConnection?.removeTrack(sender);
     });

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

@@ -78,7 +78,7 @@
         <div class="item">
           <h2>obs/ffmpeg推流到billd-live失败</h2>
           <p>
-            服务器性能有限,限制了推流码率为:<b>2500kbps</b>,超过则会导致推流失败!
+            服务器性能有限,限制了推流码率为:<b>3000kbps</b>,超过则会导致推流失败!
           </p>
         </div>
         <div class="hr"></div>

+ 5 - 1
src/views/home/index.vue

@@ -160,7 +160,7 @@ import { useRouter } from 'vue-router';
 import { fetchLiveList } from '@/api/live';
 import { sliderList } from '@/constant';
 import { usePull } from '@/hooks/use-pull';
-import { ILive } from '@/interface';
+import { ILive, LiveLineEnum, LiveRoomTypeEnum } from '@/interface';
 import { routerName } from '@/router';
 import { useAppStore } from '@/store/app';
 
@@ -213,6 +213,10 @@ function playLive(item: ILive) {
 
 function changeLiveRoom(item: ILive) {
   if (item.id === currentLiveRoom.value?.id) return;
+  if (item.live_room?.type !== LiveRoomTypeEnum.user_wertc) {
+    appStore.setLiveLine(LiveLineEnum.hls);
+  }
+  appStore.setPlay(true);
   playLive(item);
 }
 

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

@@ -247,6 +247,7 @@ onMounted(() => {
   setTimeout(() => {
     scrollTo(0, 0);
   }, 100);
+  appStore.setPlay(true);
   getGoodsList();
   if (topRef.value && bottomRef.value && containerRef.value) {
     const res =

+ 46 - 19
src/views/push/index.vue

@@ -297,7 +297,7 @@ import * as workerTimers from 'worker-timers';
 
 import { mediaTypeEnumMap } from '@/constant';
 import { usePush } from '@/hooks/use-push';
-import { useRTCParams } from '@/hooks/use-rtc-params';
+import { useRTCParams } from '@/hooks/use-rtcParams';
 import { DanmuMsgTypeEnum, MediaTypeEnum } from '@/interface';
 import { AppRootState, useAppStore } from '@/store/app';
 import { usePiniaCacheStore } from '@/store/cache';
@@ -450,7 +450,6 @@ function renderFrame() {
   workerTimerId.value = workerTimers.setInterval(() => {
     renderAll();
   }, delay);
-  console.log('workerTimerId.value', workerTimerId.value);
 }
 
 function handleMixedAudio() {
@@ -619,7 +618,6 @@ function changeCanvasAttr({
     fabricCanvas.value.setWidth(resolutionWidth);
     fabricCanvas.value.setHeight(resolutionHeight);
     appStore.allTrack.forEach((iten) => {
-      console.log('当前类型', iten.type);
       const item = iten.canvasDom;
 
       if (item) {
@@ -637,7 +635,6 @@ function changeCanvasAttr({
       }
     });
     appStore.allTrack.forEach((iten) => {
-      console.log('当前类型', iten.type);
       const item = iten.canvasDom;
 
       if (item) {
@@ -785,6 +782,7 @@ function handleMoving({
 
 async function handleCache() {
   const res: AppRootState['allTrack'] = [];
+  const err: string[] = [];
   const queue: any[] = [];
   cacheStore['resource-list'].forEach((item) => {
     // @ts-ignore
@@ -898,19 +896,51 @@ async function handleCache() {
     }
 
     async function handleScreen() {
-      const event = await navigator.mediaDevices.getUserMedia({
-        video: true,
-        audio: { deviceId: obj.deviceId },
-      });
-      const videoEl = createVideo({ appendChild: true, muted: false });
-      bodyAppendChildElArr.value.push(videoEl);
-      videoEl.setAttribute('videoid', obj.id);
-      videoEl.srcObject = event;
-      if (obj.volume !== undefined) {
-        videoEl.volume = obj.volume / 100;
+      try {
+        const event = await navigator.mediaDevices.getDisplayMedia({
+          video: true,
+          audio: true,
+        });
+        const videoEl = createVideo({ appendChild: true });
+        bodyAppendChildElArr.value.push(videoEl);
+        videoEl.setAttribute('videoid', obj.id);
+        videoEl.srcObject = event;
+        await new Promise((resolve) => {
+          videoEl.onloadedmetadata = () => {
+            const stream = videoEl
+              // @ts-ignore
+              .captureStream();
+            const width = stream.getVideoTracks()[0].getSettings().width!;
+            const height = stream.getVideoTracks()[0].getSettings().height!;
+            videoEl.width = width;
+            videoEl.height = height;
+
+            const canvasDom = markRaw(
+              new fabric.Image(videoEl, {
+                top: (item.rect?.top || 0) / window.devicePixelRatio,
+                left: (item.rect?.left || 0) / window.devicePixelRatio,
+                width,
+                height,
+              })
+            );
+            handleMoving({ canvasDom, id: item.id });
+            handleScaling({ canvasDom, id: item.id });
+            canvasDom.scale(
+              item.scaleInfo[window.devicePixelRatio].scaleX || 1
+            );
+            fabricCanvas.value!.add(canvasDom);
+            obj.videoEl = videoEl;
+            obj.canvasDom = canvasDom;
+            resolve({ videoEl, canvasDom });
+          };
+        });
+      } catch (error) {
+        console.error(error);
+        handleDel(obj);
+        err.push(obj.id);
       }
-      obj.videoEl = videoEl;
     }
+
     async function handleMicrophone() {
       const event = await navigator.mediaDevices.getUserMedia({
         video: false,
@@ -1039,7 +1069,7 @@ async function handleCache() {
   });
   await Promise.all(queue);
   canvasVideoStream.value = pushCanvasRef.value!.captureStream();
-  appStore.setAllTrack(res);
+  appStore.setAllTrack(res.filter((v) => !err.includes(v.id)));
 }
 
 function handleShowMediaModalCpt(val: MediaTypeEnum) {
@@ -1051,7 +1081,6 @@ function handleShowMediaModalCpt(val: MediaTypeEnum) {
 }
 
 function handleEdit(item: AppRootState['allTrack'][0]) {
-  console.log('handleEdit', item);
   currentMediaType.value = item.type;
   currentMediaData.value = item;
   isEdit.value = true;
@@ -1105,7 +1134,6 @@ async function addMediaOk(val: AppRootState['allTrack'][0]) {
       stream: event,
       id: videoTrack.id,
     });
-    console.log(scale, 'scalescale');
     setScaleInfo({ canvasDom, track: videoTrack, scale });
     videoTrack.videoEl = videoEl;
     // @ts-ignore
@@ -1542,7 +1570,6 @@ function handleChangeVolume(item: AppRootState['allTrack'][0], v) {
 }
 
 function handleDel(item: AppRootState['allTrack'][0]) {
-  console.log('handleDel', item);
   if (item.canvasDom !== undefined) {
     fabricCanvas.value?.remove(item.canvasDom);
     item.videoEl?.remove();