shuisheng 2 лет назад
Родитель
Сommit
c7783ed68c
4 измененных файлов с 46 добавлено и 123 удалено
  1. 1 59
      src/hooks/use-push.ts
  2. 1 2
      src/network/webRTC.ts
  3. 8 4
      src/utils/index.ts
  4. 36 58
      src/views/push/index.vue

+ 1 - 59
src/hooks/use-push.ts

@@ -8,7 +8,7 @@ import {
 } from '@/api/userLiveRoom';
 } from '@/api/userLiveRoom';
 import { DanmuMsgTypeEnum, ILiveRoom, IMessage } from '@/interface';
 import { DanmuMsgTypeEnum, ILiveRoom, IMessage } from '@/interface';
 import { WsMsgTypeEnum } from '@/network/webSocket';
 import { WsMsgTypeEnum } from '@/network/webSocket';
-import { AppRootState, useAppStore } from '@/store/app';
+import { useAppStore } from '@/store/app';
 import { useNetworkStore } from '@/store/network';
 import { useNetworkStore } from '@/store/network';
 import { useUserStore } from '@/store/user';
 import { useUserStore } from '@/store/user';
 import { createVideo, generateBase64 } from '@/utils';
 import { createVideo, generateBase64 } from '@/utils';
@@ -194,62 +194,6 @@ export function usePush() {
     closeWs();
     closeWs();
     closeRtc();
     closeRtc();
   });
   });
-  function addTrack(addTrackInfo: { track; stream }) {
-    networkStore.rtcMap.forEach((rtc) => {
-      const sender = rtc.peerConnection
-        ?.getSenders()
-        .find((sender) => sender.track?.id === addTrackInfo.track?.id);
-      if (!sender) {
-        console.log(
-          'pc添加track-开播后中途添加,替换它',
-          addTrackInfo.track?.id,
-          canvasVideoStream.value!.getAudioTracks()[0]
-        );
-        rtc.peerConnection
-          ?.getSenders()
-          ?.find((sender) => sender.track?.kind === 'audio')
-          ?.replaceTrack(canvasVideoStream.value!.getAudioTracks()[0]);
-      }
-    });
-    const mixedStream = new MediaStream();
-    appStore.allTrack.forEach((item) => {
-      if (item.track) {
-        mixedStream.addTrack(item.track);
-      }
-    });
-    console.log('addTrack后结果的音频轨', mixedStream.getAudioTracks());
-    console.log('addTrack后结果的视频轨', mixedStream.getVideoTracks());
-    console.log(
-      'addTrack后canvasVideoStream音频轨',
-      canvasVideoStream.value?.getAudioTracks()
-    );
-    console.log(
-      'addTrack后canvasVideoStream视频轨',
-      canvasVideoStream.value?.getVideoTracks()
-    );
-    localStream.value = mixedStream;
-  }
-
-  function delTrack(delTrackInfo: AppRootState['allTrack'][0]) {
-    networkStore.rtcMap.forEach((rtc) => {
-      const sender = rtc.peerConnection
-        ?.getSenders()
-        .find((sender) => sender.track?.id === delTrackInfo.track?.id);
-      if (sender) {
-        console.log('删除track', delTrackInfo, sender);
-        rtc.peerConnection?.removeTrack(sender);
-      }
-    });
-    const mixedStream = new MediaStream();
-    appStore.allTrack.forEach((item) => {
-      if (item.track) {
-        mixedStream.addTrack(item.track);
-      }
-    });
-    console.log('delTrack后结果的音频轨', mixedStream.getAudioTracks());
-    console.log('delTrack后结果的视频轨', mixedStream.getVideoTracks());
-    localStream.value = mixedStream;
-  }
 
 
   function closeWs() {
   function closeWs() {
     const instance = networkStore.wsMap.get(roomId.value);
     const instance = networkStore.wsMap.get(roomId.value);
@@ -405,8 +349,6 @@ export function usePush() {
     endLive,
     endLive,
     sendDanmu,
     sendDanmu,
     keydownDanmu,
     keydownDanmu,
-    addTrack,
-    delTrack,
     mySocketId,
     mySocketId,
     lastCoverImg,
     lastCoverImg,
     localStream,
     localStream,

+ 1 - 2
src/network/webRTC.ts

@@ -343,12 +343,11 @@ export class WebRTCClass {
     if (!this.peerConnection) return;
     if (!this.peerConnection) return;
     // 废弃:https://developer.mozilla.org/en-US/docs/Web/API/RTCPeerConnection/addStream
     // 废弃:https://developer.mozilla.org/en-US/docs/Web/API/RTCPeerConnection/addStream
     console.warn(`${this.roomId},开始监听pc的addstream`);
     console.warn(`${this.roomId},开始监听pc的addstream`);
-    this.peerConnection.addEventListener('addstream', (event: any) => {
+    this.peerConnection.addEventListener('addstream', () => {
       // console.warn(`${this.roomId},pc收到addstream事件`, event);
       // console.warn(`${this.roomId},pc收到addstream事件`, event);
       // console.log('addstream事件的stream', event.stream);
       // console.log('addstream事件的stream', event.stream);
       // console.log('addstream事件的视频轨', event.stream.getVideoTracks());
       // console.log('addstream事件的视频轨', event.stream.getVideoTracks());
       // console.log('addstream事件的音频轨', event.stream.getAudioTracks());
       // console.log('addstream事件的音频轨', event.stream.getAudioTracks());
-      // this.addTrack(event.stream, true);
     });
     });
 
 
     console.warn(`${this.roomId},开始监听pc的track`);
     console.warn(`${this.roomId},开始监听pc的track`);

+ 8 - 4
src/utils/index.ts

@@ -189,6 +189,7 @@ export const createVideo = ({
   muted = true,
   muted = true,
   autoplay = true,
   autoplay = true,
   appendChild = false,
   appendChild = false,
+  show = false,
 }) => {
 }) => {
   const videoEl = document.createElement('video');
   const videoEl = document.createElement('video');
   videoEl.autoplay = autoplay;
   videoEl.autoplay = autoplay;
@@ -204,13 +205,16 @@ export const createVideo = ({
     e.preventDefault();
     e.preventDefault();
   };
   };
   if (appendChild) {
   if (appendChild) {
-    videoEl.style.width = `1px`;
-    videoEl.style.height = `1px`;
+    if (!show) {
+      videoEl.style.width = `1px`;
+      videoEl.style.height = `1px`;
+      videoEl.style.opacity = '0';
+      videoEl.style.pointerEvents = 'none';
+    }
     videoEl.style.position = 'fixed';
     videoEl.style.position = 'fixed';
     videoEl.style.bottom = '0';
     videoEl.style.bottom = '0';
     videoEl.style.right = '0';
     videoEl.style.right = '0';
-    videoEl.style.opacity = '0';
-    videoEl.style.pointerEvents = 'none';
+
     document.body.appendChild(videoEl);
     document.body.appendChild(videoEl);
   }
   }
   return videoEl;
   return videoEl;

+ 36 - 58
src/views/push/index.vue

@@ -301,6 +301,7 @@ import { useRTCParams } from '@/hooks/use-rtc-params';
 import { DanmuMsgTypeEnum, MediaTypeEnum } from '@/interface';
 import { DanmuMsgTypeEnum, MediaTypeEnum } from '@/interface';
 import { AppRootState, useAppStore } from '@/store/app';
 import { AppRootState, useAppStore } from '@/store/app';
 import { useResourceCacheStore } from '@/store/cache';
 import { useResourceCacheStore } from '@/store/cache';
+import { useNetworkStore } from '@/store/network';
 import { useUserStore } from '@/store/user';
 import { useUserStore } from '@/store/user';
 import {
 import {
   createVideo,
   createVideo,
@@ -319,6 +320,7 @@ import SelectMediaModalCpt from './selectMediaModal/index.vue';
 const route = useRoute();
 const route = useRoute();
 const userStore = useUserStore();
 const userStore = useUserStore();
 const appStore = useAppStore();
 const appStore = useAppStore();
+const networkStore = useNetworkStore();
 const resourceCacheStore = useResourceCacheStore();
 const resourceCacheStore = useResourceCacheStore();
 const { maxBitrate, maxFramerate, resolutionRatio, allMediaTypeList } =
 const { maxBitrate, maxFramerate, resolutionRatio, allMediaTypeList } =
   useRTCParams();
   useRTCParams();
@@ -329,8 +331,6 @@ const {
   endLive,
   endLive,
   sendDanmu,
   sendDanmu,
   keydownDanmu,
   keydownDanmu,
-  addTrack,
-  delTrack,
   mySocketId,
   mySocketId,
   lastCoverImg,
   lastCoverImg,
   canvasVideoStream,
   canvasVideoStream,
@@ -459,42 +459,47 @@ function handleMixedAudio() {
   console.log('handleMixedAudio');
   console.log('handleMixedAudio');
   const allAudioTrack = appStore.allTrack.filter((item) => item.audio === 1);
   const allAudioTrack = appStore.allTrack.filter((item) => item.audio === 1);
   audioCtx.value = new AudioContext();
   audioCtx.value = new AudioContext();
-  const gainNode = audioCtx.value.createGain();
+  if (canvasVideoStream.value?.getAudioTracks()[0]) {
+    canvasVideoStream.value.removeTrack(
+      canvasVideoStream.value.getAudioTracks()[0]
+    );
+  }
+  const res: { source: MediaStreamAudioSourceNode; gainNode: GainNode }[] = [];
   allAudioTrack.forEach((item) => {
   allAudioTrack.forEach((item) => {
     if (!audioCtx.value || !item.stream) return;
     if (!audioCtx.value || !item.stream) return;
-    const audioInput = audioCtx.value.createMediaStreamSource(item.stream);
-    audioInput.connect(gainNode);
+    const source = audioCtx.value.createMediaStreamSource(item.stream);
+    const gainNode = audioCtx.value.createGain();
+    gainNode.gain.value = (item.volume || 100) / 100;
+    source.connect(gainNode);
+    res.push({ source, gainNode });
     console.log('混流', item.stream?.id, item.stream);
     console.log('混流', item.stream?.id, item.stream);
   });
   });
-
   const destination = audioCtx.value.createMediaStreamDestination();
   const destination = audioCtx.value.createMediaStreamDestination();
-  if (canvasVideoStream.value?.getAudioTracks()[0]) {
-    canvasVideoStream.value.removeTrack(
-      canvasVideoStream.value?.getAudioTracks()[0]
-    );
-  }
-  canvasVideoStream.value?.addTrack(destination.stream.getAudioTracks()[0]);
-  // streamTmp = destination.stream;
-  if (canvasVideoStream.value?.getAudioTracks()[0]) {
-    canvasVideoStream.value.removeTrack(
-      canvasVideoStream.value?.getAudioTracks()[0]
-    );
-    canvasVideoStream.value?.addTrack(destination.stream.getAudioTracks()[0]);
-  } else {
-    canvasVideoStream.value?.addTrack(destination.stream.getAudioTracks()[0]);
-  }
-  console.log(
-    canvasVideoStream.value?.getAudioTracks(),
-    'canvasVideoStreamcanvasVideoStream'
-  );
-  gainNode.connect(destination);
+  res.forEach((item) => {
+    item.source.connect(item.gainNode);
+    item.gainNode.connect(destination);
+  });
   if (webaudioVideo.value) {
   if (webaudioVideo.value) {
     webaudioVideo.value.remove();
     webaudioVideo.value.remove();
   }
   }
-  webaudioVideo.value = createVideo({ appendChild: true });
+  webaudioVideo.value = createVideo({ appendChild: true, show: true });
   bodyAppendChildElArr.value.push(webaudioVideo.value);
   bodyAppendChildElArr.value.push(webaudioVideo.value);
   webaudioVideo.value.className = 'web-audio-video';
   webaudioVideo.value.className = 'web-audio-video';
-  webaudioVideo.value.srcObject = destination.stream;
+  webaudioVideo.value!.srcObject = destination.stream;
+  const resAudio = destination.stream.getAudioTracks()[0];
+  canvasVideoStream.value?.addTrack(resAudio);
+  networkStore.rtcMap.forEach((rtc) => {
+    const sender = rtc.peerConnection
+      ?.getSenders()
+      .find((sender) => sender.track?.id === resAudio.id);
+    if (!sender) {
+      rtc.peerConnection
+        ?.getSenders()
+        ?.find((sender) => sender.track?.kind === 'audio')
+        ?.replaceTrack(resAudio);
+    }
+  });
+  console.log(canvasVideoStream.value?.getAudioTracks());
 }
 }
 
 
 function handleStartLive() {
 function handleStartLive() {
@@ -1130,16 +1135,11 @@ async function addMediaOk(val: AppRootState['allTrack'][0]) {
       appStore.setAllTrack(res);
       appStore.setAllTrack(res);
       resourceCacheStore.setList(res);
       resourceCacheStore.setList(res);
       handleMixedAudio();
       handleMixedAudio();
-      // @ts-ignore
-      addTrack(videoTrack);
-      // @ts-ignore
-      addTrack(audioTrack);
     } else {
     } else {
       const res = [...appStore.allTrack, videoTrack];
       const res = [...appStore.allTrack, videoTrack];
       appStore.setAllTrack(res);
       appStore.setAllTrack(res);
       resourceCacheStore.setList(res);
       resourceCacheStore.setList(res);
       // @ts-ignore
       // @ts-ignore
-      addTrack(videoTrack);
     }
     }
 
 
     console.log('获取窗口成功');
     console.log('获取窗口成功');
@@ -1178,7 +1178,6 @@ async function addMediaOk(val: AppRootState['allTrack'][0]) {
     appStore.setAllTrack(res);
     appStore.setAllTrack(res);
     resourceCacheStore.setList(res);
     resourceCacheStore.setList(res);
     // @ts-ignore
     // @ts-ignore
-    addTrack(videoTrack);
     console.log('获取摄像头成功');
     console.log('获取摄像头成功');
   } else if (val.type === MediaTypeEnum.microphone) {
   } else if (val.type === MediaTypeEnum.microphone) {
     const event = await navigator.mediaDevices.getUserMedia({
     const event = await navigator.mediaDevices.getUserMedia({
@@ -1210,8 +1209,6 @@ async function addMediaOk(val: AppRootState['allTrack'][0]) {
     appStore.setAllTrack(res);
     appStore.setAllTrack(res);
     resourceCacheStore.setList(res);
     resourceCacheStore.setList(res);
     handleMixedAudio();
     handleMixedAudio();
-    // @ts-ignore
-    addTrack(microphoneVideoTrack);
 
 
     console.log('获取麦克风成功');
     console.log('获取麦克风成功');
   } else if (val.type === MediaTypeEnum.txt) {
   } else if (val.type === MediaTypeEnum.txt) {
@@ -1251,7 +1248,6 @@ async function addMediaOk(val: AppRootState['allTrack'][0]) {
       } else {
       } else {
         txtTrack.scaleInfo[window.devicePixelRatio] = { scaleX: 1, scaleY: 1 };
         txtTrack.scaleInfo[window.devicePixelRatio] = { scaleX: 1, scaleY: 1 };
       }
       }
-      // @ts-ignore
       txtTrack.canvasDom = canvasDom;
       txtTrack.canvasDom = canvasDom;
       fabricCanvas.value.add(canvasDom);
       fabricCanvas.value.add(canvasDom);
     }
     }
@@ -1261,8 +1257,6 @@ async function addMediaOk(val: AppRootState['allTrack'][0]) {
     appStore.setAllTrack(res);
     appStore.setAllTrack(res);
     // @ts-ignore
     // @ts-ignore
     resourceCacheStore.setList(res);
     resourceCacheStore.setList(res);
-    // @ts-ignore
-    addTrack(txtTrack);
 
 
     console.log('获取文字成功', fabricCanvas.value);
     console.log('获取文字成功', fabricCanvas.value);
   } else if (val.type === MediaTypeEnum.time) {
   } else if (val.type === MediaTypeEnum.time) {
@@ -1293,7 +1287,6 @@ async function addMediaOk(val: AppRootState['allTrack'][0]) {
       handleMoving({ canvasDom, id: timeTrack.id });
       handleMoving({ canvasDom, id: timeTrack.id });
       handleScaling({ canvasDom, id: timeTrack.id });
       handleScaling({ canvasDom, id: timeTrack.id });
       timeTrack.timeInfo = val.timeInfo;
       timeTrack.timeInfo = val.timeInfo;
-      // @ts-ignore
       timeTrack.canvasDom = canvasDom;
       timeTrack.canvasDom = canvasDom;
       fabricCanvas.value.add(canvasDom);
       fabricCanvas.value.add(canvasDom);
     }
     }
@@ -1303,8 +1296,6 @@ async function addMediaOk(val: AppRootState['allTrack'][0]) {
     appStore.setAllTrack(res);
     appStore.setAllTrack(res);
     // @ts-ignore
     // @ts-ignore
     resourceCacheStore.setList(res);
     resourceCacheStore.setList(res);
-    // @ts-ignore
-    addTrack(timeTrack);
 
 
     console.log('获取时间成功', fabricCanvas.value);
     console.log('获取时间成功', fabricCanvas.value);
   } else if (val.type === MediaTypeEnum.stopwatch) {
   } else if (val.type === MediaTypeEnum.stopwatch) {
@@ -1336,7 +1327,6 @@ async function addMediaOk(val: AppRootState['allTrack'][0]) {
       handleMoving({ canvasDom, id: stopwatchTrack.id });
       handleMoving({ canvasDom, id: stopwatchTrack.id });
       handleScaling({ canvasDom, id: stopwatchTrack.id });
       handleScaling({ canvasDom, id: stopwatchTrack.id });
       stopwatchTrack.stopwatchInfo = val.stopwatchInfo;
       stopwatchTrack.stopwatchInfo = val.stopwatchInfo;
-      // @ts-ignore
       stopwatchTrack.canvasDom = canvasDom;
       stopwatchTrack.canvasDom = canvasDom;
       fabricCanvas.value.add(canvasDom);
       fabricCanvas.value.add(canvasDom);
     }
     }
@@ -1346,8 +1336,6 @@ async function addMediaOk(val: AppRootState['allTrack'][0]) {
     appStore.setAllTrack(res);
     appStore.setAllTrack(res);
     // @ts-ignore
     // @ts-ignore
     resourceCacheStore.setList(res);
     resourceCacheStore.setList(res);
-    // @ts-ignore
-    addTrack(stopwatchTrack);
 
 
     console.log('获取秒表成功', fabricCanvas.value);
     console.log('获取秒表成功', fabricCanvas.value);
   } else if (val.type === MediaTypeEnum.img) {
   } else if (val.type === MediaTypeEnum.img) {
@@ -1401,7 +1389,6 @@ async function addMediaOk(val: AppRootState['allTrack'][0]) {
       setScaleInfo({ canvasDom, track: imgTrack, scale });
       setScaleInfo({ canvasDom, track: imgTrack, scale });
       handleMoving({ canvasDom, id: imgTrack.id });
       handleMoving({ canvasDom, id: imgTrack.id });
       handleScaling({ canvasDom, id: imgTrack.id });
       handleScaling({ canvasDom, id: imgTrack.id });
-      // @ts-ignore
       imgTrack.canvasDom = canvasDom;
       imgTrack.canvasDom = canvasDom;
       fabricCanvas.value.add(canvasDom);
       fabricCanvas.value.add(canvasDom);
     }
     }
@@ -1411,8 +1398,6 @@ async function addMediaOk(val: AppRootState['allTrack'][0]) {
     appStore.setAllTrack(res);
     appStore.setAllTrack(res);
     // @ts-ignore
     // @ts-ignore
     resourceCacheStore.setList(res);
     resourceCacheStore.setList(res);
-    // @ts-ignore
-    addTrack(imgTrack);
 
 
     console.log('获取图片成功', fabricCanvas.value);
     console.log('获取图片成功', fabricCanvas.value);
   } else if (val.type === MediaTypeEnum.media) {
   } else if (val.type === MediaTypeEnum.media) {
@@ -1454,7 +1439,6 @@ async function addMediaOk(val: AppRootState['allTrack'][0]) {
       });
       });
       setScaleInfo({ canvasDom, track: mediaVideoTrack, scale });
       setScaleInfo({ canvasDom, track: mediaVideoTrack, scale });
       mediaVideoTrack.videoEl = videoEl;
       mediaVideoTrack.videoEl = videoEl;
-      // @ts-ignore
       mediaVideoTrack.canvasDom = canvasDom;
       mediaVideoTrack.canvasDom = canvasDom;
       if (stream.getAudioTracks()[0]) {
       if (stream.getAudioTracks()[0]) {
         console.log('视频有音频', stream.getAudioTracks()[0]);
         console.log('视频有音频', stream.getAudioTracks()[0]);
@@ -1475,14 +1459,10 @@ async function addMediaOk(val: AppRootState['allTrack'][0]) {
           volume: mediaVideoTrack.volume,
           volume: mediaVideoTrack.volume,
           scaleInfo: {},
           scaleInfo: {},
         };
         };
-        // @ts-ignore
         const res = [...appStore.allTrack, audioTrack];
         const res = [...appStore.allTrack, audioTrack];
         appStore.setAllTrack(res);
         appStore.setAllTrack(res);
         resourceCacheStore.setList(res);
         resourceCacheStore.setList(res);
         handleMixedAudio();
         handleMixedAudio();
-        // @ts-ignore
-
-        addTrack(audioTrack);
       }
       }
     }
     }
     const res = [...appStore.allTrack, mediaVideoTrack];
     const res = [...appStore.allTrack, mediaVideoTrack];
@@ -1490,9 +1470,6 @@ async function addMediaOk(val: AppRootState['allTrack'][0]) {
     appStore.setAllTrack(res);
     appStore.setAllTrack(res);
     // @ts-ignore
     // @ts-ignore
     resourceCacheStore.setList(res);
     resourceCacheStore.setList(res);
-    // @ts-ignore
-
-    addTrack(mediaVideoTrack);
 
 
     console.log('获取视频成功', fabricCanvas.value);
     console.log('获取视频成功', fabricCanvas.value);
   }
   }
@@ -1544,6 +1521,7 @@ function handleChangeMuted(item: AppRootState['allTrack'][0]) {
     item.volume = res ? 0 : normalVolume.value;
     item.volume = res ? 0 : normalVolume.value;
     item.muted = res;
     item.muted = res;
     resourceCacheStore.setList(appStore.allTrack);
     resourceCacheStore.setList(appStore.allTrack);
+    handleMixedAudio();
   }
   }
 }
 }
 
 
@@ -1565,19 +1543,19 @@ function handleChangeVolume(item: AppRootState['allTrack'][0], v) {
   });
   });
   appStore.setAllTrack(res);
   appStore.setAllTrack(res);
   resourceCacheStore.setList(res);
   resourceCacheStore.setList(res);
+  handleMixedAudio();
 }
 }
 
 
 function handleDel(item: AppRootState['allTrack'][0]) {
 function handleDel(item: AppRootState['allTrack'][0]) {
   console.log('handleDel', item);
   console.log('handleDel', item);
   if (item.canvasDom !== undefined) {
   if (item.canvasDom !== undefined) {
-    // @ts-ignore
     fabricCanvas.value?.remove(item.canvasDom);
     fabricCanvas.value?.remove(item.canvasDom);
     item.videoEl?.remove();
     item.videoEl?.remove();
   }
   }
   const res = appStore.allTrack.filter((iten) => iten.id !== item.id);
   const res = appStore.allTrack.filter((iten) => iten.id !== item.id);
   appStore.setAllTrack(res);
   appStore.setAllTrack(res);
   resourceCacheStore.setList(res);
   resourceCacheStore.setList(res);
-  delTrack(item);
+  handleMixedAudio();
 }
 }
 
 
 function handleStartMedia(item: { type: MediaTypeEnum; txt: string }) {
 function handleStartMedia(item: { type: MediaTypeEnum; txt: string }) {