yangjie #46
22
main.js
22
main.js
|
|
@ -402,6 +402,9 @@ app.on('ready', () => {
|
||||||
case 'show':
|
case 'show':
|
||||||
mainWindow.show()
|
mainWindow.show()
|
||||||
mainWindow.focus();
|
mainWindow.focus();
|
||||||
|
mainWindow.setSkipTaskbar(false)
|
||||||
|
mainWindow.setResizable(true)
|
||||||
|
mainWindow.setAlwaysOnTop(false)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
@ -485,6 +488,11 @@ app.on('ready', () => {
|
||||||
});
|
});
|
||||||
// 设置桌面应用基础属性
|
// 设置桌面应用基础属性
|
||||||
ipcMain.handle('setMainWindowSize', (event, config) => {
|
ipcMain.handle('setMainWindowSize', (event, config) => {
|
||||||
|
if (config.width === 250) {
|
||||||
|
mainWindow.setSkipTaskbar(true)
|
||||||
|
mainWindow.setResizable(false)
|
||||||
|
mainWindow.setAlwaysOnTop(true, 'screen-saver')
|
||||||
|
}
|
||||||
// 设置最小窗口尺寸
|
// 设置最小窗口尺寸
|
||||||
mainWindow.setMinimumSize(config.width, config.height);
|
mainWindow.setMinimumSize(config.width, config.height);
|
||||||
// 设置最大尺寸
|
// 设置最大尺寸
|
||||||
|
|
@ -572,9 +580,6 @@ app.on('ready', () => {
|
||||||
childWindow[k] = ""
|
childWindow[k] = ""
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
mainWindow.setSkipTaskbar(false)
|
|
||||||
mainWindow.setResizable(true)
|
|
||||||
mainWindow.setAlwaysOnTop(false)
|
|
||||||
} else {
|
} else {
|
||||||
childWindow[key].close()
|
childWindow[key].close()
|
||||||
childWindow[key] = ""
|
childWindow[key] = ""
|
||||||
|
|
@ -610,10 +615,14 @@ app.on('ready', () => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (childWindow[config.key].isVisible()) {
|
if (config.bool) {
|
||||||
childWindow[config.key].hide()
|
childWindow[config.key].hide()
|
||||||
} else {
|
} else {
|
||||||
childWindow[config.key].show()
|
if (childWindow[config.key].isVisible()) {
|
||||||
|
childWindow[config.key].hide()
|
||||||
|
} else {
|
||||||
|
childWindow[config.key].show()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
@ -715,9 +724,6 @@ function windowOperation(config) {
|
||||||
case 'shareScreenWindow':
|
case 'shareScreenWindow':
|
||||||
x = Math.round((display.workArea.width - child.getSize()[0]) / 2);
|
x = Math.round((display.workArea.width - child.getSize()[0]) / 2);
|
||||||
child.setPosition(x, 0);
|
child.setPosition(x, 0);
|
||||||
mainWindow.setSkipTaskbar(true)
|
|
||||||
mainWindow.setResizable(false)
|
|
||||||
mainWindow.setAlwaysOnTop(true, 'screen-saver')
|
|
||||||
break;
|
break;
|
||||||
case 'chatSmallWindow':
|
case 'chatSmallWindow':
|
||||||
y = height - child.getSize()[1];
|
y = height - child.getSize()[1];
|
||||||
|
|
|
||||||
55
preload.js
55
preload.js
|
|
@ -116,8 +116,59 @@ window.electron = {
|
||||||
ipcRenderer.invoke('setRegistry', uuid)
|
ipcRenderer.invoke('setRegistry', uuid)
|
||||||
},
|
},
|
||||||
// 创建子窗口
|
// 创建子窗口
|
||||||
createChildWindow: (config) => {
|
createChildWindow: (str) => {
|
||||||
ipcRenderer.invoke('createChildWindow', config)
|
switch (str) {
|
||||||
|
case 'show':
|
||||||
|
ipcRenderer.invoke('setChildWindowShow', {
|
||||||
|
key: 'shareScreenWindow',
|
||||||
|
})
|
||||||
|
ipcRenderer.invoke('setChildWindowShow', {
|
||||||
|
key: 'chatSmallWindow',
|
||||||
|
})
|
||||||
|
break;
|
||||||
|
case 'hide':
|
||||||
|
ipcRenderer.invoke('createChildWindow', {
|
||||||
|
url: location.origin + `/#/noticeWindow`,
|
||||||
|
width: 388,
|
||||||
|
height: 150,
|
||||||
|
key: 'noticeWindow',
|
||||||
|
})
|
||||||
|
ipcRenderer.invoke('createChildWindow', {
|
||||||
|
url: location.origin + `/#/shareScreenWindow`,
|
||||||
|
width: 400,
|
||||||
|
height: 80,
|
||||||
|
key: 'shareScreenWindow',
|
||||||
|
})
|
||||||
|
ipcRenderer.invoke('createChildWindow', {
|
||||||
|
url: location.origin + `/#/chatSmallWindow`,
|
||||||
|
width: 200,
|
||||||
|
height: 150,
|
||||||
|
key: 'chatSmallWindow',
|
||||||
|
})
|
||||||
|
ipcRenderer.invoke('createChildWindow', {
|
||||||
|
url: location.origin + `/#/chatBigWindow`,
|
||||||
|
width: 540,
|
||||||
|
height: 640,
|
||||||
|
key: 'chatBigWindow',
|
||||||
|
})
|
||||||
|
ipcRenderer.invoke('createChildWindow', {
|
||||||
|
url: location.origin + `/#/userListWindow`,
|
||||||
|
width: 440,
|
||||||
|
height: 540,
|
||||||
|
key: 'userListWindow',
|
||||||
|
})
|
||||||
|
break;
|
||||||
|
case 'stop':
|
||||||
|
ipcRenderer.invoke('setChildWindowShow', {
|
||||||
|
key: 'shareScreenWindow',
|
||||||
|
bool: true
|
||||||
|
})
|
||||||
|
ipcRenderer.invoke('setChildWindowShow', {
|
||||||
|
key: 'chatSmallWindow',
|
||||||
|
bool: true
|
||||||
|
})
|
||||||
|
break;
|
||||||
|
}
|
||||||
},
|
},
|
||||||
// 关闭子窗口
|
// 关闭子窗口
|
||||||
closeChildWindow: (key) => {
|
closeChildWindow: (key) => {
|
||||||
|
|
|
||||||
|
|
@ -171,6 +171,7 @@ const Meeting: React.FC = () => {
|
||||||
})
|
})
|
||||||
const [networkOther, setNetworkOther] = useState<RtcStats>({})
|
const [networkOther, setNetworkOther] = useState<RtcStats>({})
|
||||||
const [isComputerAudio, setIsComputerAudio] = useState(false)
|
const [isComputerAudio, setIsComputerAudio] = useState(false)
|
||||||
|
const [_isLeave, setIsLeave] = useState(false)
|
||||||
const [isScreenCapture, setIsScreenCapture] = useState(false)
|
const [isScreenCapture, setIsScreenCapture] = useState(false)
|
||||||
const [isFluencyPriority, setIsFluencyPriority] = useState(false)
|
const [isFluencyPriority, setIsFluencyPriority] = useState(false)
|
||||||
const [open, setOpen] = useState(false)
|
const [open, setOpen] = useState(false)
|
||||||
|
|
@ -208,6 +209,7 @@ const Meeting: React.FC = () => {
|
||||||
const channel = new BroadcastChannel('meeting_channel');
|
const channel = new BroadcastChannel('meeting_channel');
|
||||||
let storeDevice: any;
|
let storeDevice: any;
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
window.electron.createChildWindow('hide')
|
||||||
let time: NodeJS.Timeout;
|
let time: NodeJS.Timeout;
|
||||||
setUser(userInfo)
|
setUser(userInfo)
|
||||||
window.electron.getIsMaximized().then((res: boolean) => {
|
window.electron.getIsMaximized().then((res: boolean) => {
|
||||||
|
|
@ -484,6 +486,7 @@ const Meeting: React.FC = () => {
|
||||||
window.removeEventListener('wheel', handleWheelChange);
|
window.removeEventListener('wheel', handleWheelChange);
|
||||||
clearInterval(time)
|
clearInterval(time)
|
||||||
channel.close();
|
channel.close();
|
||||||
|
window.electron.closeChildWindow('shareScreenWindow')
|
||||||
};
|
};
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
|
|
@ -871,7 +874,22 @@ const Meeting: React.FC = () => {
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (recorder) {
|
if (recorder) {
|
||||||
recorder.start();
|
recorder.start()
|
||||||
|
recorder.onstart = async () => {
|
||||||
|
message.success('开始录制')
|
||||||
|
}
|
||||||
|
recorder.onerror = async () => {
|
||||||
|
setRecorder('')
|
||||||
|
setMediaStream([])
|
||||||
|
setIsClickedMediaSteam(false)
|
||||||
|
changeStatusList({
|
||||||
|
title: '录制中'
|
||||||
|
}, 1, 3)
|
||||||
|
message.error('录制失败,请重新录制!')
|
||||||
|
}
|
||||||
|
recorder.onstop = async () => {
|
||||||
|
|
||||||
|
}
|
||||||
recorder.ondataavailable = async (event: any) => {
|
recorder.ondataavailable = async (event: any) => {
|
||||||
const blob = await fixWebmDuration(event.data);
|
const blob = await fixWebmDuration(event.data);
|
||||||
const reader = new FileReader() as any;
|
const reader = new FileReader() as any;
|
||||||
|
|
@ -900,6 +918,16 @@ const Meeting: React.FC = () => {
|
||||||
onCancel() {
|
onCancel() {
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
setIsLeave(bool => {
|
||||||
|
if (bool) {
|
||||||
|
if (userInfo.isAnonymous) {
|
||||||
|
storage.setItem('userLogin', false)
|
||||||
|
} else {
|
||||||
|
navigate('/home/index')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
})
|
||||||
};
|
};
|
||||||
reader.readAsArrayBuffer(blob);
|
reader.readAsArrayBuffer(blob);
|
||||||
}
|
}
|
||||||
|
|
@ -1001,8 +1029,8 @@ const Meeting: React.FC = () => {
|
||||||
channelId: connection.channelId,
|
channelId: connection.channelId,
|
||||||
sourceType: VideoSourceType.VideoSourceCameraPrimary,
|
sourceType: VideoSourceType.VideoSourceCameraPrimary,
|
||||||
})
|
})
|
||||||
getShowUser();
|
}, 1000);
|
||||||
}, 1500);
|
getShowUser();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
@ -1017,7 +1045,7 @@ const Meeting: React.FC = () => {
|
||||||
view: document.getElementById(`video-${remoteUid}`),
|
view: document.getElementById(`video-${remoteUid}`),
|
||||||
channelId: connection.channelId,
|
channelId: connection.channelId,
|
||||||
})
|
})
|
||||||
}, 1500);
|
}, 1000);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
@ -1200,22 +1228,18 @@ const Meeting: React.FC = () => {
|
||||||
// 刷新
|
// 刷新
|
||||||
const refreshVideoView = async (userItem: any): Promise<void> => {
|
const refreshVideoView = async (userItem: any): Promise<void> => {
|
||||||
if (userItem.uid === userInfo.uid) {
|
if (userItem.uid === userInfo.uid) {
|
||||||
setTimeout(async () => {
|
await agora.setupLocalVideo({
|
||||||
await agora.setupLocalVideo({
|
uid: Number(userItem.uid),
|
||||||
uid: Number(userItem.uid),
|
view: document.getElementById(`video-${userItem.uid}`),
|
||||||
view: document.getElementById(`video-${userItem.uid}`),
|
channelId: state.channelId,
|
||||||
channelId: state.channelId,
|
sourceType: VideoSourceType.VideoSourceCameraPrimary,
|
||||||
sourceType: VideoSourceType.VideoSourceCameraPrimary,
|
})
|
||||||
})
|
|
||||||
}, 1500);
|
|
||||||
} else {
|
} else {
|
||||||
setTimeout(async () => {
|
await agora.setupRemoteVideoJoin({
|
||||||
await agora.setupRemoteVideoJoin({
|
uid: Number(userItem.uid),
|
||||||
uid: Number(userItem.uid),
|
view: document.getElementById(`video-${userItem.uid}`),
|
||||||
view: document.getElementById(`video-${userItem.uid}`),
|
channelId: state.channelId,
|
||||||
channelId: state.channelId,
|
})
|
||||||
})
|
|
||||||
}, 1500);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// 替换数据
|
// 替换数据
|
||||||
|
|
@ -1578,7 +1602,7 @@ const Meeting: React.FC = () => {
|
||||||
// 开始录制
|
// 开始录制
|
||||||
const mediaRecorder = new MediaRecorder(combinedSource, {
|
const mediaRecorder = new MediaRecorder(combinedSource, {
|
||||||
mimeType: 'video/webm;codecs=vp9,opus',
|
mimeType: 'video/webm;codecs=vp9,opus',
|
||||||
videoBitsPerSecond: 1.5e6,
|
videoBitsPerSecond: 1500,
|
||||||
});
|
});
|
||||||
setRecorder(mediaRecorder);
|
setRecorder(mediaRecorder);
|
||||||
});
|
});
|
||||||
|
|
@ -1642,7 +1666,10 @@ const Meeting: React.FC = () => {
|
||||||
const stopRecorderMedia = async (): Promise<void> => {
|
const stopRecorderMedia = async (): Promise<void> => {
|
||||||
setRecorder((res: any) => {
|
setRecorder((res: any) => {
|
||||||
if (res) {
|
if (res) {
|
||||||
res.stop();
|
try {
|
||||||
|
res.stop()
|
||||||
|
} catch (error) {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return res
|
return res
|
||||||
})
|
})
|
||||||
|
|
@ -1650,7 +1677,10 @@ const Meeting: React.FC = () => {
|
||||||
if (res.length) {
|
if (res.length) {
|
||||||
res.forEach((item: any) => {
|
res.forEach((item: any) => {
|
||||||
item.getTracks().forEach((track: any) => {
|
item.getTracks().forEach((track: any) => {
|
||||||
track.stop()
|
try {
|
||||||
|
track.stop()
|
||||||
|
} catch (error) {
|
||||||
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
@ -1659,19 +1689,25 @@ const Meeting: React.FC = () => {
|
||||||
}
|
}
|
||||||
// 退出房间
|
// 退出房间
|
||||||
const leaveChannel = async (bool: boolean = true): Promise<void> => {
|
const leaveChannel = async (bool: boolean = true): Promise<void> => {
|
||||||
|
setIsLeave(true)
|
||||||
await stopScreenCapture()
|
await stopScreenCapture()
|
||||||
await stopRecorderMedia()
|
await stopRecorderMedia()
|
||||||
if (bool) {
|
if (bool) {
|
||||||
await getLeave()
|
await getLeave()
|
||||||
}
|
}
|
||||||
await agora.leaveChannel()
|
await agora.leaveChannel()
|
||||||
setTimeout(() => {
|
setRecorder((res: any) => {
|
||||||
if (userInfo.isAnonymous) {
|
if (res) {
|
||||||
storage.setItem('userLogin', false)
|
|
||||||
} else {
|
} else {
|
||||||
navigate('/home/index')
|
if (userInfo.isAnonymous) {
|
||||||
|
storage.setItem('userLogin', false)
|
||||||
|
} else {
|
||||||
|
navigate('/home/index')
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}, 1000)
|
return res
|
||||||
|
})
|
||||||
}
|
}
|
||||||
// 分享屏幕
|
// 分享屏幕
|
||||||
const clickSharedScreen = async (): Promise<void> => {
|
const clickSharedScreen = async (): Promise<void> => {
|
||||||
|
|
@ -1694,39 +1730,7 @@ const Meeting: React.FC = () => {
|
||||||
const isOpen = await getKeyOpenChildWindow('shareScreenWindow')
|
const isOpen = await getKeyOpenChildWindow('shareScreenWindow')
|
||||||
setIsScreenCapture(true)
|
setIsScreenCapture(true)
|
||||||
if (!isOpen) {
|
if (!isOpen) {
|
||||||
window.electron.createChildWindow({
|
window.electron.createChildWindow('show')
|
||||||
url: location.origin + `/#/noticeWindow`,
|
|
||||||
width: 388,
|
|
||||||
height: 150,
|
|
||||||
key: 'noticeWindow',
|
|
||||||
show: true,
|
|
||||||
})
|
|
||||||
window.electron.createChildWindow({
|
|
||||||
url: location.origin + `/#/shareScreenWindow`,
|
|
||||||
width: 400,
|
|
||||||
height: 80,
|
|
||||||
key: 'shareScreenWindow',
|
|
||||||
show: true,
|
|
||||||
})
|
|
||||||
window.electron.createChildWindow({
|
|
||||||
url: location.origin + `/#/chatSmallWindow`,
|
|
||||||
width: 200,
|
|
||||||
height: 150,
|
|
||||||
key: 'chatSmallWindow',
|
|
||||||
show: true,
|
|
||||||
})
|
|
||||||
window.electron.createChildWindow({
|
|
||||||
url: location.origin + `/#/chatBigWindow`,
|
|
||||||
width: 540,
|
|
||||||
height: 640,
|
|
||||||
key: 'chatBigWindow',
|
|
||||||
})
|
|
||||||
window.electron.createChildWindow({
|
|
||||||
url: location.origin + `/#/userListWindow`,
|
|
||||||
width: 440,
|
|
||||||
height: 540,
|
|
||||||
key: 'userListWindow',
|
|
||||||
})
|
|
||||||
setKeyOpenChildWindow('shareScreenWindow', true)
|
setKeyOpenChildWindow('shareScreenWindow', true)
|
||||||
window.electron.setMainWindowSize({
|
window.electron.setMainWindowSize({
|
||||||
width: 250,
|
width: 250,
|
||||||
|
|
@ -1749,7 +1753,7 @@ const Meeting: React.FC = () => {
|
||||||
}
|
}
|
||||||
// 获取桌面可共享屏幕的引用
|
// 获取桌面可共享屏幕的引用
|
||||||
const getDesktopCapturerVideo = (): void => {
|
const getDesktopCapturerVideo = (): void => {
|
||||||
agora.getDesktopCapturerVideo({ width: 300, height: 300 }, { width: 300, height: 300 }, true).then((res: any) => {
|
agora.getDesktopCapturerVideo({ width: 50, height: 50 }, { width: 30, height: 30 }, true).then((res: any) => {
|
||||||
res.forEach((item: any, index: number) => {
|
res.forEach((item: any, index: number) => {
|
||||||
if (item.type === 1) {
|
if (item.type === 1) {
|
||||||
item.sourceTitle = '桌面' + (index + 1)
|
item.sourceTitle = '桌面' + (index + 1)
|
||||||
|
|
@ -1785,9 +1789,10 @@ const Meeting: React.FC = () => {
|
||||||
const footerListTemplate = [...footerList]
|
const footerListTemplate = [...footerList]
|
||||||
await agora.leaveChannelEx(userInfo.screenShareId)
|
await agora.leaveChannelEx(userInfo.screenShareId)
|
||||||
agora.stopScreenCapture()
|
agora.stopScreenCapture()
|
||||||
|
await agora.destroyRendererByView()
|
||||||
footerListTemplate[1][0].title = '共享屏幕'
|
footerListTemplate[1][0].title = '共享屏幕'
|
||||||
setFooterList(footerListTemplate)
|
setFooterList(footerListTemplate)
|
||||||
window.electron.closeChildWindow('shareScreenWindow')
|
window.electron.createChildWindow('stop')
|
||||||
setKeyOpenChildWindow('shareScreenWindow', false)
|
setKeyOpenChildWindow('shareScreenWindow', false)
|
||||||
setIsScreenCapture(bool => {
|
setIsScreenCapture(bool => {
|
||||||
if (bool) {
|
if (bool) {
|
||||||
|
|
@ -2750,7 +2755,8 @@ const Meeting: React.FC = () => {
|
||||||
<div className={styles.meetingUserVideoList} style={{ width: statusList.userVideo ? '500px' : '500px' }}>
|
<div className={styles.meetingUserVideoList} style={{ width: statusList.userVideo ? '500px' : '500px' }}>
|
||||||
<div className={styles.meetingUserVideoListTitle}>
|
<div className={styles.meetingUserVideoListTitle}>
|
||||||
<span>会议监控</span>
|
<span>会议监控</span>
|
||||||
<img src={ImageUrl.icon18} alt="" onClick={() => {
|
<img src={ImageUrl.icon18} alt="" onClick={async () => {
|
||||||
|
await agora.allLeaveChannelEx()
|
||||||
setStatusList({
|
setStatusList({
|
||||||
userList: false,
|
userList: false,
|
||||||
userChatList: false,
|
userChatList: false,
|
||||||
|
|
|
||||||
|
|
@ -29,7 +29,7 @@ export interface IElectronAPI {
|
||||||
isVisible: () => Promise<string>;
|
isVisible: () => Promise<string>;
|
||||||
setRegistry: (uuid: string) => any;
|
setRegistry: (uuid: string) => any;
|
||||||
getRegistry: () => any;
|
getRegistry: () => any;
|
||||||
createChildWindow: (config: any) => void;
|
createChildWindow: (str: string) => void;
|
||||||
setChildWindow: (config: any) => void;
|
setChildWindow: (config: any) => void;
|
||||||
setChildWindowShow: (config: any) => void;
|
setChildWindowShow: (config: any) => void;
|
||||||
closeChildWindow: (key: string) => void;
|
closeChildWindow: (key: string) => void;
|
||||||
|
|
|
||||||
|
|
@ -366,7 +366,6 @@ export const agora = {
|
||||||
},
|
},
|
||||||
// 退出第二个房间
|
// 退出第二个房间
|
||||||
allLeaveChannelEx: async () => {
|
allLeaveChannelEx: async () => {
|
||||||
await agora.stopCameraCapture();
|
|
||||||
await rtcEngine.leaveChannelEx({ channelId: option.channelId + 'a', localUid: Number('1' + option.screenShareId) })
|
await rtcEngine.leaveChannelEx({ channelId: option.channelId + 'a', localUid: Number('1' + option.screenShareId) })
|
||||||
},
|
},
|
||||||
// 停止/恢复接收指定的视频流。
|
// 停止/恢复接收指定的视频流。
|
||||||
|
|
@ -385,6 +384,12 @@ export const agora = {
|
||||||
destroyRendererByConfig: async (uid: number, channelId?: string) => {
|
destroyRendererByConfig: async (uid: number, channelId?: string) => {
|
||||||
await rtcEngine.destroyRendererByConfig(VideoSourceType.VideoSourceRemote, channelId, uid);
|
await rtcEngine.destroyRendererByConfig(VideoSourceType.VideoSourceRemote, channelId, uid);
|
||||||
},
|
},
|
||||||
|
destroyRendererByView: async () => {
|
||||||
|
let dom = document.getElementById(`meetingAbsoluteVideo`);
|
||||||
|
if (dom) {
|
||||||
|
await rtcEngine.destroyRendererByView(dom);
|
||||||
|
}
|
||||||
|
},
|
||||||
// ai降噪
|
// ai降噪
|
||||||
setAINSMode: async (enabled: boolean, mode: AudioAinsMode) => {
|
setAINSMode: async (enabled: boolean, mode: AudioAinsMode) => {
|
||||||
rtcEngine.setAINSMode(enabled, mode)
|
rtcEngine.setAINSMode(enabled, mode)
|
||||||
|
|
@ -436,7 +441,7 @@ export const agora = {
|
||||||
},
|
},
|
||||||
// 停止采集摄像头
|
// 停止采集摄像头
|
||||||
stopCameraCapture: async () => {
|
stopCameraCapture: async () => {
|
||||||
await rtcEngine.stopCameraCapture()
|
await rtcEngine.stopCameraCapture(VideoSourceType.VideoSourceCamera)
|
||||||
},
|
},
|
||||||
// 加入频道
|
// 加入频道
|
||||||
setJoinChannel: async (data: any) => {
|
setJoinChannel: async (data: any) => {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue