|
@@ -1,936 +0,0 @@
|
|
|
-import { getRandomString } from 'billd-utils';
|
|
|
|
|
-import { onUnmounted, reactive, ref, watch } from 'vue';
|
|
|
|
|
-
|
|
|
|
|
-import { fetchRtcV1Play, fetchRtcV1Publish } from '@/api/srs';
|
|
|
|
|
-import { WEBSOCKET_URL } from '@/constant';
|
|
|
|
|
-import {
|
|
|
|
|
- DanmuMsgTypeEnum,
|
|
|
|
|
- IDanmu,
|
|
|
|
|
- ILiveRoom,
|
|
|
|
|
- ILiveUser,
|
|
|
|
|
- IUser,
|
|
|
|
|
- LiveRoomTypeEnum,
|
|
|
|
|
- liveTypeEnum,
|
|
|
|
|
-} from '@/interface';
|
|
|
|
|
-import {
|
|
|
|
|
- WSGetRoomAllUserType,
|
|
|
|
|
- WsAnswerType,
|
|
|
|
|
- WsCandidateType,
|
|
|
|
|
- WsGetLiveUserType,
|
|
|
|
|
- WsHeartbeatType,
|
|
|
|
|
- WsJoinType,
|
|
|
|
|
- WsLeavedType,
|
|
|
|
|
- WsMessageType,
|
|
|
|
|
- WsOfferType,
|
|
|
|
|
- WsOtherJoinType,
|
|
|
|
|
- WsRoomLivingType,
|
|
|
|
|
- WsStartLiveType,
|
|
|
|
|
- WsUpdateJoinInfoType,
|
|
|
|
|
-} from '@/interface-ws';
|
|
|
|
|
-import { WebRTCClass } from '@/network/webRTC';
|
|
|
|
|
-import {
|
|
|
|
|
- WebSocketClass,
|
|
|
|
|
- WsConnectStatusEnum,
|
|
|
|
|
- WsMsgTypeEnum,
|
|
|
|
|
- prettierReceiveWsMsg,
|
|
|
|
|
-} from '@/network/webSocket';
|
|
|
|
|
-import { AppRootState, useAppStore } from '@/store/app';
|
|
|
|
|
-import { useNetworkStore } from '@/store/network';
|
|
|
|
|
-import { useUserStore } from '@/store/user';
|
|
|
|
|
-import { createVideo } from '@/utils';
|
|
|
|
|
-
|
|
|
|
|
-export const useWs = () => {
|
|
|
|
|
- const appStore = useAppStore();
|
|
|
|
|
- const userStore = useUserStore();
|
|
|
|
|
- const networkStore = useNetworkStore();
|
|
|
|
|
- const loopHeartbeatTimer = ref();
|
|
|
|
|
- const liveUserList = ref<ILiveUser[]>([]);
|
|
|
|
|
- const roomId = ref('');
|
|
|
|
|
- const roomName = ref('');
|
|
|
|
|
- const roomNoLive = ref(false);
|
|
|
|
|
- const roomLiving = ref(false);
|
|
|
|
|
- const liveRoomInfo = ref<ILiveRoom>();
|
|
|
|
|
- const anchorInfo = ref<IUser>();
|
|
|
|
|
- const isAnchor = ref(false);
|
|
|
|
|
- const roomLiveType = ref(liveTypeEnum.srsFlvPull);
|
|
|
|
|
- const joined = ref(false);
|
|
|
|
|
- const isSRS = ref(false);
|
|
|
|
|
- const isPull = ref(false);
|
|
|
|
|
- const trackInfo = reactive({ track_audio: 1, track_video: 1 });
|
|
|
|
|
- const localVideo = ref<HTMLVideoElement>(document.createElement('video'));
|
|
|
|
|
- const localStream = ref<MediaStream>();
|
|
|
|
|
- const canvasVideoStream = ref<MediaStream>();
|
|
|
|
|
- const lastCoverImg = ref('');
|
|
|
|
|
- const maxBitrate = ref([
|
|
|
|
|
- {
|
|
|
|
|
- label: '1',
|
|
|
|
|
- value: 1,
|
|
|
|
|
- },
|
|
|
|
|
- {
|
|
|
|
|
- label: '10',
|
|
|
|
|
- value: 10,
|
|
|
|
|
- },
|
|
|
|
|
- {
|
|
|
|
|
- label: '1000',
|
|
|
|
|
- value: 1000,
|
|
|
|
|
- },
|
|
|
|
|
- {
|
|
|
|
|
- label: '2000',
|
|
|
|
|
- value: 2000,
|
|
|
|
|
- },
|
|
|
|
|
- {
|
|
|
|
|
- label: '3000',
|
|
|
|
|
- value: 3000,
|
|
|
|
|
- },
|
|
|
|
|
- {
|
|
|
|
|
- label: '4000',
|
|
|
|
|
- value: 4000,
|
|
|
|
|
- disabled: true,
|
|
|
|
|
- },
|
|
|
|
|
- {
|
|
|
|
|
- label: '5000',
|
|
|
|
|
- value: 5000,
|
|
|
|
|
- disabled: true,
|
|
|
|
|
- },
|
|
|
|
|
- {
|
|
|
|
|
- label: '6000',
|
|
|
|
|
- value: 6000,
|
|
|
|
|
- disabled: true,
|
|
|
|
|
- },
|
|
|
|
|
- {
|
|
|
|
|
- label: '7000',
|
|
|
|
|
- value: 7000,
|
|
|
|
|
- disabled: true,
|
|
|
|
|
- },
|
|
|
|
|
- {
|
|
|
|
|
- label: '8000',
|
|
|
|
|
- value: 8000,
|
|
|
|
|
- disabled: true,
|
|
|
|
|
- },
|
|
|
|
|
- ]);
|
|
|
|
|
- const maxFramerate = ref([
|
|
|
|
|
- {
|
|
|
|
|
- label: '1帧',
|
|
|
|
|
- value: 1,
|
|
|
|
|
- },
|
|
|
|
|
- {
|
|
|
|
|
- label: '10帧',
|
|
|
|
|
- value: 10,
|
|
|
|
|
- },
|
|
|
|
|
- {
|
|
|
|
|
- label: '24帧',
|
|
|
|
|
- value: 24,
|
|
|
|
|
- },
|
|
|
|
|
- {
|
|
|
|
|
- label: '30帧',
|
|
|
|
|
- value: 30,
|
|
|
|
|
- },
|
|
|
|
|
- {
|
|
|
|
|
- label: '60帧',
|
|
|
|
|
- value: 60,
|
|
|
|
|
- disabled: true,
|
|
|
|
|
- },
|
|
|
|
|
- ]);
|
|
|
|
|
- const resolutionRatio = ref([
|
|
|
|
|
- {
|
|
|
|
|
- label: '360P',
|
|
|
|
|
- value: 360,
|
|
|
|
|
- },
|
|
|
|
|
- {
|
|
|
|
|
- label: '540P',
|
|
|
|
|
- value: 540,
|
|
|
|
|
- },
|
|
|
|
|
- {
|
|
|
|
|
- label: '720P',
|
|
|
|
|
- value: 720,
|
|
|
|
|
- },
|
|
|
|
|
- {
|
|
|
|
|
- label: '1080P',
|
|
|
|
|
- value: 1080,
|
|
|
|
|
- },
|
|
|
|
|
- {
|
|
|
|
|
- label: '1440P',
|
|
|
|
|
- value: 1440,
|
|
|
|
|
- disabled: true,
|
|
|
|
|
- },
|
|
|
|
|
- ]);
|
|
|
|
|
- const currentMaxBitrate = ref(maxBitrate.value[2].value);
|
|
|
|
|
- const currentResolutionRatio = ref(resolutionRatio.value[3].value);
|
|
|
|
|
- const currentMaxFramerate = ref(maxFramerate.value[2].value);
|
|
|
|
|
-
|
|
|
|
|
- const damuList = ref<IDanmu[]>([]);
|
|
|
|
|
-
|
|
|
|
|
- watch(
|
|
|
|
|
- () => appStore.allTrack,
|
|
|
|
|
- (newTrack, oldTrack) => {
|
|
|
|
|
- console.log('appStore.allTrack变了', newTrack, oldTrack);
|
|
|
|
|
- const mixedStream = new MediaStream();
|
|
|
|
|
- newTrack.forEach((item) => {
|
|
|
|
|
- if (item.track) {
|
|
|
|
|
- mixedStream.addTrack(item.track);
|
|
|
|
|
- }
|
|
|
|
|
- });
|
|
|
|
|
- console.log('新的allTrack音频轨', mixedStream.getAudioTracks());
|
|
|
|
|
- console.log('新的allTrack视频轨', mixedStream.getVideoTracks());
|
|
|
|
|
- console.log('旧的allTrack音频轨', localStream.value?.getAudioTracks());
|
|
|
|
|
- console.log('旧的allTrack视频轨', localStream.value?.getVideoTracks());
|
|
|
|
|
- localStream.value = mixedStream;
|
|
|
|
|
- // if (isSRS.value) {
|
|
|
|
|
- // if (!isPull.value) {
|
|
|
|
|
- // networkStore.rtcMap.forEach((rtc) => {
|
|
|
|
|
- // rtc.close();
|
|
|
|
|
- // });
|
|
|
|
|
- // startNewWebRtc({
|
|
|
|
|
- // receiver: 'srs',
|
|
|
|
|
- // videoEl: localVideo.value,
|
|
|
|
|
- // });
|
|
|
|
|
- // }
|
|
|
|
|
- // }
|
|
|
|
|
- },
|
|
|
|
|
- { deep: true }
|
|
|
|
|
- );
|
|
|
|
|
- onUnmounted(() => {
|
|
|
|
|
- clearInterval(loopHeartbeatTimer.value);
|
|
|
|
|
- });
|
|
|
|
|
-
|
|
|
|
|
- watch(
|
|
|
|
|
- () => currentResolutionRatio.value,
|
|
|
|
|
- (newVal) => {
|
|
|
|
|
- if (canvasVideoStream.value) {
|
|
|
|
|
- canvasVideoStream.value.getVideoTracks().forEach((track) => {
|
|
|
|
|
- track.applyConstraints({
|
|
|
|
|
- frameRate: { max: currentMaxFramerate.value },
|
|
|
|
|
- height: newVal,
|
|
|
|
|
- });
|
|
|
|
|
- });
|
|
|
|
|
- } else {
|
|
|
|
|
- appStore.allTrack.forEach((info) => {
|
|
|
|
|
- info.track?.applyConstraints({
|
|
|
|
|
- frameRate: { max: currentMaxFramerate.value },
|
|
|
|
|
- height: newVal,
|
|
|
|
|
- });
|
|
|
|
|
- });
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- networkStore.rtcMap.forEach(async (rtc) => {
|
|
|
|
|
- const res = await rtc.setResolutionRatio(newVal);
|
|
|
|
|
- if (res === 1) {
|
|
|
|
|
- window.$message.success('切换分辨率成功!');
|
|
|
|
|
- } else {
|
|
|
|
|
- window.$message.success('切换分辨率失败!');
|
|
|
|
|
- }
|
|
|
|
|
- });
|
|
|
|
|
- }
|
|
|
|
|
- );
|
|
|
|
|
-
|
|
|
|
|
- watch(
|
|
|
|
|
- () => currentMaxFramerate.value,
|
|
|
|
|
- (newVal) => {
|
|
|
|
|
- console.log(currentMaxFramerate.value, 'currentMaxFramerate.value');
|
|
|
|
|
- if (canvasVideoStream.value) {
|
|
|
|
|
- canvasVideoStream.value.getVideoTracks().forEach((track) => {
|
|
|
|
|
- track.applyConstraints({
|
|
|
|
|
- frameRate: { max: newVal },
|
|
|
|
|
- height: currentResolutionRatio.value,
|
|
|
|
|
- });
|
|
|
|
|
- });
|
|
|
|
|
- } else {
|
|
|
|
|
- appStore.allTrack.forEach((info) => {
|
|
|
|
|
- info.track?.applyConstraints({
|
|
|
|
|
- frameRate: { max: newVal },
|
|
|
|
|
- height: currentResolutionRatio.value,
|
|
|
|
|
- });
|
|
|
|
|
- });
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- networkStore.rtcMap.forEach(async (rtc) => {
|
|
|
|
|
- const res = await rtc.setMaxFramerate(newVal);
|
|
|
|
|
- if (res === 1) {
|
|
|
|
|
- window.$message.success('切换帧率成功!');
|
|
|
|
|
- } else {
|
|
|
|
|
- window.$message.success('切换帧率失败!');
|
|
|
|
|
- }
|
|
|
|
|
- });
|
|
|
|
|
- }
|
|
|
|
|
- );
|
|
|
|
|
-
|
|
|
|
|
- watch(
|
|
|
|
|
- () => currentMaxBitrate.value,
|
|
|
|
|
- (newVal) => {
|
|
|
|
|
- networkStore.rtcMap.forEach(async (rtc) => {
|
|
|
|
|
- const res = await rtc.setMaxBitrate(newVal);
|
|
|
|
|
- if (res === 1) {
|
|
|
|
|
- window.$message.success('切换码率成功!');
|
|
|
|
|
- } else {
|
|
|
|
|
- window.$message.success('切换码率失败!');
|
|
|
|
|
- }
|
|
|
|
|
- });
|
|
|
|
|
- }
|
|
|
|
|
- );
|
|
|
|
|
-
|
|
|
|
|
- function addTrack(addTrackInfo: { track; stream }) {
|
|
|
|
|
- if (isAnchor.value) {
|
|
|
|
|
- networkStore.rtcMap.forEach((rtc) => {
|
|
|
|
|
- const sender = rtc.peerConnection
|
|
|
|
|
- ?.getSenders()
|
|
|
|
|
- .find((sender) => sender.track?.id === addTrackInfo.track?.id);
|
|
|
|
|
- if (!sender) {
|
|
|
|
|
- console.log('pc添加track-开播后中途添加', addTrackInfo.track?.id);
|
|
|
|
|
- // vel.srcObject = destination.stream;
|
|
|
|
|
- // canvasVideoStream.value!.getAudioTracks()[0] =
|
|
|
|
|
- // destination.stream.getAudioTracks()[0];
|
|
|
|
|
-
|
|
|
|
|
- // rtc.peerConnection?.addTrack(addTrackInfo.track, addTrackInfo.stream);
|
|
|
|
|
- rtc.peerConnection
|
|
|
|
|
- ?.getSenders()
|
|
|
|
|
- ?.find((sender) => sender.track?.kind === 'audio')
|
|
|
|
|
- ?.replaceTrack(canvasVideoStream.value!.getAudioTracks()[0]);
|
|
|
|
|
- const vel = createVideo({});
|
|
|
|
|
- vel.srcObject = canvasVideoStream.value!;
|
|
|
|
|
- // document.body.appendChild(vel);
|
|
|
|
|
- console.log(
|
|
|
|
|
- rtc.peerConnection
|
|
|
|
|
- ?.getSenders()
|
|
|
|
|
- ?.find((sender) => sender.track?.kind === 'audio'),
|
|
|
|
|
- 8888,
|
|
|
|
|
- rtc.peerConnection?.getSenders()
|
|
|
|
|
- );
|
|
|
|
|
- }
|
|
|
|
|
- });
|
|
|
|
|
- }
|
|
|
|
|
- const mixedStream = new MediaStream();
|
|
|
|
|
- appStore.allTrack.forEach((item) => {
|
|
|
|
|
- if (item.track) {
|
|
|
|
|
- mixedStream.addTrack(item.track);
|
|
|
|
|
- }
|
|
|
|
|
- });
|
|
|
|
|
- console.log('addTrack后结果的音频轨', mixedStream.getAudioTracks());
|
|
|
|
|
- console.log('addTrack后结果的视频轨', mixedStream.getVideoTracks());
|
|
|
|
|
- localStream.value = mixedStream;
|
|
|
|
|
- // srs不需要更新,因为更新了之后,跟着就关闭当前rtc然后重新new一个新的rtc了
|
|
|
|
|
- if (!isSRS.value) {
|
|
|
|
|
- let resUrl = '';
|
|
|
|
|
- const rtmpUrl = userStore.userInfo?.live_rooms?.[0].rtmp_url!;
|
|
|
|
|
- if (rtmpUrl.indexOf('type=') === -1) {
|
|
|
|
|
- resUrl += `${rtmpUrl}&type=${
|
|
|
|
|
- isSRS.value ? LiveRoomTypeEnum.user_srs : LiveRoomTypeEnum.user_wertc
|
|
|
|
|
- }`;
|
|
|
|
|
- } else {
|
|
|
|
|
- resUrl = rtmpUrl.replace(
|
|
|
|
|
- /type=([0-9]+)/,
|
|
|
|
|
- `type=${
|
|
|
|
|
- isSRS.value
|
|
|
|
|
- ? LiveRoomTypeEnum.user_srs
|
|
|
|
|
- : LiveRoomTypeEnum.user_wertc
|
|
|
|
|
- }`
|
|
|
|
|
- );
|
|
|
|
|
- }
|
|
|
|
|
- const data: WsUpdateJoinInfoType['data'] = {
|
|
|
|
|
- live_room_id: Number(roomId.value),
|
|
|
|
|
- track: {
|
|
|
|
|
- audio: appStore.getTrackInfo().audio > 0 ? 1 : 2,
|
|
|
|
|
- video: appStore.getTrackInfo().video > 0 ? 1 : 2,
|
|
|
|
|
- },
|
|
|
|
|
- rtmp_url: resUrl,
|
|
|
|
|
- };
|
|
|
|
|
- networkStore.wsMap.get(roomId.value)?.send({
|
|
|
|
|
- msgType: WsMsgTypeEnum.updateJoinInfo,
|
|
|
|
|
- data,
|
|
|
|
|
- });
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- function delTrack(delTrackInfo: AppRootState['allTrack'][0]) {
|
|
|
|
|
- if (isAnchor.value) {
|
|
|
|
|
- networkStore.rtcMap.forEach((rtc) => {
|
|
|
|
|
- const sender = rtc.peerConnection
|
|
|
|
|
- ?.getSenders()
|
|
|
|
|
- .find((sender) => sender.track?.id === delTrackInfo.track?.id);
|
|
|
|
|
- if (sender) {
|
|
|
|
|
- console.log('删除track', delTrackInfo, sender);
|
|
|
|
|
- rtc.peerConnection?.removeTrack(sender);
|
|
|
|
|
- }
|
|
|
|
|
- });
|
|
|
|
|
- }
|
|
|
|
|
- const mixedStream = new MediaStream();
|
|
|
|
|
- appStore.allTrack.forEach((item) => {
|
|
|
|
|
- if (item.track) {
|
|
|
|
|
- mixedStream.addTrack(item.track);
|
|
|
|
|
- }
|
|
|
|
|
- });
|
|
|
|
|
- console.log('delTrack后结果的音频轨', mixedStream.getAudioTracks());
|
|
|
|
|
- console.log('delTrack后结果的视频轨', mixedStream.getVideoTracks());
|
|
|
|
|
- localStream.value = mixedStream;
|
|
|
|
|
- if (!isSRS.value) {
|
|
|
|
|
- let resUrl = '';
|
|
|
|
|
- const rtmpUrl = userStore.userInfo?.live_rooms?.[0].rtmp_url!;
|
|
|
|
|
- if (rtmpUrl.indexOf('type=') === -1) {
|
|
|
|
|
- resUrl += `${rtmpUrl}&type=${
|
|
|
|
|
- isSRS.value ? LiveRoomTypeEnum.user_srs : LiveRoomTypeEnum.user_wertc
|
|
|
|
|
- }`;
|
|
|
|
|
- } else {
|
|
|
|
|
- resUrl = rtmpUrl.replace(
|
|
|
|
|
- /type=([0-9]+)/,
|
|
|
|
|
- `type=${
|
|
|
|
|
- isSRS.value
|
|
|
|
|
- ? LiveRoomTypeEnum.user_srs
|
|
|
|
|
- : LiveRoomTypeEnum.user_wertc
|
|
|
|
|
- }`
|
|
|
|
|
- );
|
|
|
|
|
- }
|
|
|
|
|
- const data: WsUpdateJoinInfoType['data'] = {
|
|
|
|
|
- live_room_id: Number(roomId.value),
|
|
|
|
|
- track: {
|
|
|
|
|
- audio: appStore.getTrackInfo().audio > 0 ? 1 : 2,
|
|
|
|
|
- video: appStore.getTrackInfo().video > 0 ? 1 : 2,
|
|
|
|
|
- },
|
|
|
|
|
- rtmp_url: resUrl,
|
|
|
|
|
- };
|
|
|
|
|
- networkStore.wsMap.get(roomId.value)?.send({
|
|
|
|
|
- msgType: WsMsgTypeEnum.updateJoinInfo,
|
|
|
|
|
- data,
|
|
|
|
|
- });
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- function getSocketId() {
|
|
|
|
|
- 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']>({
|
|
|
|
|
- msgType: WsMsgTypeEnum.heartbeat,
|
|
|
|
|
- data: {
|
|
|
|
|
- socket_id: socketId,
|
|
|
|
|
- },
|
|
|
|
|
- });
|
|
|
|
|
- }, 1000 * 5);
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- async function sendOffer({
|
|
|
|
|
- sender,
|
|
|
|
|
- receiver,
|
|
|
|
|
- }: {
|
|
|
|
|
- sender: string;
|
|
|
|
|
- receiver: string;
|
|
|
|
|
- }) {
|
|
|
|
|
- console.log('开始sendOffer');
|
|
|
|
|
- const ws = networkStore.wsMap.get(roomId.value);
|
|
|
|
|
- if (!ws) return;
|
|
|
|
|
- const rtc = networkStore.getRtcMap(`${roomId.value}___${receiver}`);
|
|
|
|
|
- if (!rtc) return;
|
|
|
|
|
- if (!isSRS.value) {
|
|
|
|
|
- const sdp = await rtc.createOffer();
|
|
|
|
|
- await rtc.setLocalDescription(sdp!);
|
|
|
|
|
- ws.send({
|
|
|
|
|
- msgType: WsMsgTypeEnum.offer,
|
|
|
|
|
- data: {
|
|
|
|
|
- sdp,
|
|
|
|
|
- sender,
|
|
|
|
|
- receiver,
|
|
|
|
|
- live_room_id: roomId.value,
|
|
|
|
|
- },
|
|
|
|
|
- });
|
|
|
|
|
- } else {
|
|
|
|
|
- const sdp = await rtc.createOffer();
|
|
|
|
|
- await rtc.setLocalDescription(sdp!);
|
|
|
|
|
- let res;
|
|
|
|
|
-
|
|
|
|
|
- if (isPull.value) {
|
|
|
|
|
- res = await fetchRtcV1Play({
|
|
|
|
|
- api: `/rtc/v1/play/`,
|
|
|
|
|
- clientip: null,
|
|
|
|
|
- sdp: sdp!.sdp!,
|
|
|
|
|
- streamurl: liveRoomInfo.value!.rtmp_url!.replace('rtmp', 'webrtc'),
|
|
|
|
|
- tid: getRandomString(10),
|
|
|
|
|
- });
|
|
|
|
|
- } else {
|
|
|
|
|
- res = await fetchRtcV1Publish({
|
|
|
|
|
- api: `/rtc/v1/publish/`,
|
|
|
|
|
- clientip: null,
|
|
|
|
|
- sdp: sdp!.sdp!,
|
|
|
|
|
- streamurl: userStore.userInfo!.live_rooms![0]!.rtmp_url!.replace(
|
|
|
|
|
- 'rtmp',
|
|
|
|
|
- 'webrtc'
|
|
|
|
|
- ),
|
|
|
|
|
- tid: getRandomString(10),
|
|
|
|
|
- });
|
|
|
|
|
- const data: WsUpdateJoinInfoType['data'] = {
|
|
|
|
|
- live_room_id: Number(roomId.value),
|
|
|
|
|
- track: {
|
|
|
|
|
- audio: appStore.getTrackInfo().audio > 0 ? 1 : 2,
|
|
|
|
|
- video: appStore.getTrackInfo().video > 0 ? 1 : 2,
|
|
|
|
|
- },
|
|
|
|
|
- };
|
|
|
|
|
- networkStore.wsMap.get(roomId.value)?.send({
|
|
|
|
|
- msgType: WsMsgTypeEnum.updateJoinInfo,
|
|
|
|
|
- data,
|
|
|
|
|
- });
|
|
|
|
|
- }
|
|
|
|
|
- if (res.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: res.data.sdp })
|
|
|
|
|
- );
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- function sendStartLive({ coverImg, name }) {
|
|
|
|
|
- networkStore.wsMap.get(roomId.value)?.send<WsStartLiveType['data']>({
|
|
|
|
|
- msgType: WsMsgTypeEnum.startLive,
|
|
|
|
|
- data: {
|
|
|
|
|
- cover_img: coverImg,
|
|
|
|
|
- name,
|
|
|
|
|
- },
|
|
|
|
|
- });
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- function sendJoin() {
|
|
|
|
|
- const instance = networkStore.wsMap.get(roomId.value);
|
|
|
|
|
- if (!instance) return;
|
|
|
|
|
- let resUrl = '';
|
|
|
|
|
- const rtmpUrl = userStore.userInfo?.live_rooms?.[0].rtmp_url;
|
|
|
|
|
- // 如果是用户看直播,发送join时不需要rtmpUrl;只有房主直播的时候需要带rtmpUrl
|
|
|
|
|
- if (rtmpUrl) {
|
|
|
|
|
- if (rtmpUrl.indexOf('type=') === -1) {
|
|
|
|
|
- resUrl += `${rtmpUrl}&type=${
|
|
|
|
|
- isSRS.value ? LiveRoomTypeEnum.user_srs : LiveRoomTypeEnum.user_wertc
|
|
|
|
|
- }`;
|
|
|
|
|
- } else {
|
|
|
|
|
- resUrl = rtmpUrl.replace(
|
|
|
|
|
- /type=([0-9]+)/,
|
|
|
|
|
- `type=${
|
|
|
|
|
- isSRS.value
|
|
|
|
|
- ? LiveRoomTypeEnum.user_srs
|
|
|
|
|
- : LiveRoomTypeEnum.user_wertc
|
|
|
|
|
- }`
|
|
|
|
|
- );
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
- instance.send<WsJoinType['data']>({
|
|
|
|
|
- msgType: WsMsgTypeEnum.join,
|
|
|
|
|
- data: {
|
|
|
|
|
- socket_id: getSocketId(),
|
|
|
|
|
- live_room: {
|
|
|
|
|
- id: Number(roomId.value),
|
|
|
|
|
- name: roomName.value,
|
|
|
|
|
- cover_img: lastCoverImg.value,
|
|
|
|
|
- type: isSRS.value
|
|
|
|
|
- ? LiveRoomTypeEnum.user_srs
|
|
|
|
|
- : LiveRoomTypeEnum.user_wertc,
|
|
|
|
|
- rtmp_url: resUrl,
|
|
|
|
|
- },
|
|
|
|
|
- },
|
|
|
|
|
- });
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- function handleNegotiationneeded(data: { roomId: string; isSRS: boolean }) {
|
|
|
|
|
- console.warn(`${data.roomId},开始监听pc的negotiationneeded`);
|
|
|
|
|
- const rtc = networkStore.getRtcMap(data.roomId);
|
|
|
|
|
- if (!rtc) return;
|
|
|
|
|
- console.warn(`监听pc的negotiationneeded`);
|
|
|
|
|
- rtc.peerConnection?.addEventListener('negotiationneeded', (event) => {
|
|
|
|
|
- console.warn(`${data.roomId},pc收到negotiationneeded`, event);
|
|
|
|
|
- sendOffer({
|
|
|
|
|
- sender: getSocketId(),
|
|
|
|
|
- receiver: rtc.receiver,
|
|
|
|
|
- });
|
|
|
|
|
- });
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- /** 原生的webrtc时,receiver必传 */
|
|
|
|
|
- function startNewWebRtc({
|
|
|
|
|
- receiver,
|
|
|
|
|
- videoEl,
|
|
|
|
|
- }: {
|
|
|
|
|
- receiver: string;
|
|
|
|
|
- videoEl: HTMLVideoElement;
|
|
|
|
|
- }) {
|
|
|
|
|
- let rtc: WebRTCClass;
|
|
|
|
|
- if (isSRS.value) {
|
|
|
|
|
- console.warn('SRS开始new WebRTCClass', `${roomId.value}___${receiver!}`);
|
|
|
|
|
- rtc = new WebRTCClass({
|
|
|
|
|
- maxBitrate: isPull.value ? -1 : currentMaxBitrate.value,
|
|
|
|
|
- maxFramerate: isPull.value ? -1 : currentMaxFramerate.value,
|
|
|
|
|
- resolutionRatio: isPull.value ? -1 : currentResolutionRatio.value,
|
|
|
|
|
- roomId: `${roomId.value}___${receiver!}`,
|
|
|
|
|
- videoEl,
|
|
|
|
|
- isSRS: true,
|
|
|
|
|
- receiver,
|
|
|
|
|
- });
|
|
|
|
|
- if (isPull.value) {
|
|
|
|
|
- if (trackInfo.track_video === 1) {
|
|
|
|
|
- rtc.peerConnection?.addTransceiver('video', {
|
|
|
|
|
- direction: 'recvonly',
|
|
|
|
|
- });
|
|
|
|
|
- }
|
|
|
|
|
- if (trackInfo.track_audio === 1) {
|
|
|
|
|
- rtc.peerConnection?.addTransceiver('audio', {
|
|
|
|
|
- direction: 'recvonly',
|
|
|
|
|
- });
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
- // handleNegotiationneeded({
|
|
|
|
|
- // roomId: `${roomId.value}___${receiver}`,
|
|
|
|
|
- // isSRS: true,
|
|
|
|
|
- // });
|
|
|
|
|
- if (canvasVideoStream.value) {
|
|
|
|
|
- localStream.value = canvasVideoStream.value;
|
|
|
|
|
- }
|
|
|
|
|
- rtc.localStream = localStream.value;
|
|
|
|
|
- localStream.value?.getTracks().forEach((track) => {
|
|
|
|
|
- console.warn(
|
|
|
|
|
- 'srs startNewWebRtc,pc插入track',
|
|
|
|
|
- track.id,
|
|
|
|
|
- localStream.value?.id
|
|
|
|
|
- );
|
|
|
|
|
- console.log('pc添加track-srs', track.kind, track.id);
|
|
|
|
|
- rtc.peerConnection?.addTrack(track, localStream.value!);
|
|
|
|
|
- });
|
|
|
|
|
-
|
|
|
|
|
- sendOffer({
|
|
|
|
|
- sender: getSocketId(),
|
|
|
|
|
- receiver,
|
|
|
|
|
- });
|
|
|
|
|
- } else {
|
|
|
|
|
- console.warn('开始new WebRTCClass', `${roomId.value}___${receiver!}`);
|
|
|
|
|
- rtc = new WebRTCClass({
|
|
|
|
|
- maxBitrate: isPull.value ? -1 : currentMaxBitrate.value,
|
|
|
|
|
- maxFramerate: isPull.value ? -1 : currentMaxFramerate.value,
|
|
|
|
|
- resolutionRatio: isPull.value ? -1 : currentResolutionRatio.value,
|
|
|
|
|
- roomId: `${roomId.value}___${receiver!}`,
|
|
|
|
|
- videoEl,
|
|
|
|
|
- isSRS: false,
|
|
|
|
|
- receiver,
|
|
|
|
|
- });
|
|
|
|
|
- if (isAnchor.value) {
|
|
|
|
|
- handleNegotiationneeded({
|
|
|
|
|
- roomId: `${roomId.value}___${receiver}`,
|
|
|
|
|
- isSRS: false,
|
|
|
|
|
- });
|
|
|
|
|
- rtc.localStream = localStream.value;
|
|
|
|
|
- localStream.value?.getTracks().forEach((track) => {
|
|
|
|
|
- // rtc.peerConnection?.addTransceiver(track, {
|
|
|
|
|
- // streams: [localStream.value!],
|
|
|
|
|
- // direction: 'sendonly',
|
|
|
|
|
- // });
|
|
|
|
|
- console.log('pc添加track-原生');
|
|
|
|
|
- rtc.peerConnection?.addTrack(track, localStream.value!);
|
|
|
|
|
- });
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
- return rtc;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- 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;
|
|
|
|
|
- ws.status = WsConnectStatusEnum.connect;
|
|
|
|
|
- ws.update();
|
|
|
|
|
- sendJoin();
|
|
|
|
|
- });
|
|
|
|
|
-
|
|
|
|
|
- // websocket连接断开
|
|
|
|
|
- ws.socketIo.on(WsConnectStatusEnum.disconnect, () => {
|
|
|
|
|
- prettierReceiveWsMsg(WsConnectStatusEnum.disconnect, ws);
|
|
|
|
|
- if (!ws) return;
|
|
|
|
|
- ws.status = WsConnectStatusEnum.disconnect;
|
|
|
|
|
- ws.update();
|
|
|
|
|
- });
|
|
|
|
|
-
|
|
|
|
|
- // 收到offer
|
|
|
|
|
- ws.socketIo.on(WsMsgTypeEnum.offer, async (data: WsOfferType) => {
|
|
|
|
|
- prettierReceiveWsMsg(
|
|
|
|
|
- WsMsgTypeEnum.offer,
|
|
|
|
|
- `发送者:${data.data.sender},接收者:${data.data.receiver}`,
|
|
|
|
|
- data
|
|
|
|
|
- );
|
|
|
|
|
- if (isSRS.value) return;
|
|
|
|
|
- if (!ws) return;
|
|
|
|
|
- if (data.data.receiver === getSocketId()) {
|
|
|
|
|
- console.log('收到offer,这个offer是发给我的');
|
|
|
|
|
- if (!isAnchor.value) {
|
|
|
|
|
- // 如果是用户进来看直播
|
|
|
|
|
- let rtc = networkStore.getRtcMap(
|
|
|
|
|
- `${roomId.value}___${data.data.sender}`
|
|
|
|
|
- );
|
|
|
|
|
- if (!rtc) {
|
|
|
|
|
- rtc = await startNewWebRtc({
|
|
|
|
|
- receiver: data.data.sender,
|
|
|
|
|
- videoEl: localVideo.value,
|
|
|
|
|
- });
|
|
|
|
|
- }
|
|
|
|
|
- await rtc.setRemoteDescription(data.data.sdp);
|
|
|
|
|
- const sdp = await rtc.createAnswer();
|
|
|
|
|
- await rtc.setLocalDescription(sdp!);
|
|
|
|
|
- const answerData: WsAnswerType['data'] = {
|
|
|
|
|
- sdp,
|
|
|
|
|
- sender: getSocketId(),
|
|
|
|
|
- receiver: data.data.sender,
|
|
|
|
|
- live_room_id: data.data.live_room_id,
|
|
|
|
|
- };
|
|
|
|
|
- ws.send({
|
|
|
|
|
- msgType: WsMsgTypeEnum.answer,
|
|
|
|
|
- data: answerData,
|
|
|
|
|
- });
|
|
|
|
|
- }
|
|
|
|
|
- } else {
|
|
|
|
|
- console.log('收到offer,但是这个offer不是发给我的');
|
|
|
|
|
- }
|
|
|
|
|
- });
|
|
|
|
|
-
|
|
|
|
|
- // 收到answer
|
|
|
|
|
- ws.socketIo.on(WsMsgTypeEnum.answer, async (data: WsOfferType) => {
|
|
|
|
|
- prettierReceiveWsMsg(
|
|
|
|
|
- WsMsgTypeEnum.answer,
|
|
|
|
|
- `发送者:${data.data.sender},接收者:${data.data.receiver}`,
|
|
|
|
|
- data
|
|
|
|
|
- );
|
|
|
|
|
- if (isSRS.value) return;
|
|
|
|
|
- if (!ws) return;
|
|
|
|
|
- const rtc = networkStore.getRtcMap(`${roomId.value}___${data.socket_id}`);
|
|
|
|
|
- if (!rtc) return;
|
|
|
|
|
- rtc.update();
|
|
|
|
|
- if (data.data.receiver === getSocketId()) {
|
|
|
|
|
- console.log('收到answer,这个answer是发给我的');
|
|
|
|
|
- await rtc.setRemoteDescription(data.data.sdp);
|
|
|
|
|
- } else {
|
|
|
|
|
- console.log('收到answer,但这个answer不是发给我的');
|
|
|
|
|
- }
|
|
|
|
|
- });
|
|
|
|
|
-
|
|
|
|
|
- // 收到candidate
|
|
|
|
|
- ws.socketIo.on(WsMsgTypeEnum.candidate, (data: WsCandidateType['data']) => {
|
|
|
|
|
- prettierReceiveWsMsg(
|
|
|
|
|
- WsMsgTypeEnum.candidate,
|
|
|
|
|
- `发送者:${data.sender},接收者:${data.receiver}`,
|
|
|
|
|
- data
|
|
|
|
|
- );
|
|
|
|
|
- if (isSRS.value) return;
|
|
|
|
|
- if (!ws) return;
|
|
|
|
|
- const rtc = networkStore.getRtcMap(`${roomId.value}___${data.sender}`);
|
|
|
|
|
- if (!rtc) return;
|
|
|
|
|
- if (data.sender !== getSocketId()) {
|
|
|
|
|
- console.log('不是我发的candidate');
|
|
|
|
|
- rtc.peerConnection
|
|
|
|
|
- ?.addIceCandidate(data.candidate)
|
|
|
|
|
- .then(() => {
|
|
|
|
|
- console.log('candidate成功');
|
|
|
|
|
- })
|
|
|
|
|
- .catch((err) => {
|
|
|
|
|
- console.error('candidate失败', err);
|
|
|
|
|
- });
|
|
|
|
|
- } else {
|
|
|
|
|
- console.log('是我发的candidate');
|
|
|
|
|
- }
|
|
|
|
|
- });
|
|
|
|
|
-
|
|
|
|
|
- // 主播正在直播
|
|
|
|
|
- ws.socketIo.on(WsMsgTypeEnum.roomLiving, (data: WsRoomLivingType) => {
|
|
|
|
|
- prettierReceiveWsMsg(WsMsgTypeEnum.roomLiving, data);
|
|
|
|
|
- roomLiving.value = true;
|
|
|
|
|
- roomNoLive.value = false;
|
|
|
|
|
- // 如果是srs开播,则不需要等有人进来了才new webrtc,只要Websocket连上了就开始new webrtc
|
|
|
|
|
- if (isSRS.value) {
|
|
|
|
|
- if (isPull.value) {
|
|
|
|
|
- if (roomLiveType.value === liveTypeEnum.srsWebrtcPull) {
|
|
|
|
|
- startNewWebRtc({
|
|
|
|
|
- receiver: 'srs',
|
|
|
|
|
- videoEl: localVideo.value,
|
|
|
|
|
- });
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
- });
|
|
|
|
|
-
|
|
|
|
|
- // 主播不在直播
|
|
|
|
|
- ws.socketIo.on(WsMsgTypeEnum.roomNoLive, (data) => {
|
|
|
|
|
- prettierReceiveWsMsg(WsMsgTypeEnum.roomNoLive, data);
|
|
|
|
|
- roomNoLive.value = true;
|
|
|
|
|
- roomLiving.value = false;
|
|
|
|
|
- });
|
|
|
|
|
-
|
|
|
|
|
- // 当前所有在线用户
|
|
|
|
|
- ws.socketIo.on(
|
|
|
|
|
- WsMsgTypeEnum.liveUser,
|
|
|
|
|
- (data: WSGetRoomAllUserType['data']) => {
|
|
|
|
|
- prettierReceiveWsMsg(WsMsgTypeEnum.liveUser, data);
|
|
|
|
|
- const res = data.liveUser.map((item) => {
|
|
|
|
|
- return {
|
|
|
|
|
- id: item.id,
|
|
|
|
|
- // userInfo: item.id,
|
|
|
|
|
- };
|
|
|
|
|
- });
|
|
|
|
|
- liveUserList.value = res;
|
|
|
|
|
- }
|
|
|
|
|
- );
|
|
|
|
|
-
|
|
|
|
|
- // 收到用户发送消息
|
|
|
|
|
- ws.socketIo.on(WsMsgTypeEnum.message, (data: WsMessageType) => {
|
|
|
|
|
- prettierReceiveWsMsg(WsMsgTypeEnum.message, data);
|
|
|
|
|
- if (!ws) return;
|
|
|
|
|
- damuList.value.push({
|
|
|
|
|
- socket_id: data.socket_id,
|
|
|
|
|
- msgType: DanmuMsgTypeEnum.danmu,
|
|
|
|
|
- msg: data.data.msg,
|
|
|
|
|
- userInfo: data.user_info,
|
|
|
|
|
- });
|
|
|
|
|
- });
|
|
|
|
|
-
|
|
|
|
|
- // 用户加入房间完成
|
|
|
|
|
- ws.socketIo.on(WsMsgTypeEnum.joined, (data: WsJoinType['data']) => {
|
|
|
|
|
- prettierReceiveWsMsg(WsMsgTypeEnum.joined, data);
|
|
|
|
|
- joined.value = true;
|
|
|
|
|
- trackInfo.track_audio = 1;
|
|
|
|
|
- trackInfo.track_video = 1;
|
|
|
|
|
- liveUserList.value.push({
|
|
|
|
|
- id: data.socket_id,
|
|
|
|
|
- userInfo: data.user_info,
|
|
|
|
|
- });
|
|
|
|
|
- liveRoomInfo.value = data.live_room;
|
|
|
|
|
- anchorInfo.value = data.anchor_info;
|
|
|
|
|
- ws.send<WsGetLiveUserType['data']>({
|
|
|
|
|
- msgType: WsMsgTypeEnum.getLiveUser,
|
|
|
|
|
- data: {
|
|
|
|
|
- live_room_id: data.live_room.id!,
|
|
|
|
|
- },
|
|
|
|
|
- });
|
|
|
|
|
- // 如果是srs开播,则不需要等有人进来了才new webrtc,只要Websocket连上了就开始new webrtc
|
|
|
|
|
- // if (isSRS.value) {
|
|
|
|
|
- // if (!isPull.value) {
|
|
|
|
|
- // startNewWebRtc({
|
|
|
|
|
- // receiver: 'srs',
|
|
|
|
|
- // videoEl: localVideo.value,
|
|
|
|
|
- // });
|
|
|
|
|
- // }
|
|
|
|
|
- // }
|
|
|
|
|
- });
|
|
|
|
|
-
|
|
|
|
|
- // 其他用户加入房间
|
|
|
|
|
- ws.socketIo.on(WsMsgTypeEnum.otherJoin, (data: WsOtherJoinType['data']) => {
|
|
|
|
|
- prettierReceiveWsMsg(WsMsgTypeEnum.otherJoin, data);
|
|
|
|
|
- liveUserList.value.push({
|
|
|
|
|
- id: data.join_socket_id,
|
|
|
|
|
- userInfo: data.join_user_info,
|
|
|
|
|
- });
|
|
|
|
|
- const danmu: IDanmu = {
|
|
|
|
|
- msgType: DanmuMsgTypeEnum.otherJoin,
|
|
|
|
|
- socket_id: data.join_socket_id,
|
|
|
|
|
- userInfo: data.join_user_info,
|
|
|
|
|
- msg: '',
|
|
|
|
|
- };
|
|
|
|
|
- damuList.value.push(danmu);
|
|
|
|
|
- ws.send<WsGetLiveUserType['data']>({
|
|
|
|
|
- msgType: WsMsgTypeEnum.getLiveUser,
|
|
|
|
|
- data: {
|
|
|
|
|
- live_room_id: data.live_room.id!,
|
|
|
|
|
- },
|
|
|
|
|
- });
|
|
|
|
|
- // 如果是srs开播,且进来的用户不是srs-webrtc-pull,则不能再new webrtc了
|
|
|
|
|
- if (isSRS.value) return;
|
|
|
|
|
- if (joined.value) {
|
|
|
|
|
- // startNewWebRtc({
|
|
|
|
|
- // receiver: data.join_socket_id,
|
|
|
|
|
- // videoEl: localVideo.value,
|
|
|
|
|
- // });
|
|
|
|
|
- }
|
|
|
|
|
- });
|
|
|
|
|
-
|
|
|
|
|
- // 用户离开房间
|
|
|
|
|
- ws.socketIo.on(WsMsgTypeEnum.leave, (data) => {
|
|
|
|
|
- prettierReceiveWsMsg(WsMsgTypeEnum.leave, data);
|
|
|
|
|
- if (!ws) return;
|
|
|
|
|
- ws.send({
|
|
|
|
|
- msgType: WsMsgTypeEnum.leave,
|
|
|
|
|
- data: { roomId: ws.roomId },
|
|
|
|
|
- });
|
|
|
|
|
- });
|
|
|
|
|
-
|
|
|
|
|
- // 用户离开房间完成
|
|
|
|
|
- ws.socketIo.on(WsMsgTypeEnum.leaved, (data: WsLeavedType['data']) => {
|
|
|
|
|
- prettierReceiveWsMsg(WsMsgTypeEnum.leaved, data);
|
|
|
|
|
- networkStore.rtcMap
|
|
|
|
|
- .get(`${roomId.value}___${data.socket_id as string}`)
|
|
|
|
|
- ?.close();
|
|
|
|
|
- networkStore.removeRtc(`${roomId.value}___${data.socket_id as string}`);
|
|
|
|
|
- const res = liveUserList.value.filter(
|
|
|
|
|
- (item) => item.id !== data.socket_id
|
|
|
|
|
- );
|
|
|
|
|
- liveUserList.value = res;
|
|
|
|
|
- damuList.value.push({
|
|
|
|
|
- socket_id: data.socket_id,
|
|
|
|
|
- msgType: DanmuMsgTypeEnum.userLeaved,
|
|
|
|
|
- userInfo: data.user_info,
|
|
|
|
|
- msg: '',
|
|
|
|
|
- });
|
|
|
|
|
- });
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- function initWs(data: {
|
|
|
|
|
- isAnchor: boolean;
|
|
|
|
|
- roomId: string;
|
|
|
|
|
- isSRS: boolean;
|
|
|
|
|
- isPull: boolean;
|
|
|
|
|
- currentResolutionRatio?: number;
|
|
|
|
|
- currentMaxFramerate?: number;
|
|
|
|
|
- currentMaxBitrate?: number;
|
|
|
|
|
- roomLiveType: liveTypeEnum;
|
|
|
|
|
- }) {
|
|
|
|
|
- roomId.value = data.roomId;
|
|
|
|
|
- isAnchor.value = data.isAnchor;
|
|
|
|
|
- roomLiveType.value = data.roomLiveType;
|
|
|
|
|
- if (data.currentMaxBitrate) {
|
|
|
|
|
- currentMaxBitrate.value = data.currentMaxBitrate;
|
|
|
|
|
- }
|
|
|
|
|
- if (data.currentMaxFramerate) {
|
|
|
|
|
- currentMaxFramerate.value = data.currentMaxFramerate;
|
|
|
|
|
- }
|
|
|
|
|
- if (data.currentResolutionRatio) {
|
|
|
|
|
- currentResolutionRatio.value = data.currentResolutionRatio;
|
|
|
|
|
- }
|
|
|
|
|
- isSRS.value = data.isSRS;
|
|
|
|
|
- isPull.value = data.isPull;
|
|
|
|
|
- new WebSocketClass({
|
|
|
|
|
- roomId: roomId.value,
|
|
|
|
|
- url: WEBSOCKET_URL,
|
|
|
|
|
- isAnchor: data.isAnchor,
|
|
|
|
|
- });
|
|
|
|
|
- initReceive();
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- return {
|
|
|
|
|
- getSocketId,
|
|
|
|
|
- initWs,
|
|
|
|
|
- addTrack,
|
|
|
|
|
- delTrack,
|
|
|
|
|
- startNewWebRtc,
|
|
|
|
|
- sendStartLive,
|
|
|
|
|
- canvasVideoStream,
|
|
|
|
|
- lastCoverImg,
|
|
|
|
|
- roomLiving,
|
|
|
|
|
- liveRoomInfo,
|
|
|
|
|
- anchorInfo,
|
|
|
|
|
- roomNoLive,
|
|
|
|
|
- loopHeartbeatTimer,
|
|
|
|
|
- localStream,
|
|
|
|
|
- liveUserList,
|
|
|
|
|
- damuList,
|
|
|
|
|
- maxBitrate,
|
|
|
|
|
- maxFramerate,
|
|
|
|
|
- resolutionRatio,
|
|
|
|
|
- currentMaxFramerate,
|
|
|
|
|
- currentMaxBitrate,
|
|
|
|
|
- currentResolutionRatio,
|
|
|
|
|
- };
|
|
|
|
|
-};
|
|
|