| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001 |
- import { copyToClipBoard, getRandomString } from 'billd-utils';
- import { NButton } from 'naive-ui';
- import { computed, h, onUnmounted, ref, watch } from 'vue';
- import { useRoute } from 'vue-router';
- import { fetchVerifyPkKey } from '@/api/liveRoom';
- import { THEME_COLOR, WEBSOCKET_URL } from '@/constant';
- import { useRTCParams } from '@/hooks/use-rtcParams';
- import { useTip } from '@/hooks/use-tip';
- import { useWebRtcLive } from '@/hooks/webrtc/live';
- import { useWebRtcMeetingOne } from '@/hooks/webrtc/meetingOne';
- import { useWebRtcMeetingPk } from '@/hooks/webrtc/meetingPk';
- import { useWebRtcSrs } from '@/hooks/webrtc/srs';
- import { useWebRtcTencentcloudCss } from '@/hooks/webrtc/tencentcloudCss';
- import {
- DanmuMsgTypeEnum,
- ILiveUser,
- WsMessageContentTypeEnum,
- } from '@/interface';
- import router, { routerName } from '@/router';
- import { useAppStore } from '@/store/app';
- import { useNetworkStore } from '@/store/network';
- import { useUserStore } from '@/store/user';
- import { LiveRoomTypeEnum } from '@/types/ILiveRoom';
- import { IUser } from '@/types/IUser';
- import {
- WSGetRoomAllUserType,
- WSLivePkKeyType,
- WsAnswerType,
- WsBatchSendOffer,
- WsCandidateType,
- WsConnectStatusEnum,
- WsDisableSpeakingType,
- WsHeartbeatType,
- WsJoinType,
- WsLeavedType,
- WsMessageType,
- WsMsgTypeEnum,
- WsOfferType,
- WsOtherJoinType,
- WsRemoteDeskBehaviorType,
- WsRoomLivingType,
- WsStartLiveType,
- WsStartRemoteDesk,
- WsUpdateJoinInfoType,
- } from '@/types/websocket';
- import {
- createNullVideo,
- handleUserMedia,
- setAudioTrackContentHints,
- setVideoTrackContentHints,
- } from '@/utils';
- import {
- WebSocketClass,
- prettierReceiveWsMsg,
- } from '@/utils/network/webSocket';
- import { useForwardAll } from './webrtc/forwardAll';
- import { useForwardBilibili } from './webrtc/forwardBilibili';
- import { useForwardHuya } from './webrtc/forwardHuya';
- import { useWebRtcRemoteDesk } from './webrtc/remoteDesk';
- export const useWebsocket = () => {
- const route = useRoute();
- const appStore = useAppStore();
- const userStore = useUserStore();
- const networkStore = useNetworkStore();
- const {
- maxBitrate,
- maxFramerate,
- resolutionRatio,
- videoContentHint,
- audioContentHint,
- } = useRTCParams();
- const { updateWebRtcRemoteDeskConfig, webRtcRemoteDesk } =
- useWebRtcRemoteDesk();
- const { updateWebRtcMeetingPkConfig, webRtcMeetingPk } = useWebRtcMeetingPk();
- const { updateWebRtcSrsConfig, webRtcSrs } = useWebRtcSrs();
- const { updateForwardBilibiliConfig, forwardBilibili } = useForwardBilibili();
- const { updateForwardAllConfig, forwardAll } = useForwardAll();
- const { updateForwardHuyaConfig, forwardHuya } = useForwardHuya();
- const { updateWebRtcTencentcloudCssConfig, webRtcTencentcloudCss } =
- useWebRtcTencentcloudCss();
- const { updateWebRtcLiveConfig, webRtcLive } = useWebRtcLive();
- const { updateWebRtcMeetingOneConfig, webRtcMeetingOne } =
- useWebRtcMeetingOne();
- const connectStatus = ref<WsConnectStatusEnum>();
- const loopHeartbeatTimer = ref();
- const loopGetLiveUserTimer = ref();
- const liveUserList = ref<ILiveUser[]>([]);
- const roomId = ref('');
- const roomLiving = ref(false);
- const isAnchor = ref(false);
- const isRemoteDesk = ref(false);
- const isBilibili = ref(false);
- const anchorInfo = ref<IUser>();
- const anchorSocketId = ref('');
- const canvasVideoStream = ref<MediaStream>();
- const userStream = ref<MediaStream>();
- const lastCoverImg = ref('');
- const currentMaxBitrate = ref(maxBitrate.value[3].value);
- const currentMaxFramerate = ref(maxFramerate.value[2].value);
- const currentResolutionRatio = ref(resolutionRatio.value[3].value);
- const currentVideoContentHint = ref(videoContentHint.value[3].value);
- const currentAudioContentHint = ref(audioContentHint.value[0].value);
- const timerObj = ref({});
- const damuList = ref<WsMessageType[]>([]);
- onUnmounted(() => {
- clearInterval(loopHeartbeatTimer.value);
- clearInterval(loopGetLiveUserTimer.value);
- });
- watch(
- [() => userStore.userInfo?.id, () => connectStatus.value],
- ([userInfo, status]) => {
- if (userInfo && status === WsConnectStatusEnum.connect) {
- const ws = networkStore.wsMap.get(roomId.value);
- if (!ws) return;
- ws.send<WsUpdateJoinInfoType['data']>({
- requestId: getRandomString(8),
- msgType: WsMsgTypeEnum.updateJoinInfo,
- data: {
- live_room_id: Number(roomId.value),
- },
- });
- }
- },
- { immediate: true }
- );
- const mySocketId = computed(() => {
- return networkStore.wsMap.get(roomId.value)?.socketIo?.id || '-1';
- });
- function handleHeartbeat() {
- loopHeartbeatTimer.value = setInterval(() => {
- const ws = networkStore.wsMap.get(roomId.value);
- if (!ws) return;
- ws.send<WsHeartbeatType['data']>({
- requestId: getRandomString(8),
- msgType: WsMsgTypeEnum.heartbeat,
- data: {
- live_room_id: Number(roomId.value),
- roomLiving: isAnchor.value && roomLiving.value,
- },
- });
- }, 1000 * 5);
- }
- function handleStartLive({
- name,
- type,
- msrDelay,
- msrMaxDelay,
- }: {
- name?: string;
- type: LiveRoomTypeEnum;
- videoEl?: HTMLVideoElement;
- msrDelay: number;
- msrMaxDelay: number;
- }) {
- if (appStore.liveRoomInfo) {
- appStore.liveRoomInfo.type = type;
- }
- networkStore.wsMap.get(roomId.value)?.send<WsStartLiveType['data']>({
- requestId: getRandomString(8),
- msgType: WsMsgTypeEnum.startLive,
- data: {
- name: name!,
- type,
- msrDelay,
- msrMaxDelay,
- },
- });
- if (canvasVideoStream.value) {
- setVideoTrackContentHints(
- canvasVideoStream.value,
- // @ts-ignore
- currentVideoContentHint.value
- );
- setAudioTrackContentHints(
- canvasVideoStream.value,
- // @ts-ignore
- currentAudioContentHint.value
- );
- }
- if (type === LiveRoomTypeEnum.srs) {
- updateWebRtcSrsConfig({
- isPk: false,
- roomId: roomId.value,
- canvasVideoStream: canvasVideoStream.value,
- });
- webRtcSrs.newWebRtc({
- sender: mySocketId.value,
- receiver: 'srs',
- videoEl: createNullVideo(),
- });
- webRtcSrs.sendOffer({
- sender: mySocketId.value,
- receiver: 'srs',
- });
- } else if (type === LiveRoomTypeEnum.forward_bilibili) {
- updateForwardBilibiliConfig({
- isPk: false,
- roomId: roomId.value,
- canvasVideoStream: canvasVideoStream.value,
- });
- forwardBilibili.newWebRtc({
- sender: mySocketId.value,
- receiver: 'srs',
- videoEl: createNullVideo(),
- });
- forwardBilibili.sendOffer({
- sender: mySocketId.value,
- receiver: 'srs',
- });
- } else if (type === LiveRoomTypeEnum.forward_huya) {
- updateForwardHuyaConfig({
- isPk: false,
- roomId: roomId.value,
- canvasVideoStream: canvasVideoStream.value,
- });
- forwardHuya.newWebRtc({
- sender: mySocketId.value,
- receiver: 'srs',
- videoEl: createNullVideo(),
- });
- forwardHuya.sendOffer({
- sender: mySocketId.value,
- receiver: 'srs',
- });
- } else if (type === LiveRoomTypeEnum.forward_all) {
- updateForwardAllConfig({
- isPk: false,
- roomId: roomId.value,
- canvasVideoStream: canvasVideoStream.value,
- });
- forwardAll.newWebRtc({
- sender: mySocketId.value,
- receiver: 'srs',
- videoEl: createNullVideo(),
- });
- forwardAll.sendOffer({
- sender: mySocketId.value,
- receiver: 'srs',
- });
- } else if (type === LiveRoomTypeEnum.tencent_css) {
- updateWebRtcTencentcloudCssConfig({
- isPk: false,
- roomId: roomId.value,
- canvasVideoStream: canvasVideoStream.value,
- });
- webRtcTencentcloudCss.newWebRtc({
- sender: mySocketId.value,
- receiver: 'tencentcloud_css',
- videoEl: createNullVideo(),
- });
- webRtcTencentcloudCss.sendOffer({
- sender: mySocketId.value,
- receiver: 'tencentcloud_css',
- });
- } else if (type === LiveRoomTypeEnum.pk) {
- updateWebRtcSrsConfig({
- isPk: true,
- roomId: roomId.value,
- canvasVideoStream: canvasVideoStream.value,
- });
- webRtcSrs.newWebRtc({
- sender: mySocketId.value,
- receiver: 'srs',
- videoEl: createNullVideo(),
- });
- webRtcSrs.sendOffer({
- sender: mySocketId.value,
- receiver: 'srs',
- });
- } else if (type === LiveRoomTypeEnum.tencent_css_pk) {
- updateWebRtcTencentcloudCssConfig({
- isPk: true,
- roomId: roomId.value,
- canvasVideoStream: canvasVideoStream.value,
- });
- webRtcTencentcloudCss.newWebRtc({
- sender: mySocketId.value,
- receiver: 'tencentcloud_css',
- videoEl: createNullVideo(),
- });
- webRtcTencentcloudCss.sendOffer({
- sender: mySocketId.value,
- receiver: 'tencentcloud_css',
- });
- }
- }
- function sendJoin() {
- const instance = networkStore.wsMap.get(roomId.value);
- if (!instance) return;
- instance.send<WsJoinType['data']>({
- requestId: getRandomString(8),
- msgType: WsMsgTypeEnum.join,
- data: {
- isBilibili: isBilibili.value,
- isRemoteDesk: isRemoteDesk.value,
- socket_id: mySocketId.value,
- live_room_id: Number(roomId.value),
- user_info: userStore.userInfo,
- },
- });
- }
- function initReceive() {
- const ws = networkStore.wsMap.get(roomId.value);
- if (!ws?.socketIo) return;
- // websocket连接成功
- ws.socketIo.on(WsConnectStatusEnum.connect, () => {
- prettierReceiveWsMsg(WsConnectStatusEnum.connect, ws.socketIo);
- handleHeartbeat();
- if (!ws) return;
- connectStatus.value = WsConnectStatusEnum.connect;
- ws.status = WsConnectStatusEnum.connect;
- ws.update();
- sendJoin();
- });
- // websocket连接断开
- ws.socketIo.on(WsConnectStatusEnum.disconnect, (err) => {
- prettierReceiveWsMsg(WsConnectStatusEnum.disconnect, ws);
- console.log('websocket连接断开', err);
- if (!ws) return;
- ws.status = WsConnectStatusEnum.disconnect;
- ws.update();
- });
- // 收到livePkKey
- ws.socketIo.on(WsMsgTypeEnum.livePkKey, (data: WSLivePkKeyType['data']) => {
- console.log('收到livePkKey', data);
- const url = router.resolve({
- name: routerName.pull,
- params: { roomId: data.live_room_id },
- query: {
- pkKey: data.key,
- },
- });
- const pkurl = `${window.location.origin}${url.href}`;
- useTip({
- title: '邀请主播加入PK',
- width: '360px',
- hiddenCancel: true,
- content: h('div', [
- h('div', { style: { marginBottom: '5px' } }, `${pkurl}`),
- h(
- NButton,
- {
- size: 'small',
- type: 'primary',
- color: THEME_COLOR,
- onClick: () => {
- copyToClipBoard(pkurl);
- window.$message.success('复制成功!');
- },
- },
- () => '复制链接' // 用箭头函数返回性能更好。
- ),
- h('div', { style: { marginTop: '5px' } }, '注意,有效期:5分钟'),
- ]),
- }).catch(() => {});
- });
- // 收到startRemoteDesk
- ws.socketIo.on(WsMsgTypeEnum.startRemoteDesk, (data: WsStartRemoteDesk) => {
- console.log('收到startRemoteDesk', data);
- if (data.data.receiver === mySocketId.value) {
- appStore.remoteDesk.startRemoteDesk = true;
- appStore.remoteDesk.sender = data.data.sender;
- }
- });
- // 收到srsOffer
- ws.socketIo.on(WsMsgTypeEnum.srsOffer, (data: WsOfferType['data']) => {
- console.log('收到srsOffer', data);
- });
- // 收到srsAnswer
- ws.socketIo.on(WsMsgTypeEnum.srsAnswer, (data: WsAnswerType['data']) => {
- console.log('收到srsAnswer', data);
- });
- // 收到srsCandidate
- ws.socketIo.on(
- WsMsgTypeEnum.srsCandidate,
- (data: WsCandidateType['data']) => {
- console.log('收到srsCandidate', data);
- if (data.receiver === mySocketId.value) {
- console.warn('是发给我的srsCandidate');
- const rtc = networkStore.rtcMap.get(data.sender);
- rtc?.addIceCandidate(data.candidate);
- } else {
- console.error('不是发给我的srsCandidate');
- }
- }
- );
- // 收到nativeWebRtcOffer
- ws.socketIo.on(
- WsMsgTypeEnum.nativeWebRtcOffer,
- async (data: WsOfferType['data']) => {
- console.log('收到nativeWebRtcOffer', data);
- if (data.isRemoteDesk) {
- if (data.receiver === mySocketId.value) {
- console.warn('是发给我的nativeWebRtcOffer-isRemoteDesk');
- if (networkStore.rtcMap.get(data.sender)) {
- return;
- }
- updateWebRtcRemoteDeskConfig({
- roomId: roomId.value,
- userStream: userStream.value,
- anchorStream: canvasVideoStream.value,
- });
- webRtcRemoteDesk.newWebRtc({
- // 因为这里是收到offer,而offer是房主发的,所以此时的data.data.sender是房主;data.data.receiver是接收者;
- // 但是这里的nativeWebRtc的sender,得是自己,不能是data.data.sender,不要混淆
- sender: mySocketId.value,
- receiver: data.sender,
- videoEl: createNullVideo(),
- });
- await webRtcRemoteDesk.sendAnswer({
- sender: mySocketId.value,
- // data.data.receiver是接收者;我们现在new pc,发送者是自己,接收者肯定是房主,不能是data.data.receiver,因为data.data.receiver是自己
- receiver: data.sender,
- sdp: data.sdp,
- });
- } else {
- console.error('不是发给我的nativeWebRtcOffer-isRemoteDesk');
- }
- return;
- }
- if (
- data.live_room.type === LiveRoomTypeEnum.pk ||
- data.live_room.type === LiveRoomTypeEnum.tencent_css_pk
- ) {
- if (!route.query.pkKey) {
- return;
- }
- if (data.receiver === mySocketId.value) {
- console.warn('是发给我的nativeWebRtcOffer-pk-tencent_css_pk');
- updateWebRtcMeetingPkConfig({
- roomId: roomId.value,
- anchorStream: canvasVideoStream.value,
- // userStream: userStream.value,
- });
- webRtcMeetingPk.newWebRtc({
- // 因为这里是收到offer,而offer是房主发的,所以此时的data.data.sender是房主;data.data.receiver是接收者;
- // 但是这里的nativeWebRtc的sender,得是自己,不能是data.data.sender,不要混淆
- sender: mySocketId.value,
- receiver: data.sender,
- videoEl: createNullVideo(),
- });
- webRtcMeetingPk.addTrack({
- stream: userStream.value,
- receiver: data.sender,
- });
- await webRtcMeetingPk.sendAnswer({
- sender: mySocketId.value,
- // data.data.receiver是接收者;我们现在new pc,发送者是自己,接收者肯定是房主,不能是data.data.receiver,因为data.data.receiver是自己
- receiver: data.sender,
- sdp: data.sdp,
- });
- } else {
- console.error('不是发给我的nativeWebRtcOffer');
- }
- } else 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;
- }
- updateWebRtcLiveConfig({
- roomId: roomId.value,
- canvasVideoStream: canvasVideoStream.value,
- });
- webRtcLive.newWebRtc({
- // 因为这里是收到offer,而offer是房主发的,所以此时的data.data.sender是房主;data.data.receiver是接收者;
- // 但是这里的nativeWebRtc的sender,得是自己,不能是data.data.sender,不要混淆
- sender: mySocketId.value,
- receiver: data.sender,
- videoEl: createNullVideo(),
- });
- await webRtcLive.sendAnswer({
- sender: mySocketId.value,
- // data.data.receiver是接收者;我们现在new pc,发送者是自己,接收者肯定是房主,不能是data.data.receiver,因为data.data.receiver是自己
- receiver: data.sender,
- sdp: data.sdp,
- });
- } 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,
- // userStream: userStream.value,
- anchorStream: canvasVideoStream.value,
- });
- if (networkStore.rtcMap.get(data.sender)) {
- return;
- }
- webRtcMeetingOne.newWebRtc({
- // 因为这里是收到offer,而offer是房主发的,所以此时的data.data.sender是房主;data.data.receiver是接收者;
- // 但是这里的nativeWebRtc的sender,得是自己,不能是data.data.sender,不要混淆
- sender: mySocketId.value,
- receiver: data.sender,
- videoEl: createNullVideo(),
- });
- 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,
- });
- } else {
- console.error('不是发给我的nativeWebRtcOffer');
- }
- }
- }
- );
- // 收到nativeWebRtcAnswer
- ws.socketIo.on(
- WsMsgTypeEnum.nativeWebRtcAnswer,
- async (data: WsAnswerType['data']) => {
- console.log('收到nativeWebRtcAnswer', data);
- if (data.receiver === mySocketId.value) {
- console.warn('是发给我的nativeWebRtcAnswer');
- const rtc = networkStore.rtcMap.get(data.sender);
- if (rtc) {
- await rtc.setRemoteDescription(data.sdp);
- }
- } else {
- console.error('不是发给我的nativeWebRtcAnswer');
- }
- }
- );
- // 收到nativeWebRtcCandidate
- ws.socketIo.on(
- WsMsgTypeEnum.nativeWebRtcCandidate,
- (data: WsCandidateType['data']) => {
- console.log('收到nativeWebRtcCandidate', data);
- if (data.receiver === mySocketId.value) {
- console.warn('是发给我的nativeWebRtcCandidate');
- const rtc = networkStore.rtcMap.get(data.sender);
- rtc?.addIceCandidate(data.candidate);
- } else {
- console.error('不是发给我的nativeWebRtcCandidate');
- }
- }
- );
- // 收到remoteDeskBehavior
- ws.socketIo.on(
- WsMsgTypeEnum.remoteDeskBehavior,
- (data: WsRemoteDeskBehaviorType['data']) => {
- console.log('收到remoteDeskBehavior', data);
- }
- );
- // 主播正在直播
- ws.socketIo.on(
- WsMsgTypeEnum.roomLiving,
- async (data: WsRoomLivingType['data']) => {
- prettierReceiveWsMsg(WsMsgTypeEnum.roomLiving, data);
- roomLiving.value = true;
- if (data.anchor_socket_id) {
- anchorSocketId.value = data.anchor_socket_id;
- }
- if (
- route.name === routerName.pull ||
- route.name === routerName.h5Room
- ) {
- // 当前是拉流页面
- if (data.live_room?.type === LiveRoomTypeEnum.wertc_meeting_one) {
- await handleMeeting();
- } else if (data.live_room?.type === LiveRoomTypeEnum.pk) {
- await handlePk();
- }
- } else if (route.name === routerName.push) {
- // 当前是推流页面
- }
- }
- );
- // 主播不在直播
- ws.socketIo.on(WsMsgTypeEnum.roomNoLive, (data) => {
- prettierReceiveWsMsg(WsMsgTypeEnum.roomNoLive, data);
- roomLiving.value = false;
- });
- // 当前所有在线用户
- ws.socketIo.on(
- WsMsgTypeEnum.liveUser,
- (data: WSGetRoomAllUserType['data']) => {
- prettierReceiveWsMsg(WsMsgTypeEnum.liveUser, data);
- liveUserList.value = data.liveUser;
- }
- );
- // 收到用户发送消息
- ws.socketIo.on(WsMsgTypeEnum.message, (data: WsMessageType) => {
- prettierReceiveWsMsg(WsMsgTypeEnum.message, data);
- damuList.value.push(data);
- });
- // 收到disableSpeaking
- ws.socketIo.on(
- WsMsgTypeEnum.disableSpeaking,
- (data: WsDisableSpeakingType['data']) => {
- prettierReceiveWsMsg(WsMsgTypeEnum.disableSpeaking, data);
- // if (data.is_disable_speaking) {
- // window.$message.error('你已被禁言!');
- // appStore.disableSpeaking.set(data.live_room_id, {
- // exp: data.disable_expired_at,
- // label: formatDownTime({
- // startTime: +new Date(),
- // endTime: data.disable_expired_at,
- // }),
- // });
- // clearTimeout(timerObj.value[data.live_room_id]);
- // timerObj.value[data.live_room_id] = setInterval(() => {
- // if (
- // data.disable_expired_at &&
- // +new Date() > data.disable_expired_at
- // ) {
- // clearTimeout(timerObj.value[data.live_room_id]);
- // }
- // appStore.disableSpeaking.set(data.live_room_id, {
- // exp: data.disable_expired_at!,
- // label: formatDownTime({
- // startTime: +new Date(),
- // endTime: data.disable_expired_at!,
- // }),
- // });
- // }, 1000);
- // damuList.value = damuList.value.filter(
- // (v) => v.request_id !== data.request_id
- // );
- // }
- if (data.user_id !== userStore.userInfo?.id && data.disable_ok) {
- window.$message.success('禁言成功!');
- }
- if (
- data.user_id !== userStore.userInfo?.id &&
- data.restore_disable_ok
- ) {
- window.$message.success('解除禁言成功!');
- }
- if (
- data.user_id === userStore.userInfo?.id &&
- data.restore_disable_ok
- ) {
- window.$message.success('禁言接触了!');
- clearTimeout(timerObj.value[data.live_room_id]);
- appStore.disableSpeaking.delete(data.live_room_id);
- }
- }
- );
- 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,
- },
- });
- }
- async function handlePk() {
- if (!route.query.pkKey) {
- return;
- }
- const res = await fetchVerifyPkKey({
- liveRoomId: Number(roomId.value),
- key: route.query.pkKey,
- });
- if (res.code === 200 && res.data === true) {
- await useTip({
- content: '是否加入PK?',
- });
- 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,
- },
- });
- } else {
- await useTip({
- content: '加入PK失败,验证pkKey错误!',
- hiddenCancel: true,
- hiddenClose: true,
- });
- }
- }
- // 用户加入房间完成
- ws.socketIo.on(WsMsgTypeEnum.joined, async (data: WsJoinType['data']) => {
- prettierReceiveWsMsg(WsMsgTypeEnum.joined, data);
- appStore.setLiveRoomInfo(data.live_room);
- anchorInfo.value = data.anchor_info;
- if (route.name === routerName.pull || route.name === routerName.h5Room) {
- // 当前是拉流页面
- if (
- roomLiving.value &&
- data.live_room?.type === LiveRoomTypeEnum.wertc_meeting_one
- ) {
- await handleMeeting();
- } else if (
- roomLiving.value &&
- data.live_room?.type === LiveRoomTypeEnum.pk
- ) {
- await handlePk();
- }
- }
- });
- // batchSendOffer
- ws.socketIo.on(
- WsMsgTypeEnum.batchSendOffer,
- (data: WsBatchSendOffer['data']) => {
- if (
- appStore.liveRoomInfo?.type === LiveRoomTypeEnum.wertc_meeting_one
- ) {
- data.socket_list?.forEach((item) => {
- if (item !== mySocketId.value) {
- if (networkStore.rtcMap.get(item)) {
- return;
- }
- webRtcMeetingOne.newWebRtc({
- sender: mySocketId.value,
- receiver: item,
- videoEl: createNullVideo(),
- });
- webRtcMeetingOne.sendOffer({
- sender: mySocketId.value,
- receiver: item,
- });
- }
- });
- } else if (appStore.liveRoomInfo?.type === LiveRoomTypeEnum.pk) {
- data.socket_list?.forEach((item) => {
- if (item !== mySocketId.value) {
- if (networkStore.rtcMap.get(item)) {
- return;
- }
- webRtcMeetingPk.newWebRtc({
- sender: mySocketId.value,
- receiver: item,
- videoEl: createNullVideo(),
- });
- webRtcMeetingPk.sendOffer({
- sender: mySocketId.value,
- receiver: item,
- });
- }
- });
- }
- }
- );
- // 其他用户加入房间
- ws.socketIo.on(WsMsgTypeEnum.otherJoin, (data: WsOtherJoinType['data']) => {
- prettierReceiveWsMsg(WsMsgTypeEnum.otherJoin, data);
- const danmu: WsMessageType = {
- request_id: '',
- socket_id: '',
- time: +new Date(),
- user_agent: navigator.userAgent,
- data: {
- live_room_id: data.live_room.id!,
- msg_id: -1,
- content: '',
- content_type: WsMessageContentTypeEnum.txt,
- msg_type: DanmuMsgTypeEnum.otherJoin,
- },
- };
- damuList.value.push(danmu);
- if (route.name === routerName.push) {
- // 当前是推流页面
- if (!isAnchor.value) {
- console.error('不是主播');
- return;
- }
- if (!roomLiving.value) {
- console.error('主播没点开始直播');
- return;
- }
- if (userStore.userInfo?.id === data.join_user_info?.id) {
- console.error('自己进入直播间,退出');
- return;
- }
- if (
- [
- LiveRoomTypeEnum.system,
- LiveRoomTypeEnum.srs,
- LiveRoomTypeEnum.obs,
- ].includes(data.live_room.type!)
- ) {
- return;
- }
- if (data.live_room.type === LiveRoomTypeEnum.wertc_live) {
- updateWebRtcLiveConfig({
- roomId: roomId.value,
- canvasVideoStream: canvasVideoStream.value,
- });
- data.socket_list.forEach((item) => {
- if (item !== mySocketId.value) {
- if (networkStore.rtcMap.get(item)) {
- return;
- }
- webRtcLive.newWebRtc({
- sender: mySocketId.value,
- receiver: item,
- videoEl: createNullVideo(),
- });
- webRtcLive.sendOffer({
- sender: mySocketId.value,
- receiver: item,
- });
- }
- });
- } else if (data.live_room.type === LiveRoomTypeEnum.wertc_meeting_one) {
- updateWebRtcMeetingOneConfig({
- roomId: roomId.value,
- anchorStream: canvasVideoStream.value,
- });
- // data.socket_list?.forEach((item) => {
- // if (item !== mySocketId.value) {
- // if (networkStore.rtcMap.get(item)) {
- // return;
- // }
- // webRtcMeetingOne.newWebRtc({
- // sender: mySocketId.value,
- // receiver: item,
- // videoEl: createNullVideo(),
- // });
- // webRtcMeetingOne.sendOffer({
- // sender: mySocketId.value,
- // receiver: item,
- // });
- // }
- // });
- } else if (data.live_room.type === LiveRoomTypeEnum.pk) {
- updateWebRtcMeetingPkConfig({
- roomId: roomId.value,
- anchorStream: canvasVideoStream.value,
- });
- // data.socket_list?.forEach((item) => {
- // if (item !== mySocketId.value) {
- // if (networkStore.rtcMap.get(item)) {
- // return;
- // }
- // webRtcMeetingPk.newWebRtc({
- // sender: mySocketId.value,
- // receiver: item,
- // videoEl: createNullVideo(),
- // });
- // webRtcMeetingPk.sendOffer({
- // sender: mySocketId.value,
- // receiver: item,
- // });
- // }
- // });
- } else if (data.live_room.type === LiveRoomTypeEnum.tencent_css_pk) {
- updateWebRtcMeetingPkConfig({
- roomId: roomId.value,
- anchorStream: canvasVideoStream.value,
- });
- data.socket_list?.forEach((item) => {
- if (item !== mySocketId.value) {
- if (networkStore.rtcMap.get(item)) {
- return;
- }
- webRtcMeetingPk.newWebRtc({
- sender: mySocketId.value,
- receiver: item,
- videoEl: createNullVideo(),
- });
- webRtcMeetingPk.sendOffer({
- sender: mySocketId.value,
- receiver: item,
- });
- }
- });
- }
- } else {
- // 当前不是推流页面
- }
- });
- // 用户离开房间
- ws.socketIo.on(WsMsgTypeEnum.leave, (data) => {
- prettierReceiveWsMsg(WsMsgTypeEnum.leave, data);
- });
- // 用户离开房间完成
- ws.socketIo.on(WsMsgTypeEnum.leaved, (data: WsLeavedType['data']) => {
- prettierReceiveWsMsg(WsMsgTypeEnum.leaved, data);
- if (anchorSocketId.value === data.socket_id) {
- roomLiving.value = false;
- }
- networkStore.removeRtc(data.socket_id);
- damuList.value.push({
- request_id: '',
- socket_id: '',
- time: +new Date(),
- user_agent: navigator.userAgent,
- data: {
- live_room_id: Number(roomId.value),
- msg_id: -1,
- content: '',
- content_type: WsMessageContentTypeEnum.txt,
- msg_type: DanmuMsgTypeEnum.userLeaved,
- },
- });
- });
- }
- function initWs(data: {
- isAnchor: boolean;
- roomId: string;
- isBilibili?: boolean;
- isRemoteDesk?: boolean;
- currentResolutionRatio?: number;
- currentMaxFramerate?: number;
- currentMaxBitrate?: number;
- }) {
- roomId.value = data.roomId;
- isAnchor.value = data.isAnchor;
- if (data.isRemoteDesk !== undefined) {
- isRemoteDesk.value = data.isRemoteDesk;
- }
- if (data.isBilibili !== undefined) {
- isBilibili.value = data.isBilibili;
- }
- if (data.currentMaxBitrate !== undefined) {
- currentMaxBitrate.value = data.currentMaxBitrate;
- }
- if (data.currentMaxFramerate !== undefined) {
- currentMaxFramerate.value = data.currentMaxFramerate;
- }
- if (data.currentResolutionRatio !== undefined) {
- currentResolutionRatio.value = data.currentResolutionRatio;
- }
- new WebSocketClass({
- roomId: roomId.value,
- url: WEBSOCKET_URL,
- isAnchor: data.isAnchor,
- });
- initReceive();
- }
- return {
- initWs,
- handleStartLive,
- isBilibili,
- connectStatus,
- mySocketId,
- canvasVideoStream,
- lastCoverImg,
- roomLiving,
- anchorInfo,
- liveUserList,
- damuList,
- currentMaxFramerate,
- currentMaxBitrate,
- currentResolutionRatio,
- currentAudioContentHint,
- currentVideoContentHint,
- };
- };
|