|
@@ -2,6 +2,7 @@ import { getRandomString } from 'billd-utils';
|
|
|
import { nextTick, onUnmounted, ref, watch } from 'vue';
|
|
import { nextTick, onUnmounted, ref, watch } from 'vue';
|
|
|
import { useRoute } from 'vue-router';
|
|
import { useRoute } from 'vue-router';
|
|
|
|
|
|
|
|
|
|
+import { URL_QUERY } from '@/constant';
|
|
|
import { commentAuthTip, loginTip } from '@/hooks/use-login';
|
|
import { commentAuthTip, loginTip } from '@/hooks/use-login';
|
|
|
import { useFlvPlay, useHlsPlay } from '@/hooks/use-play';
|
|
import { useFlvPlay, useHlsPlay } from '@/hooks/use-play';
|
|
|
import { useWebsocket } from '@/hooks/use-websocket';
|
|
import { useWebsocket } from '@/hooks/use-websocket';
|
|
@@ -16,13 +17,23 @@ import {
|
|
|
import { useAppStore } from '@/store/app';
|
|
import { useAppStore } from '@/store/app';
|
|
|
import { useCacheStore } from '@/store/cache';
|
|
import { useCacheStore } from '@/store/cache';
|
|
|
import { useNetworkStore } from '@/store/network';
|
|
import { useNetworkStore } from '@/store/network';
|
|
|
|
|
+import { ILiveRoom, LiveRoomTypeEnum } from '@/types/ILiveRoom';
|
|
|
import {
|
|
import {
|
|
|
- ILiveRoom,
|
|
|
|
|
- LiveRoomTypeEnum,
|
|
|
|
|
- LiveRoomUseCDNEnum,
|
|
|
|
|
-} from '@/types/ILiveRoom';
|
|
|
|
|
-import { WsMessageType, WsMsgTypeEnum } from '@/types/websocket';
|
|
|
|
|
-import { createVideo, videoFullBox, videoToCanvas } from '@/utils';
|
|
|
|
|
|
|
+ WsBatchSendOffer,
|
|
|
|
|
+ WsMessageType,
|
|
|
|
|
+ WsMsgTypeEnum,
|
|
|
|
|
+ WsOfferType,
|
|
|
|
|
+} from '@/types/websocket';
|
|
|
|
|
+import {
|
|
|
|
|
+ createVideo,
|
|
|
|
|
+ handleUserMedia,
|
|
|
|
|
+ videoFullBox,
|
|
|
|
|
+ videoToCanvas,
|
|
|
|
|
+} from '@/utils';
|
|
|
|
|
+
|
|
|
|
|
+import { useTip } from './use-tip';
|
|
|
|
|
+import { useWebRtcLive } from './webrtc/live';
|
|
|
|
|
+import { useWebRtcMeetingOne } from './webrtc/meetingOne';
|
|
|
|
|
|
|
|
export function usePull() {
|
|
export function usePull() {
|
|
|
const route = useRoute();
|
|
const route = useRoute();
|
|
@@ -47,11 +58,14 @@ export function usePull() {
|
|
|
const { mySocketId, initWs, roomLiving, anchorInfo, liveUserList, damuList } =
|
|
const { mySocketId, initWs, roomLiving, anchorInfo, liveUserList, damuList } =
|
|
|
useWebsocket();
|
|
useWebsocket();
|
|
|
const { updateWebRtcRtmpToRtcConfig, webRtcRtmpToRtc } = useWebRtcRtmpToRtc();
|
|
const { updateWebRtcRtmpToRtcConfig, webRtcRtmpToRtc } = useWebRtcRtmpToRtc();
|
|
|
-
|
|
|
|
|
|
|
+ const { updateWebRtcLiveConfig, webRtcLive } = useWebRtcLive();
|
|
|
|
|
+ const { updateWebRtcMeetingOneConfig, webRtcMeetingOne } =
|
|
|
|
|
+ useWebRtcMeetingOne();
|
|
|
const { flvVideoEl, flvIsPlaying, startFlvPlay, destroyFlv } = useFlvPlay();
|
|
const { flvVideoEl, flvIsPlaying, startFlvPlay, destroyFlv } = useFlvPlay();
|
|
|
const { hlsVideoEl, hlsIsPlaying, startHlsPlay, destroyHls } = useHlsPlay();
|
|
const { hlsVideoEl, hlsIsPlaying, startHlsPlay, destroyHls } = useHlsPlay();
|
|
|
const stopDrawingArr = ref<any[]>([]);
|
|
const stopDrawingArr = ref<any[]>([]);
|
|
|
const rtcVideo = ref<HTMLVideoElement[]>([]);
|
|
const rtcVideo = ref<HTMLVideoElement[]>([]);
|
|
|
|
|
+ const userStream = ref<MediaStream>();
|
|
|
|
|
|
|
|
let changeWrapSizeFn;
|
|
let changeWrapSizeFn;
|
|
|
|
|
|
|
@@ -234,6 +248,130 @@ export function usePull() {
|
|
|
});
|
|
});
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ async function handleWebRtcLivePlay(data) {
|
|
|
|
|
+ console.log('handleWebRtcLivePlay');
|
|
|
|
|
+ handleStopDrawing();
|
|
|
|
|
+ videoLoading.value = true;
|
|
|
|
|
+ appStore.liveLine = LiveLineEnum.rtc;
|
|
|
|
|
+ updateWebRtcLiveConfig({
|
|
|
|
|
+ roomId: roomId.value,
|
|
|
|
|
+ canvasVideoStream: null,
|
|
|
|
|
+ });
|
|
|
|
|
+ const videoEl = createVideo({
|
|
|
|
|
+ appendChild: true,
|
|
|
|
|
+ muted: appStore.pageIsClick ? cacheStore.muted : true,
|
|
|
|
|
+ });
|
|
|
|
|
+ rtcVideo.value.push(videoEl);
|
|
|
|
|
+ webRtcLive.newWebRtc({
|
|
|
|
|
+ sender: mySocketId.value,
|
|
|
|
|
+ receiver: data.sender,
|
|
|
|
|
+ videoEl,
|
|
|
|
|
+ sucessCb: (stream) => {
|
|
|
|
|
+ remoteStream.value.push(stream);
|
|
|
|
|
+ },
|
|
|
|
|
+ });
|
|
|
|
|
+
|
|
|
|
|
+ await webRtcLive.sendAnswer({
|
|
|
|
|
+ sender: mySocketId.value,
|
|
|
|
|
+ // data.data.receiver是接收者;我们现在new pc,发送者是自己,接收者肯定是房主,不能是data.data.receiver,因为data.data.receiver是自己
|
|
|
|
|
+ receiver: data.sender,
|
|
|
|
|
+ sdp: data.sdp,
|
|
|
|
|
+ });
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ async function handleWebRtcMeetingOnePlay(data) {
|
|
|
|
|
+ await handleMeeting();
|
|
|
|
|
+ console.log('handleWebRtcLivePlay');
|
|
|
|
|
+ handleStopDrawing();
|
|
|
|
|
+ videoLoading.value = true;
|
|
|
|
|
+ appStore.liveLine = LiveLineEnum.rtc;
|
|
|
|
|
+ const videoEl = createVideo({
|
|
|
|
|
+ appendChild: true,
|
|
|
|
|
+ muted: appStore.pageIsClick ? cacheStore.muted : true,
|
|
|
|
|
+ });
|
|
|
|
|
+ rtcVideo.value.push(videoEl);
|
|
|
|
|
+ webRtcMeetingOne.newWebRtc({
|
|
|
|
|
+ // 因为这里是收到offer,而offer是房主发的,所以此时的data.data.sender是房主;data.data.receiver是接收者;
|
|
|
|
|
+ // 但是这里的nativeWebRtc的sender,得是自己,不能是data.data.sender,不要混淆
|
|
|
|
|
+ sender: mySocketId.value,
|
|
|
|
|
+ receiver: data.sender,
|
|
|
|
|
+ videoEl,
|
|
|
|
|
+ sucessCb: (stream) => {
|
|
|
|
|
+ remoteStream.value.push(stream);
|
|
|
|
|
+ },
|
|
|
|
|
+ });
|
|
|
|
|
+ webRtcMeetingOne.addTrack({
|
|
|
|
|
+ stream: userStream.value,
|
|
|
|
|
+ receiver: data.sender,
|
|
|
|
|
+ });
|
|
|
|
|
+ await webRtcMeetingOne.sendAnswer({
|
|
|
|
|
+ sender: mySocketId.value,
|
|
|
|
|
+ // data.data.receiver是接收者;我们现在new pc,发送者是自己,接收者肯定是房主,不能是data.data.receiver,因为data.data.receiver是自己
|
|
|
|
|
+ receiver: data.sender,
|
|
|
|
|
+ sdp: data.sdp,
|
|
|
|
|
+ });
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ async function handleMeeting() {
|
|
|
|
|
+ await useTip({
|
|
|
|
|
+ content: '是否加入会议?',
|
|
|
|
|
+ });
|
|
|
|
|
+ const stream = await handleUserMedia({
|
|
|
|
|
+ video: true,
|
|
|
|
|
+ audio: true,
|
|
|
|
|
+ });
|
|
|
|
|
+ userStream.value = stream;
|
|
|
|
|
+ networkStore.wsMap.get(roomId.value)?.send<WsBatchSendOffer['data']>({
|
|
|
|
|
+ requestId: getRandomString(8),
|
|
|
|
|
+ msgType: WsMsgTypeEnum.batchSendOffer,
|
|
|
|
|
+ data: {
|
|
|
|
|
+ roomId: roomId.value,
|
|
|
|
|
+ },
|
|
|
|
|
+ });
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ function initRtcReceive() {
|
|
|
|
|
+ const ws = networkStore.wsMap.get(roomId.value);
|
|
|
|
|
+ if (!ws?.socketIo) return;
|
|
|
|
|
+ // 收到nativeWebRtcOffer
|
|
|
|
|
+ ws.socketIo.on(
|
|
|
|
|
+ WsMsgTypeEnum.nativeWebRtcOffer,
|
|
|
|
|
+ (data: WsOfferType['data']) => {
|
|
|
|
|
+ console.log(
|
|
|
|
|
+ '收2到nativeWebRtcOffer',
|
|
|
|
|
+ data.live_room.type,
|
|
|
|
|
+ LiveRoomTypeEnum.wertc_live,
|
|
|
|
|
+ data
|
|
|
|
|
+ );
|
|
|
|
|
+ if (data.live_room.type === LiveRoomTypeEnum.wertc_live) {
|
|
|
|
|
+ if (data.receiver === mySocketId.value) {
|
|
|
|
|
+ console.warn('是发给我的nativeWebRtcOffer-wertc_live');
|
|
|
|
|
+ if (networkStore.rtcMap.get(data.sender)) {
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+ handleWebRtcLivePlay(data);
|
|
|
|
|
+ } else {
|
|
|
|
|
+ console.error('不是发给我的nativeWebRtcOffer');
|
|
|
|
|
+ }
|
|
|
|
|
+ } else if (data.live_room.type === LiveRoomTypeEnum.wertc_meeting_one) {
|
|
|
|
|
+ if (data.receiver === mySocketId.value) {
|
|
|
|
|
+ console.warn('是发给我的nativeWebRtcOffer-wertc_meeting_one');
|
|
|
|
|
+ updateWebRtcMeetingOneConfig({
|
|
|
|
|
+ roomId: roomId.value,
|
|
|
|
|
+ anchorStream: null,
|
|
|
|
|
+ });
|
|
|
|
|
+ if (networkStore.rtcMap.get(data.sender)) {
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+ handleWebRtcMeetingOnePlay(data);
|
|
|
|
|
+ } else {
|
|
|
|
|
+ console.error('不是发给我的nativeWebRtcOffer');
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ );
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
function handleHlsPlay() {
|
|
function handleHlsPlay() {
|
|
|
console.log('handleHlsPlay', hlsurl.value);
|
|
console.log('handleHlsPlay', hlsurl.value);
|
|
|
handleStopDrawing();
|
|
handleStopDrawing();
|
|
@@ -256,20 +394,18 @@ export function usePull() {
|
|
|
|
|
|
|
|
function handlePlay(data: ILiveRoom) {
|
|
function handlePlay(data: ILiveRoom) {
|
|
|
roomLiving.value = true;
|
|
roomLiving.value = true;
|
|
|
- flvurl.value =
|
|
|
|
|
- data.cdn === LiveRoomUseCDNEnum.yes &&
|
|
|
|
|
- [LiveRoomTypeEnum.tencent_css, LiveRoomTypeEnum.tencent_css_pk].includes(
|
|
|
|
|
- data.type!
|
|
|
|
|
- )
|
|
|
|
|
- ? data.cdn_flv_url!
|
|
|
|
|
- : data.flv_url!;
|
|
|
|
|
- hlsurl.value =
|
|
|
|
|
- data.cdn === LiveRoomUseCDNEnum.yes &&
|
|
|
|
|
- [LiveRoomTypeEnum.tencent_css, LiveRoomTypeEnum.tencent_css_pk].includes(
|
|
|
|
|
- data.type!
|
|
|
|
|
- )
|
|
|
|
|
- ? data.cdn_hls_url!
|
|
|
|
|
- : data.hls_url!;
|
|
|
|
|
|
|
+ flvurl.value = [
|
|
|
|
|
+ LiveRoomTypeEnum.tencent_css,
|
|
|
|
|
+ LiveRoomTypeEnum.tencent_css_pk,
|
|
|
|
|
+ ].includes(data.type!)
|
|
|
|
|
+ ? data.cdn_flv_url!
|
|
|
|
|
+ : data.flv_url!;
|
|
|
|
|
+ hlsurl.value = [
|
|
|
|
|
+ LiveRoomTypeEnum.tencent_css,
|
|
|
|
|
+ LiveRoomTypeEnum.tencent_css_pk,
|
|
|
|
|
+ ].includes(data.type!)
|
|
|
|
|
+ ? data.cdn_hls_url!
|
|
|
|
|
+ : data.hls_url!;
|
|
|
function play() {
|
|
function play() {
|
|
|
if (appStore.liveLine === LiveLineEnum.flv) {
|
|
if (appStore.liveLine === LiveLineEnum.flv) {
|
|
|
handleFlvPlay();
|
|
handleFlvPlay();
|
|
@@ -277,7 +413,7 @@ export function usePull() {
|
|
|
handleHlsPlay();
|
|
handleHlsPlay();
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
- if (LiveRoomTypeEnum.pk === data.type && !route.query.pkKey) {
|
|
|
|
|
|
|
+ if (LiveRoomTypeEnum.pk === data.type && !route.query[URL_QUERY.pkKey]) {
|
|
|
play();
|
|
play();
|
|
|
} else if (
|
|
} else if (
|
|
|
[
|
|
[
|
|
@@ -308,7 +444,7 @@ export function usePull() {
|
|
|
watch(
|
|
watch(
|
|
|
[() => roomLiving.value, () => appStore.liveRoomInfo],
|
|
[() => roomLiving.value, () => appStore.liveRoomInfo],
|
|
|
([val, liveRoomInfo]) => {
|
|
([val, liveRoomInfo]) => {
|
|
|
- if (val && liveRoomInfo) {
|
|
|
|
|
|
|
+ if (val && liveRoomInfo && liveRoomInfo.type !== undefined) {
|
|
|
showPlayBtn.value = false;
|
|
showPlayBtn.value = false;
|
|
|
if (
|
|
if (
|
|
|
[
|
|
[
|
|
@@ -323,13 +459,14 @@ export function usePull() {
|
|
|
LiveRoomTypeEnum.forward_all,
|
|
LiveRoomTypeEnum.forward_all,
|
|
|
].includes(liveRoomInfo.type!)
|
|
].includes(liveRoomInfo.type!)
|
|
|
) {
|
|
) {
|
|
|
- handlePlay(liveRoomInfo!);
|
|
|
|
|
- } else if (LiveRoomTypeEnum.pk === liveRoomInfo.type!) {
|
|
|
|
|
- if (!route.query.pkKey) {
|
|
|
|
|
- handlePlay(liveRoomInfo!);
|
|
|
|
|
|
|
+ handlePlay(liveRoomInfo);
|
|
|
|
|
+ } else if (LiveRoomTypeEnum.pk === liveRoomInfo.type) {
|
|
|
|
|
+ if (!route.query[URL_QUERY.pkKey]) {
|
|
|
|
|
+ handlePlay(liveRoomInfo);
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
+ console.log('kkkkk', val, liveRoomInfo?.type);
|
|
|
if (!roomLiving.value) {
|
|
if (!roomLiving.value) {
|
|
|
closeRtc();
|
|
closeRtc();
|
|
|
handleStopDrawing();
|
|
handleStopDrawing();
|
|
@@ -503,6 +640,7 @@ export function usePull() {
|
|
|
|
|
|
|
|
return {
|
|
return {
|
|
|
initWs,
|
|
initWs,
|
|
|
|
|
+ initRtcReceive,
|
|
|
videoWrapRef,
|
|
videoWrapRef,
|
|
|
handlePlay,
|
|
handlePlay,
|
|
|
handleStopDrawing,
|
|
handleStopDrawing,
|