| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913 |
- import { copyToClipBoard, getRandomString } from 'billd-utils';
- import { NButton, useDialog } from 'naive-ui';
- import { computed, h, onUnmounted, ref, watch } from 'vue';
- import { useRoute } from 'vue-router';
- import { fetchVerifyPkKey } from '@/api/liveRoom';
- import { fetchRtcV1Publish } from '@/api/srs';
- import { SRS_CB_URL_PARAMS, THEME_COLOR, WEBSOCKET_URL } from '@/constant';
- import {
- DanmuMsgTypeEnum,
- ILiveUser,
- WsMessageMsgIsFileEnum,
- } from '@/interface';
- import { WebRTCClass } from '@/network/webRTC';
- import { WebSocketClass, prettierReceiveWsMsg } from '@/network/webSocket';
- 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,
- WsCandidateType,
- WsConnectStatusEnum,
- WsDisableSpeakingType,
- WsGetLiveUserType,
- WsHeartbeatType,
- WsJoinType,
- WsLeavedType,
- WsMessageType,
- WsMsgTypeEnum,
- WsOfferType,
- WsOtherJoinType,
- WsRoomLivingType,
- WsStartLiveType,
- WsUpdateJoinInfoType,
- } from '@/types/websocket';
- import { createVideo } from '@/utils';
- import { useRTCParams } from './use-rtcParams';
- import { useTip } from './use-tip';
- export const useWebsocket = () => {
- const route = useRoute();
- const appStore = useAppStore();
- const userStore = useUserStore();
- const networkStore = useNetworkStore();
- const dialog = useDialog();
- const { maxBitrate, maxFramerate, resolutionRatio } = useRTCParams();
- const connectStatus = ref();
- const loopHeartbeatTimer = ref();
- const loopGetLiveUserTimer = ref();
- const liveUserList = ref<ILiveUser[]>([]);
- const roomId = ref('');
- const isPull = ref(false);
- const roomLiving = ref(false);
- const isAnchor = ref(false);
- const isSRS = ref(false);
- const anchorInfo = ref<IUser>();
- const anchorSocketId = ref('');
- const canvasVideoStream = 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 timerObj = ref({});
- const damuList = ref<IDanmu[]>([]);
- onUnmounted(() => {
- clearInterval(loopHeartbeatTimer.value);
- clearInterval(loopGetLiveUserTimer.value);
- });
- watch(
- () => appStore.pkStream,
- (newval) => {
- if (newval && isAnchor.value) {
- console.log('转推到srs', newval);
- srsWebRtc.sendOffer({
- isPk: true,
- sender: mySocketId.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),
- },
- });
- }, 1000 * 5);
- }
- function handleSendGetLiveUser(liveRoomId: number) {
- loopGetLiveUserTimer.value = setInterval(() => {
- const ws = networkStore.wsMap.get(roomId.value);
- if (!ws) return;
- ws.send<WsGetLiveUserType['data']>({
- requestId: getRandomString(8),
- msgType: WsMsgTypeEnum.getLiveUser,
- data: {
- live_room_id: liveRoomId,
- },
- });
- }, 1000 * 5);
- }
- function handleStartLive({
- coverImg,
- name,
- type,
- msrDelay,
- msrMaxDelay,
- }: {
- coverImg?: string;
- name?: string;
- type: LiveRoomTypeEnum;
- videoEl?: HTMLVideoElement;
- msrDelay: number;
- msrMaxDelay: number;
- }) {
- networkStore.wsMap.get(roomId.value)?.send<WsStartLiveType['data']>({
- requestId: getRandomString(8),
- msgType: WsMsgTypeEnum.startLive,
- data: {
- cover_img: coverImg!,
- name: name!,
- type,
- msrDelay,
- msrMaxDelay,
- },
- });
- // if (type === LiveRoomTypeEnum.user_msr) {
- // return;
- // }
- // if ([LiveRoomTypeEnum.user_srs, LiveRoomTypeEnum.user_obs].includes(type)) {
- // isSRS.value = true;
- // srsWebRtc.sendOffer({
- // isPk: false,
- // sender: mySocketId.value,
- // });
- // } else {
- // isSRS.value = false;
- // }
- }
- function sendJoin() {
- const instance = networkStore.wsMap.get(roomId.value);
- if (!instance) return;
- instance.send<WsJoinType['data']>({
- requestId: getRandomString(8),
- msgType: WsMsgTypeEnum.join,
- data: {
- socket_id: mySocketId.value,
- live_room_id: Number(roomId.value),
- user_info: userStore.userInfo,
- },
- });
- }
- async function handleUserMedia({ video, audio }) {
- try {
- const event = await navigator.mediaDevices.getUserMedia({
- video,
- audio,
- });
- return event;
- } catch (error) {
- console.log(error);
- }
- }
- const nativeWebRtc = {
- newWebrtc: ({
- isAnchor,
- sender,
- receiver,
- videoEl,
- }: {
- isAnchor: boolean;
- sender: string;
- receiver: string;
- videoEl: HTMLVideoElement;
- }) => {
- return new WebRTCClass({
- maxBitrate: currentMaxBitrate.value,
- maxFramerate: currentMaxFramerate.value,
- resolutionRatio: currentResolutionRatio.value,
- isSRS: false,
- roomId: roomId.value,
- isAnchor,
- videoEl,
- sender,
- receiver,
- localStream: canvasVideoStream.value,
- });
- },
- /**
- * 原生webrtc视频通话
- * 视频发起方是房主,房主发offer给用户
- */
- sendOffer: async ({
- sender,
- receiver,
- }: {
- sender: string;
- receiver: string;
- }) => {
- console.log('开始nativeWebRtc的sendOffer', { sender, receiver });
- try {
- const ws = networkStore.wsMap.get(roomId.value);
- if (!ws) return;
- if (networkStore.rtcMap.get(receiver)) {
- return;
- }
- const rtc = nativeWebRtc.newWebrtc({
- isAnchor: true,
- sender,
- receiver,
- videoEl: createVideo({
- appendChild: true,
- }),
- });
- canvasVideoStream.value?.getTracks().forEach((track) => {
- if (rtc && canvasVideoStream.value) {
- console.log(
- 'nativeWebRtc的canvasVideoStream插入track',
- track.kind,
- track
- );
- rtc.peerConnection?.addTrack(track, canvasVideoStream.value);
- }
- });
- const offerSdp = await rtc.createOffer();
- if (!offerSdp) {
- console.error('nativeWebRtc的offerSdp为空');
- return;
- }
- await rtc.setLocalDescription(offerSdp!);
- networkStore.wsMap.get(roomId.value)?.send<WsOfferType['data']>({
- requestId: getRandomString(8),
- msgType: WsMsgTypeEnum.nativeWebRtcOffer,
- data: {
- live_room: appStore.liveRoomInfo!,
- live_room_id: Number(roomId.value),
- sender,
- receiver,
- sdp: offerSdp,
- },
- });
- } catch (error) {
- console.error('nativeWebRtc的sendOffer错误');
- }
- },
- /**
- * 原生webrtc视频通话
- * 用户收到房主的offer,用户回复房主answer
- */
- sendAnswer: async ({
- isPk,
- sdp,
- sender,
- receiver,
- }: {
- isPk: boolean;
- sdp: RTCSessionDescriptionInit;
- sender: string;
- receiver: string;
- }) => {
- console.log('开始nativeWebRtc的sendAnswer', { sender, receiver, sdp });
- try {
- const ws = networkStore.wsMap.get(roomId.value);
- if (!ws) return;
- const rtc = networkStore.rtcMap.get(receiver);
- if (rtc) {
- await rtc.setRemoteDescription(sdp);
- if (isPk) {
- if (!isAnchor.value) {
- const stream = await handleUserMedia({
- video: true,
- audio: true,
- });
- if (rtc?.peerConnection) {
- rtc.peerConnection.onnegotiationneeded = (event) => {
- console.log('onnegotiationneeded', event);
- };
- stream?.getTracks().forEach((track) => {
- rtc.peerConnection?.addTrack(track, stream);
- });
- }
- }
- }
- const answerSdp = await rtc.createAnswer();
- if (!answerSdp) {
- console.error('nativeWebRtc的answerSdp为空');
- return;
- }
- await rtc.setLocalDescription(answerSdp);
- networkStore.wsMap.get(roomId.value)?.send<WsAnswerType['data']>({
- requestId: getRandomString(8),
- msgType: WsMsgTypeEnum.nativeWebRtcAnswer,
- data: {
- live_room_id: Number(roomId.value),
- sender,
- receiver,
- sdp: answerSdp,
- },
- });
- } else {
- console.error('rtc不存在');
- }
- } catch (error) {
- console.error('nativeWebRtc的sendAnswer错误');
- }
- },
- };
- const srsWebRtc = {
- newWebrtc: ({
- roomId,
- sender,
- videoEl,
- }: {
- roomId: string;
- sender: string;
- videoEl: HTMLVideoElement;
- }) => {
- return new WebRTCClass({
- isAnchor: true,
- maxBitrate: currentMaxBitrate.value,
- maxFramerate: currentMaxFramerate.value,
- resolutionRatio: currentResolutionRatio.value,
- roomId,
- videoEl,
- isSRS: true,
- sender,
- receiver: 'srs',
- localStream: canvasVideoStream.value,
- });
- },
- /**
- * srs的webrtc推流视频通话
- * 视频发起方是房主,房主发offer给srs
- */
- sendOffer: async ({ isPk, sender }: { isPk: boolean; sender: string }) => {
- console.log('开始srsWebRtc的sendOffer', { sender });
- try {
- const ws = networkStore.wsMap.get(roomId.value);
- if (!ws) return;
- const rtc = srsWebRtc.newWebrtc({
- roomId: `${isPk ? `${roomId.value}___pk` : `${roomId.value}`}`,
- sender,
- videoEl: createVideo({ appendChild: true }),
- });
- canvasVideoStream.value?.getTracks().forEach((track) => {
- if (rtc && canvasVideoStream.value) {
- console.log(
- 'srsWebRtc的canvasVideoStream插入track',
- track.kind,
- track
- );
- rtc.peerConnection?.addTrack(track, canvasVideoStream.value);
- }
- });
- const offerSdp = await rtc.createOffer();
- if (!offerSdp) {
- console.error('srsWebRtc的offerSdp为空');
- return;
- }
- await rtc.setLocalDescription(offerSdp!);
- const myLiveRoom = userStore.userInfo!.live_rooms![0];
- const answerRes = await fetchRtcV1Publish({
- api: `/rtc/v1/publish/`,
- clientip: null,
- sdp: offerSdp!.sdp!,
- streamurl: `${myLiveRoom.rtmp_url!}?${
- SRS_CB_URL_PARAMS.publishKey
- }=${myLiveRoom.key!}&${SRS_CB_URL_PARAMS.publishType}=${
- isPk ? LiveRoomTypeEnum.user_pk : LiveRoomTypeEnum.user_srs
- }`,
- tid: getRandomString(10),
- });
- if (answerRes.data.code !== 0) {
- console.error('/rtc/v1/publish/拿不到sdp');
- window.$message.error('/rtc/v1/publish/拿不到sdp');
- return;
- }
- await rtc.setRemoteDescription(
- new RTCSessionDescription({ type: 'answer', sdp: answerRes.data.sdp })
- );
- } catch (error) {
- console.error('srsWebRtc的sendOffer错误');
- }
- },
- };
- 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(() => {});
- });
- // 收到srsOffer
- ws.socketIo.on(
- WsMsgTypeEnum.srsOffer,
- async (data: WsOfferType['data']) => {
- console.log('收到srsOffer', data);
- if (data.receiver === mySocketId.value) {
- console.warn('是发给我的srsOffer');
- const videoEl = createVideo({ appendChild: true });
- const rtc = new WebRTCClass({
- isAnchor: true,
- maxBitrate: currentMaxBitrate.value,
- maxFramerate: currentMaxFramerate.value,
- resolutionRatio: currentResolutionRatio.value,
- roomId: roomId.value,
- videoEl,
- isSRS: true,
- sender: data.sender,
- receiver: data.receiver,
- });
- isSRS.value = true;
- await rtc.setRemoteDescription(data.sdp);
- const answerSdp = await rtc.createAnswer();
- if (answerSdp) {
- await rtc.setLocalDescription(answerSdp);
- ws.send<WsAnswerType['data']>({
- requestId: getRandomString(8),
- msgType: WsMsgTypeEnum.srsAnswer,
- data: {
- live_room_id: Number(roomId.value),
- sdp: answerSdp,
- receiver: data.sender,
- sender: mySocketId.value,
- },
- });
- } else {
- console.error('srsOffer的answerSdp为空');
- }
- } else {
- console.error('不是发给我的srsOffer');
- }
- }
- );
- // 收到srsAnswer
- ws.socketIo.on(WsMsgTypeEnum.srsAnswer, (data: WsAnswerType['data']) => {
- console.log('收到srsAnswer', data);
- if (data.receiver === mySocketId.value) {
- console.warn('是发给我的srsAnswer');
- const rtc = networkStore.getRtcMap(data.sender);
- rtc?.setRemoteDescription(data.sdp);
- } else {
- console.error('不是发给我的srsAnswer');
- }
- });
- // 收到srsCandidate
- ws.socketIo.on(
- WsMsgTypeEnum.srsCandidate,
- (data: WsCandidateType['data']) => {
- console.log('收到srsCandidate', data);
- if (data.receiver === mySocketId.value) {
- console.warn('是发给我的srsCandidate');
- const rtc = networkStore.getRtcMap(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.live_room.type === LiveRoomTypeEnum.user_pk) {
- if (!isAnchor.value) {
- const res = await fetchVerifyPkKey({
- liveRoomId: Number(roomId.value),
- key: route.query.pkKey,
- });
- if (res.code === 200 && res.data === true) {
- dialog.warning({
- title: '提示',
- content: '是否加入PK',
- positiveText: '确认',
- onPositiveClick() {
- async function main() {
- if (data.receiver === mySocketId.value) {
- console.warn('是发给我的nativeWebRtcOffer');
- await nativeWebRtc.newWebrtc({
- isAnchor: true,
- // 因为这里是收到offer,而offer是房主发的,所以此时的data.data.sender是房主;data.data.receiver是接收者;
- // 但是这里的nativeWebRtc的sender,得是自己,不能是data.data.sender,不要混淆
- sender: mySocketId.value,
- receiver: data.sender,
- videoEl: createVideo({
- appendChild: true,
- }),
- });
- nativeWebRtc.sendAnswer({
- isPk: true,
- sender: mySocketId.value,
- // data.data.receiver是接收者;我们现在new pc,发送者是自己,接收者肯定是房主,不能是data.data.receiver,因为data.data.receiver是自己
- receiver: data.sender,
- sdp: data.sdp,
- });
- } else {
- console.error('不是发给我的nativeWebRtcOffer');
- }
- }
- return main();
- },
- });
- } else {
- window.$message.error('验证pkKey错误!');
- }
- } else {
- if (data.receiver === mySocketId.value) {
- console.warn('是发给我的nativeWebRtcOffer');
- await nativeWebRtc.newWebrtc({
- isAnchor: true,
- // 因为这里是收到offer,而offer是房主发的,所以此时的data.data.sender是房主;data.data.receiver是接收者;
- // 但是这里的nativeWebRtc的sender,得是自己,不能是data.data.sender,不要混淆
- sender: mySocketId.value,
- receiver: data.sender,
- videoEl: createVideo({
- appendChild: true,
- }),
- });
- nativeWebRtc.sendAnswer({
- isPk: true,
- 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.receiver === mySocketId.value) {
- console.warn('是发给我的nativeWebRtcOffer');
- await nativeWebRtc.newWebrtc({
- isAnchor: true,
- // 因为这里是收到offer,而offer是房主发的,所以此时的data.data.sender是房主;data.data.receiver是接收者;
- // 但是这里的nativeWebRtc的sender,得是自己,不能是data.data.sender,不要混淆
- sender: mySocketId.value,
- receiver: data.sender,
- videoEl: createVideo({
- appendChild: true,
- }),
- });
- await nativeWebRtc.sendAnswer({
- isPk: false,
- sender: mySocketId.value,
- // data.data.receiver是接收者;我们现在new pc,发送者是自己,接收者肯定是房主,不能是data.data.receiver,因为data.data.receiver是自己
- receiver: data.sender,
- sdp: data.sdp,
- });
- } else {
- console.error('不是发给我的nativeWebRtcOffer');
- }
- }
- return '1';
- }
- );
- // 收到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.getRtcMap(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.getRtcMap(data.sender);
- rtc?.addIceCandidate(data.candidate);
- } else {
- console.error('不是发给我的nativeWebRtcCandidate');
- }
- }
- );
- // 主播正在直播
- ws.socketIo.on(
- WsMsgTypeEnum.roomLiving,
- (data: WsRoomLivingType['data']) => {
- prettierReceiveWsMsg(WsMsgTypeEnum.roomLiving, data);
- roomLiving.value = true;
- if (data.anchor_socket_id) {
- anchorSocketId.value = data.anchor_socket_id;
- }
- isSRS.value = true;
- if (
- data.live_room.type &&
- [LiveRoomTypeEnum.user_wertc, LiveRoomTypeEnum.user_pk].includes(
- data.live_room.type
- )
- ) {
- isSRS.value = false;
- }
- }
- );
- // 主播不在直播
- 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);
- }
- }
- );
- // 用户加入房间完成
- ws.socketIo.on(WsMsgTypeEnum.joined, (data: WsJoinType['data']) => {
- prettierReceiveWsMsg(WsMsgTypeEnum.joined, data);
- appStore.setLiveRoomInfo(data.live_room);
- anchorInfo.value = data.anchor_info;
- });
- // 其他用户加入房间
- 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 (data.live_room.type === LiveRoomTypeEnum.user_wertc) {
- isSRS.value = false;
- nativeWebRtc.sendOffer({
- sender: mySocketId.value,
- receiver: data.join_socket_id,
- });
- } else {
- data.socket_list.forEach((item) => {
- if (item !== mySocketId.value) {
- if (
- [
- LiveRoomTypeEnum.user_wertc,
- LiveRoomTypeEnum.user_wertc_meeting,
- LiveRoomTypeEnum.user_pk,
- ].includes(data.live_room.type!)
- ) {
- isSRS.value = false;
- nativeWebRtc.sendOffer({
- sender: mySocketId.value,
- receiver: item,
- });
- }
- }
- });
- }
- });
- // 用户离开房间
- 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(`${roomId.value}`);
- 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 initSrsWs(data: {
- isAnchor: boolean;
- roomId: string;
- currentResolutionRatio?: number;
- currentMaxFramerate?: number;
- currentMaxBitrate?: number;
- }) {
- roomId.value = data.roomId;
- isAnchor.value = data.isAnchor;
- 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 {
- isPull,
- initSrsWs,
- handleStartLive,
- handleSendGetLiveUser,
- mySocketId,
- canvasVideoStream,
- lastCoverImg,
- roomLiving,
- anchorInfo,
- liveUserList,
- damuList,
- currentMaxFramerate,
- currentMaxBitrate,
- currentResolutionRatio,
- };
- };
|