Compare commits
21 Commits
3498dc9a61
...
ae8ba8cbe2
| Author | SHA1 | Date |
|---|---|---|
|
|
ae8ba8cbe2 | |
|
|
7aa8bb4a8f | |
|
|
bafa7e3a70 | |
|
|
4f462e818b | |
|
|
c99ec3668c | |
|
|
9a5ef75322 | |
|
|
0781ebc3af | |
|
|
cb1593a76f | |
|
|
79b1d8c5c2 | |
|
|
0b57e83e29 | |
|
|
cc2759b242 | |
|
|
b314a2c25f | |
|
|
5fb95d6a15 | |
|
|
4fbcf0e319 | |
|
|
a20c833de0 | |
|
|
234665d08d | |
|
|
4528696ec7 | |
|
|
9619230cf8 | |
|
|
844547d853 | |
|
|
b267f8bf4c | |
|
|
a29784bb26 |
11
main.js
11
main.js
|
|
@ -8,6 +8,7 @@ const {
|
||||||
ipcMain,
|
ipcMain,
|
||||||
clipboard,
|
clipboard,
|
||||||
dialog,
|
dialog,
|
||||||
|
crashReporter,
|
||||||
desktopCapturer,
|
desktopCapturer,
|
||||||
} = require('electron');
|
} = require('electron');
|
||||||
const path = require('node:path')
|
const path = require('node:path')
|
||||||
|
|
@ -16,6 +17,7 @@ const fs = require('fs');
|
||||||
const Registry = require('winreg');
|
const Registry = require('winreg');
|
||||||
const { autoUpdater, CancellationToken } = require('electron-updater');
|
const { autoUpdater, CancellationToken } = require('electron-updater');
|
||||||
const signalR = require('@microsoft/signalr');
|
const signalR = require('@microsoft/signalr');
|
||||||
|
const { setTimeout, setInterval, clearTimeout, clearInterval } = require('timers');
|
||||||
const cancellationToken = new CancellationToken()
|
const cancellationToken = new CancellationToken()
|
||||||
app.allowRendererProcessReuse = false;
|
app.allowRendererProcessReuse = false;
|
||||||
let mainWindow = null;
|
let mainWindow = null;
|
||||||
|
|
@ -25,6 +27,7 @@ let env;
|
||||||
let regKey;
|
let regKey;
|
||||||
let connection = null;
|
let connection = null;
|
||||||
let envStr;
|
let envStr;
|
||||||
|
let startNumber = 0;
|
||||||
|
|
||||||
class AppWindow extends BrowserWindow {
|
class AppWindow extends BrowserWindow {
|
||||||
constructor(config) {
|
constructor(config) {
|
||||||
|
|
@ -99,6 +102,11 @@ const additionalData = { myKey: 'myValue' }
|
||||||
app.on('ready', () => {
|
app.on('ready', () => {
|
||||||
const gotTheLock = app.requestSingleInstanceLock(additionalData)
|
const gotTheLock = app.requestSingleInstanceLock(additionalData)
|
||||||
if (gotTheLock) {
|
if (gotTheLock) {
|
||||||
|
app.getPath('crashDumps')
|
||||||
|
crashReporter.start({
|
||||||
|
uploadToServer: false,
|
||||||
|
ignoreSystemCrashHandler: false
|
||||||
|
})
|
||||||
env = process.argv.find((arg) => arg.startsWith('--env='))?.split('=')[1];
|
env = process.argv.find((arg) => arg.startsWith('--env='))?.split('=')[1];
|
||||||
if (env === 'development') {
|
if (env === 'development') {
|
||||||
Object.defineProperty(app, 'isPackaged', {
|
Object.defineProperty(app, 'isPackaged', {
|
||||||
|
|
@ -141,11 +149,14 @@ app.on('ready', () => {
|
||||||
});
|
});
|
||||||
ipcMain.handle('setEnv', (event, str) => {
|
ipcMain.handle('setEnv', (event, str) => {
|
||||||
envStr = str;
|
envStr = str;
|
||||||
|
if (startNumber === 0) {
|
||||||
updateHandle() // 检查更新
|
updateHandle() // 检查更新
|
||||||
setInterval(() => {
|
setInterval(() => {
|
||||||
updateHandle() // 每一小时检查更新
|
updateHandle() // 每一小时检查更新
|
||||||
}, 1000 * 60 * 60)
|
}, 1000 * 60 * 60)
|
||||||
createTray()
|
createTray()
|
||||||
|
startNumber++
|
||||||
|
}
|
||||||
});
|
});
|
||||||
// socket
|
// socket
|
||||||
ipcMain.handle('startSignalr', (event, user) => {
|
ipcMain.handle('startSignalr', (event, user) => {
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,7 @@ import Avatar from '@/components/Avatar';
|
||||||
import { useNavigate } from 'react-router-dom';
|
import { useNavigate } from 'react-router-dom';
|
||||||
import { agora } from '@/utils/package/agora';
|
import { agora } from '@/utils/package/agora';
|
||||||
import { role } from '@/config/role';
|
import { role } from '@/config/role';
|
||||||
|
const { setInterval, clearInterval } = require('timers');
|
||||||
let time = null as any;
|
let time = null as any;
|
||||||
const JoinSetting = forwardRef((_props: any, ref: any) => {
|
const JoinSetting = forwardRef((_props: any, ref: any) => {
|
||||||
useImperativeHandle(ref, () => ({
|
useImperativeHandle(ref, () => ({
|
||||||
|
|
|
||||||
|
|
@ -65,8 +65,8 @@
|
||||||
height: 0;
|
height: 0;
|
||||||
|
|
||||||
.userVideoContentListItem {
|
.userVideoContentListItem {
|
||||||
height: 32%;
|
height: 13%;
|
||||||
width: calc(100% / 4 - 8px);
|
width: calc(100% / 3 - 8px);
|
||||||
padding: 4px;
|
padding: 4px;
|
||||||
|
|
||||||
.userVideoContentListItemVideo {
|
.userVideoContentListItemVideo {
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@ import { Button, Empty, Select, message } from 'antd';
|
||||||
import { useEffect, useState } from "react";
|
import { useEffect, useState } from "react";
|
||||||
import { useLocation } from 'react-router';
|
import { useLocation } from 'react-router';
|
||||||
import { VideoStreamType } from 'agora-electron-sdk';
|
import { VideoStreamType } from 'agora-electron-sdk';
|
||||||
|
const { setInterval, clearInterval } = require('timers');
|
||||||
const UserVideo: React.FC = () => {
|
const UserVideo: React.FC = () => {
|
||||||
const { state } = useLocation();
|
const { state } = useLocation();
|
||||||
const [from, setFrom] = useState<any>({
|
const [from, setFrom] = useState<any>({
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,7 @@ import { role } from '@/config/role';
|
||||||
import dayjs from 'dayjs';
|
import dayjs from 'dayjs';
|
||||||
import StupWizard from '@/components/StupWizard';
|
import StupWizard from '@/components/StupWizard';
|
||||||
import { GetSubDpList } from '@/api/Home/User';
|
import { GetSubDpList } from '@/api/Home/User';
|
||||||
|
const { setInterval, clearInterval } = require('timers');
|
||||||
const fs = require('fs').promises;
|
const fs = require('fs').promises;
|
||||||
const { exec } = require('child_process');
|
const { exec } = require('child_process');
|
||||||
const { RangePicker } = DatePicker;
|
const { RangePicker } = DatePicker;
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@ import { storage } from '@/utils';
|
||||||
import ImageUrl from '@/utils/package/imageUrl'
|
import ImageUrl from '@/utils/package/imageUrl'
|
||||||
import Avatar from '@/components/Avatar';
|
import Avatar from '@/components/Avatar';
|
||||||
import StupWizard from '@/components/StupWizard';
|
import StupWizard from '@/components/StupWizard';
|
||||||
|
const { setInterval, clearInterval } = require('timers');
|
||||||
dayjs.locale('zh-cn');
|
dayjs.locale('zh-cn');
|
||||||
type navListType = {
|
type navListType = {
|
||||||
title: string;
|
title: string;
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@ import { CaretDownOutlined, CaretUpOutlined } from '@ant-design/icons';
|
||||||
import { Button } from 'antd';
|
import { Button } from 'antd';
|
||||||
import dayjs from 'dayjs';
|
import dayjs from 'dayjs';
|
||||||
import { useEffect, useState } from "react";
|
import { useEffect, useState } from "react";
|
||||||
|
const { setInterval, clearInterval } = require('timers');
|
||||||
const ShareScreenWindow: React.FC = () => {
|
const ShareScreenWindow: React.FC = () => {
|
||||||
const [footerLists, setFooterLists] = useState<any>([
|
const [footerLists, setFooterLists] = useState<any>([
|
||||||
{
|
{
|
||||||
|
|
@ -54,6 +55,11 @@ const ShareScreenWindow: React.FC = () => {
|
||||||
let timeout: NodeJS.Timeout;
|
let timeout: NodeJS.Timeout;
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
getRoomUser()
|
getRoomUser()
|
||||||
|
if (!role.ID.includes(userInfo.roleId)) {
|
||||||
|
setFooterLists((res: any) => {
|
||||||
|
return res.splice(4, 1)
|
||||||
|
})
|
||||||
|
}
|
||||||
channel.onmessage = function (event) {
|
channel.onmessage = function (event) {
|
||||||
let { type, time } = event.data;
|
let { type, time } = event.data;
|
||||||
switch (type) {
|
switch (type) {
|
||||||
|
|
@ -82,8 +88,10 @@ const ShareScreenWindow: React.FC = () => {
|
||||||
footerListTemplate[0].active = data.parmes.footerList[0][0].active;
|
footerListTemplate[0].active = data.parmes.footerList[0][0].active;
|
||||||
footerListTemplate[1].title = data.parmes.footerList[0][1].active ? '开启视频' : '关闭视频';
|
footerListTemplate[1].title = data.parmes.footerList[0][1].active ? '开启视频' : '关闭视频';
|
||||||
footerListTemplate[1].active = data.parmes.footerList[0][1].active;
|
footerListTemplate[1].active = data.parmes.footerList[0][1].active;
|
||||||
|
if (role.ID.includes(userInfo.roleId)) {
|
||||||
footerListTemplate[4].title = data.parmes.footerList[1][3].active ? '录制中' : '录制';
|
footerListTemplate[4].title = data.parmes.footerList[1][3].active ? '录制中' : '录制';
|
||||||
footerListTemplate[4].active = data.parmes.footerList[1][3].active;
|
footerListTemplate[4].active = data.parmes.footerList[1][3].active;
|
||||||
|
}
|
||||||
setFooterLists(footerListTemplate)
|
setFooterLists(footerListTemplate)
|
||||||
break;
|
break;
|
||||||
case 'roomUserList':
|
case 'roomUserList':
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,7 @@ import { fixWebmDuration } from "webm-duration-fix-buffer";
|
||||||
import { getKeyOpenChildWindow, setKeyOpenChildWindow } from '@/utils/package/public';
|
import { getKeyOpenChildWindow, setKeyOpenChildWindow } from '@/utils/package/public';
|
||||||
import MeetingDisconnected from '@/components/MeetingDisconnected';
|
import MeetingDisconnected from '@/components/MeetingDisconnected';
|
||||||
import SingIn from '@/components/SingIn';
|
import SingIn from '@/components/SingIn';
|
||||||
|
const { setTimeout, setInterval, clearTimeout, clearInterval } = require('timers');
|
||||||
const { confirm } = Modal;
|
const { confirm } = Modal;
|
||||||
const { exec } = require('child_process');
|
const { exec } = require('child_process');
|
||||||
const fs = require('fs').promises;
|
const fs = require('fs').promises;
|
||||||
|
|
@ -435,6 +436,7 @@ const Meeting: React.FC = () => {
|
||||||
if (!data) {
|
if (!data) {
|
||||||
setIsScreenCapture(bool => {
|
setIsScreenCapture(bool => {
|
||||||
if (!bool) {
|
if (!bool) {
|
||||||
|
if (role.ID.includes(userInfo.roleId)) {
|
||||||
confirm({
|
confirm({
|
||||||
title: '提示',
|
title: '提示',
|
||||||
icon: <ExclamationCircleFilled />,
|
icon: <ExclamationCircleFilled />,
|
||||||
|
|
@ -456,6 +458,9 @@ const Meeting: React.FC = () => {
|
||||||
showSingIn()
|
showSingIn()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
} else {
|
||||||
|
showSingIn()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return bool
|
return bool
|
||||||
})
|
})
|
||||||
|
|
@ -914,12 +919,18 @@ const Meeting: React.FC = () => {
|
||||||
observer?.unobserve(element);
|
observer?.unobserve(element);
|
||||||
});
|
});
|
||||||
const observerObject = new IntersectionObserver(async (entries: IntersectionObserverEntry[], _observer: IntersectionObserver) => {
|
const observerObject = new IntersectionObserver(async (entries: IntersectionObserverEntry[], _observer: IntersectionObserver) => {
|
||||||
|
setIsScreenCapture((bool: boolean) => {
|
||||||
entries.forEach(async (entry) => {
|
entries.forEach(async (entry) => {
|
||||||
if (entry.target.id !== user.uid) {
|
if (entry.target.id !== user.uid) {
|
||||||
await agora.muteRemoteVideoStreamEx(Number(entry.target.id), !entry.isIntersecting)
|
await agora.muteRemoteVideoStreamEx(Number(entry.target.id), bool ? true : !entry.isIntersecting)
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
await agora.muteRemoteVideoStreamEx(Number(currentVideoId), false)
|
return bool
|
||||||
|
})
|
||||||
|
setIsScreenCapture((bool: boolean) => {
|
||||||
|
agora.muteRemoteVideoStreamEx(Number(currentVideoId), bool)
|
||||||
|
return bool
|
||||||
|
})
|
||||||
}, { threshold: 0, root: document.getElementById('videoView') });
|
}, { threshold: 0, root: document.getElementById('videoView') });
|
||||||
setObserver(observerObject)
|
setObserver(observerObject)
|
||||||
elements.forEach(element => {
|
elements.forEach(element => {
|
||||||
|
|
@ -1611,11 +1622,11 @@ const Meeting: React.FC = () => {
|
||||||
}
|
}
|
||||||
// 退出房间
|
// 退出房间
|
||||||
const leaveChannel = async (bool: boolean = true): Promise<void> => {
|
const leaveChannel = async (bool: boolean = true): Promise<void> => {
|
||||||
|
await stopScreenCapture()
|
||||||
await stopRecorderMedia()
|
await stopRecorderMedia()
|
||||||
if (bool) {
|
if (bool) {
|
||||||
await getLeave()
|
await getLeave()
|
||||||
}
|
}
|
||||||
await stopScreenCapture()
|
|
||||||
await agora.leaveChannel()
|
await agora.leaveChannel()
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
if (userInfo.isAnonymous) {
|
if (userInfo.isAnonymous) {
|
||||||
|
|
@ -1623,11 +1634,20 @@ const Meeting: React.FC = () => {
|
||||||
} else {
|
} else {
|
||||||
navigate('/home/index')
|
navigate('/home/index')
|
||||||
}
|
}
|
||||||
}, 0)
|
}, 1000)
|
||||||
}
|
}
|
||||||
// 分享屏幕
|
// 分享屏幕
|
||||||
const clickSharedScreen = async (): Promise<void> => {
|
const clickSharedScreen = async (): Promise<void> => {
|
||||||
let data = sharedScreenList.find((item: any) => item.sourceId === sharedScreenItem.sourceId)
|
let data = sharedScreenList.find((item: any) => item.sourceId === sharedScreenItem.sourceId)
|
||||||
|
const elements = document.querySelectorAll('.intersectionObserver-view');
|
||||||
|
if (elements.length) {
|
||||||
|
elements.forEach(item => {
|
||||||
|
if (item.id !== userInfo.uid) {
|
||||||
|
agora.muteRemoteVideoStreamEx(Number(item.id), true)
|
||||||
|
}
|
||||||
|
});
|
||||||
|
agora.setSubscribeVideoBlocklist([Number(user.screenShareId)], 1)
|
||||||
|
}
|
||||||
if (data) {
|
if (data) {
|
||||||
const footerListTemplate = [...footerList]
|
const footerListTemplate = [...footerList]
|
||||||
footerListTemplate[footerListIndex.itemIndex][footerListIndex.rowIndex].title = '停止共享'
|
footerListTemplate[footerListIndex.itemIndex][footerListIndex.rowIndex].title = '停止共享'
|
||||||
|
|
@ -2667,7 +2687,7 @@ const Meeting: React.FC = () => {
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
:
|
:
|
||||||
<div className={styles.meetingUserVideoList} style={{ width: statusList.userVideo ? '100vw' : '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={() => {
|
||||||
|
|
@ -2837,6 +2857,21 @@ const Meeting: React.FC = () => {
|
||||||
</label>
|
</label>
|
||||||
<span>{row.title}</span>
|
<span>{row.title}</span>
|
||||||
</div>
|
</div>
|
||||||
|
case '录制':
|
||||||
|
case '录制中':
|
||||||
|
if (role.ID.includes(user.roleId)) {
|
||||||
|
return <div
|
||||||
|
className='drag'
|
||||||
|
onClick={() => changeStatusList(row, itemIndex, rowIndex)}
|
||||||
|
onMouseDown={() => changeFooterListSelect(row, itemIndex, rowIndex, true)}
|
||||||
|
onMouseUp={() => changeFooterListSelect(row, itemIndex, rowIndex, false)}
|
||||||
|
onMouseLeave={() => changeFooterListSelect(row, itemIndex, rowIndex, false)}
|
||||||
|
key={rowIndex}>
|
||||||
|
{row.select ? <img src={row.iconSelect} alt="" /> : <img src={row.active ? row.iconActive : row.icon} alt="" />}
|
||||||
|
<span>{row.title}</span>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
return null
|
||||||
default:
|
default:
|
||||||
return <div
|
return <div
|
||||||
className='drag'
|
className='drag'
|
||||||
|
|
|
||||||
|
|
@ -21,12 +21,14 @@ import {
|
||||||
BeautyOptions,
|
BeautyOptions,
|
||||||
ColorEnhanceOptions,
|
ColorEnhanceOptions,
|
||||||
LowlightEnhanceOptions,
|
LowlightEnhanceOptions,
|
||||||
VirtualBackgroundSource
|
VirtualBackgroundSource,
|
||||||
|
AudienceLatencyLevelType
|
||||||
} from "agora-electron-sdk";
|
} from "agora-electron-sdk";
|
||||||
import { GetRoomRtcToken, GetAgoraConf } from "@/api/Home/Index";
|
import { GetRoomRtcToken, GetAgoraConf } from "@/api/Home/Index";
|
||||||
import { storage } from '@/utils';
|
import { storage } from '@/utils';
|
||||||
import { role } from "@/config/role";
|
import { role } from "@/config/role";
|
||||||
import path from "path";
|
import path from "path";
|
||||||
|
const os = require("os");
|
||||||
const option: any = {
|
const option: any = {
|
||||||
appId: '',
|
appId: '',
|
||||||
token: '',
|
token: '',
|
||||||
|
|
@ -44,6 +46,7 @@ export const agora = {
|
||||||
rtcEngine = createAgoraRtcEngine();
|
rtcEngine = createAgoraRtcEngine();
|
||||||
await rtcEngine.initialize({
|
await rtcEngine.initialize({
|
||||||
appId: data,
|
appId: data,
|
||||||
|
logConfig: { filePath: path.resolve(os.homedir(), "./agorasdk.log") }
|
||||||
});
|
});
|
||||||
if (bool) {
|
if (bool) {
|
||||||
await agora.setDeviceManager()
|
await agora.setDeviceManager()
|
||||||
|
|
@ -213,6 +216,9 @@ export const agora = {
|
||||||
// 本地加入
|
// 本地加入
|
||||||
setupLocalVideo: async (item: any) => {
|
setupLocalVideo: async (item: any) => {
|
||||||
if (item.view?.childNodes.length === 1 || item.type) {
|
if (item.view?.childNodes.length === 1 || item.type) {
|
||||||
|
if (String(item.uid).length === 9) {
|
||||||
|
return
|
||||||
|
}
|
||||||
await rtcEngine.setupLocalVideo({
|
await rtcEngine.setupLocalVideo({
|
||||||
renderMode: agora.getRrenderMode(item.uid),
|
renderMode: agora.getRrenderMode(item.uid),
|
||||||
sourceType: item.sourceType,
|
sourceType: item.sourceType,
|
||||||
|
|
@ -302,6 +308,7 @@ export const agora = {
|
||||||
publishMicrophoneTrack: true,//设置是否发布麦克风采集到的音频
|
publishMicrophoneTrack: true,//设置是否发布麦克风采集到的音频
|
||||||
publishCameraTrack: true,//设置是否发布摄像头采集的视频
|
publishCameraTrack: true,//设置是否发布摄像头采集的视频
|
||||||
publishScreenTrack: false,//设置是否发布屏幕采集的视频
|
publishScreenTrack: false,//设置是否发布屏幕采集的视频
|
||||||
|
audienceLatencyLevel: bool ? AudienceLatencyLevelType.AudienceLatencyLevelUltraLowLatency : AudienceLatencyLevelType.AudienceLatencyLevelLowLatency,
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
// 设置接收大小流
|
// 设置接收大小流
|
||||||
|
|
@ -342,6 +349,7 @@ export const agora = {
|
||||||
publishMicrophoneTrack: false,//设置是否发布麦克风采集到的音频
|
publishMicrophoneTrack: false,//设置是否发布麦克风采集到的音频
|
||||||
publishCameraTrack: true,//设置是否发布摄像头采集的视频
|
publishCameraTrack: true,//设置是否发布摄像头采集的视频
|
||||||
publishScreenTrack: false,//设置是否发布屏幕采集的视频
|
publishScreenTrack: false,//设置是否发布屏幕采集的视频
|
||||||
|
audienceLatencyLevel: bool ? AudienceLatencyLevelType.AudienceLatencyLevelLowLatency : AudienceLatencyLevelType.AudienceLatencyLevelUltraLowLatency,
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
await rtcEngine.setDualStreamModeEx(
|
await rtcEngine.setDualStreamModeEx(
|
||||||
|
|
@ -365,6 +373,10 @@ export const agora = {
|
||||||
muteRemoteVideoStreamEx: async (uid: number, mute: boolean) => {
|
muteRemoteVideoStreamEx: async (uid: number, mute: boolean) => {
|
||||||
await rtcEngine.muteRemoteVideoStreamEx(uid, mute, { channelId: option.channelId, localUid: Number(option.uid) })
|
await rtcEngine.muteRemoteVideoStreamEx(uid, mute, { channelId: option.channelId, localUid: Number(option.uid) })
|
||||||
},
|
},
|
||||||
|
// 设置视频订阅黑名单。
|
||||||
|
setSubscribeVideoBlocklist: async (uidList: number[], uidNumber: number) => {
|
||||||
|
await rtcEngine.setSubscribeVideoBlocklist(uidList, uidNumber)
|
||||||
|
},
|
||||||
// 取消或恢复订阅指定远端用户的音频流
|
// 取消或恢复订阅指定远端用户的音频流
|
||||||
muteRemoteVideoStream: async (uid: number, mute: boolean) => {
|
muteRemoteVideoStream: async (uid: number, mute: boolean) => {
|
||||||
rtcEngine.muteRemoteVideoStream(uid, mute)
|
rtcEngine.muteRemoteVideoStream(uid, mute)
|
||||||
|
|
@ -396,6 +408,7 @@ export const agora = {
|
||||||
publishMicrophoneTrack: publishMicrophoneTrack,//设置是否发布麦克风采集到的音频
|
publishMicrophoneTrack: publishMicrophoneTrack,//设置是否发布麦克风采集到的音频
|
||||||
publishCameraTrack: publishCameraTrack,//设置是否发布摄像头采集的视频
|
publishCameraTrack: publishCameraTrack,//设置是否发布摄像头采集的视频
|
||||||
publishScreenTrack: false,//设置是否发布屏幕采集的视频
|
publishScreenTrack: false,//设置是否发布屏幕采集的视频
|
||||||
|
audienceLatencyLevel: data ? AudienceLatencyLevelType.AudienceLatencyLevelUltraLowLatency : AudienceLatencyLevelType.AudienceLatencyLevelLowLatency,
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
// 取消或恢复发布本地视频流
|
// 取消或恢复发布本地视频流
|
||||||
|
|
@ -408,6 +421,7 @@ export const agora = {
|
||||||
publishMicrophoneTrack: publishMicrophoneTrack,//设置是否发布麦克风采集到的音频
|
publishMicrophoneTrack: publishMicrophoneTrack,//设置是否发布麦克风采集到的音频
|
||||||
publishCameraTrack: publishCameraTrack,//设置是否发布摄像头采集的视频
|
publishCameraTrack: publishCameraTrack,//设置是否发布摄像头采集的视频
|
||||||
publishScreenTrack: false,//设置是否发布屏幕采集的视频
|
publishScreenTrack: false,//设置是否发布屏幕采集的视频
|
||||||
|
audienceLatencyLevel: data ? AudienceLatencyLevelType.AudienceLatencyLevelUltraLowLatency : AudienceLatencyLevelType.AudienceLatencyLevelLowLatency,
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
// 摄像头采集
|
// 摄像头采集
|
||||||
|
|
|
||||||
|
|
@ -76,7 +76,8 @@ export default defineConfig({
|
||||||
BeautyOptions,
|
BeautyOptions,
|
||||||
ColorEnhanceOptions,
|
ColorEnhanceOptions,
|
||||||
LowlightEnhanceOptions,
|
LowlightEnhanceOptions,
|
||||||
VirtualBackgroundSource
|
VirtualBackgroundSource,
|
||||||
|
AudienceLatencyLevelType
|
||||||
} = require("agora-electron-sdk")
|
} = require("agora-electron-sdk")
|
||||||
export {
|
export {
|
||||||
createAgoraRtcEngine,
|
createAgoraRtcEngine,
|
||||||
|
|
@ -101,7 +102,8 @@ export default defineConfig({
|
||||||
BeautyOptions,
|
BeautyOptions,
|
||||||
ColorEnhanceOptions,
|
ColorEnhanceOptions,
|
||||||
LowlightEnhanceOptions,
|
LowlightEnhanceOptions,
|
||||||
VirtualBackgroundSource
|
VirtualBackgroundSource,
|
||||||
|
AudienceLatencyLevelType
|
||||||
}
|
}
|
||||||
`,
|
`,
|
||||||
})
|
})
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue