| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002 |
- 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,
- WsMessageMsgIsFileEnum,
- } 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 {
- IDanmu,
- 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 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<IDanmu[]>([]);
- 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(socketId: string) {
- loopHeartbeatTimer.value = setInterval(() => {
- const ws = networkStore.wsMap.get(roomId.value);
- if (!ws) return;
- ws.send<WsHeartbeatType['data']>({
- requestId: getRandomString(8),
- msgType: WsMsgTypeEnum.heartbeat,
- data: {
- socket_id: socketId,
- 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: {
- 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(ws.socketIo!.id!);
- 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({
- user_agent: data.data.user_agent,
- live_room_id: data.data.live_room_id,
- request_id: data.request_id,
- socket_id: data.socket_id,
- msgType: data.data.msgType,
- msg: data.data.msg,
- userInfo: data.user_info,
- msgIsFile: data.data.msgIsFile,
- send_msg_time: data.data.send_msg_time,
- });
- });
- // 收到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,
- });
- console.log(stream?.getAudioTracks());
- console.log(stream?.getVideoTracks(), 1111);
- 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 requestId = getRandomString(8);
- const danmu: IDanmu = {
- live_room_id: data.live_room.id!,
- request_id: requestId,
- msgType: DanmuMsgTypeEnum.otherJoin,
- socket_id: data.join_socket_id,
- userInfo: data.join_user_info,
- msgIsFile: WsMessageMsgIsFileEnum.no,
- msg: '',
- send_msg_time: +new Date(),
- };
- 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({
- live_room_id: Number(roomId.value),
- socket_id: data.socket_id,
- msgType: DanmuMsgTypeEnum.userLeaved,
- msgIsFile: WsMessageMsgIsFileEnum.no,
- userInfo: data.user_info,
- msg: '',
- send_msg_time: +new Date(),
- });
- });
- }
- function initWs(data: {
- isAnchor: boolean;
- roomId: string;
- isRemoteDesk?: boolean;
- currentResolutionRatio?: number;
- currentMaxFramerate?: number;
- currentMaxBitrate?: number;
- }) {
- roomId.value = data.roomId;
- isAnchor.value = data.isAnchor;
- if (data.isRemoteDesk) {
- isRemoteDesk.value = data.isRemoteDesk;
- }
- if (data.currentMaxBitrate) {
- currentMaxBitrate.value = data.currentMaxBitrate;
- }
- if (data.currentMaxFramerate) {
- currentMaxFramerate.value = data.currentMaxFramerate;
- }
- if (data.currentResolutionRatio) {
- currentResolutionRatio.value = data.currentResolutionRatio;
- }
- new WebSocketClass({
- roomId: roomId.value,
- url: WEBSOCKET_URL,
- isAnchor: data.isAnchor,
- });
- initReceive();
- }
- return {
- initWs,
- handleStartLive,
- connectStatus,
- mySocketId,
- canvasVideoStream,
- lastCoverImg,
- roomLiving,
- anchorInfo,
- liveUserList,
- damuList,
- currentMaxFramerate,
- currentMaxBitrate,
- currentResolutionRatio,
- currentAudioContentHint,
- currentVideoContentHint,
- };
- };
|