下载文件准备

This commit is contained in:
yj 2024-07-10 17:56:56 +08:00
parent 250cb75558
commit 76db877293
14 changed files with 448 additions and 432 deletions

View File

@ -14,6 +14,7 @@
<body>
<div id="root"></div>
<script type="module" src="/src/main.tsx"></script>
<script type="module" src="/src/utils/package/agora.js"></script>
</body>
</html>

View File

@ -8,7 +8,7 @@ class AppWindow extends BrowserWindow {
constructor(config) {
const basicConfig = {
webPreferences: {
contextIsolation: true,
contextIsolation: false,
nodeIntegration: true,
enableRemoteModule: true,
nodeIntegrationInWorker: true,

118
package-lock.json generated
View File

@ -14,9 +14,9 @@
"agora-electron-sdk": "^4.3.2",
"antd": "^5.18.2",
"axios": "^1.7.2",
"crypto-js": "^4.2.0",
"dayjs": "^1.11.11",
"electron-squirrel-startup": "^1.0.1",
"js-md5": "^0.8.3",
"path": "^0.12.7",
"postcss-px-to-viewport-8-plugin": "^1.2.5",
"react": "^18.3.1",
@ -1408,9 +1408,9 @@
}
},
"node_modules/@jridgewell/sourcemap-codec": {
"version": "1.4.15",
"resolved": "https://registry.npmmirror.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz",
"integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==",
"version": "1.5.0",
"resolved": "https://registry.npmmirror.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz",
"integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==",
"dev": true
},
"node_modules/@jridgewell/trace-mapping": {
@ -1446,9 +1446,9 @@
}
},
"node_modules/@microsoft/signalr": {
"version": "8.0.0",
"resolved": "https://registry.npmmirror.com/@microsoft/signalr/-/signalr-8.0.0.tgz",
"integrity": "sha512-K/wS/VmzRWePCGqGh8MU8OWbS1Zvu7DG7LSJS62fBB8rJUXwwj4axQtqrAAwKGUZHQF6CuteuQR9xMsVpM2JNA==",
"version": "8.0.7",
"resolved": "https://registry.npmmirror.com/@microsoft/signalr/-/signalr-8.0.7.tgz",
"integrity": "sha512-PHcdMv8v5hJlBkRHAuKG5trGViQEkPYee36LnJQx4xHOQ5LL4X0nEWIxOp5cCtZ7tu+30quz5V3k0b1YNuc6lw==",
"dependencies": {
"abort-controller": "^3.0.0",
"eventsource": "^2.0.2",
@ -4132,9 +4132,9 @@
}
},
"node_modules/browserslist": {
"version": "4.23.1",
"resolved": "https://registry.npmmirror.com/browserslist/-/browserslist-4.23.1.tgz",
"integrity": "sha512-TUfofFo/KsK/bWZ9TWQ5O26tsWW4Uhmt8IYklbnUa70udB6P2wA7w7o4PY4muaEPBQaAX+CEnmmIA41NVHtPVw==",
"version": "4.23.2",
"resolved": "https://registry.npmmirror.com/browserslist/-/browserslist-4.23.2.tgz",
"integrity": "sha512-qkqSyistMYdxAcw+CzbZwlBy8AGmS/eEWs+sEV5TnLRGDOL+C5M2EnH6tlZyg0YoAxGJAFKh61En9BR941GnHA==",
"dev": true,
"funding": [
{
@ -4151,10 +4151,10 @@
}
],
"dependencies": {
"caniuse-lite": "^1.0.30001629",
"electron-to-chromium": "^1.4.796",
"caniuse-lite": "^1.0.30001640",
"electron-to-chromium": "^1.4.820",
"node-releases": "^2.0.14",
"update-browserslist-db": "^1.0.16"
"update-browserslist-db": "^1.1.0"
},
"bin": {
"browserslist": "cli.js"
@ -4393,9 +4393,9 @@
}
},
"node_modules/caniuse-lite": {
"version": "1.0.30001640",
"resolved": "https://registry.npmmirror.com/caniuse-lite/-/caniuse-lite-1.0.30001640.tgz",
"integrity": "sha512-lA4VMpW0PSUrFnkmVuEKBUovSWKhj7puyCg8StBChgu298N1AtuF1sKWEvfDuimSEDbhlb/KqPKC3fs1HbuQUA==",
"version": "1.0.30001641",
"resolved": "https://registry.npmmirror.com/caniuse-lite/-/caniuse-lite-1.0.30001641.tgz",
"integrity": "sha512-Phv5thgl67bHYo1TtMY/MurjkHhV4EDaCosezRXgZ8jzA/Ub+wjxAvbGvjoFENStinwi5kCyOYV3mi5tOGykwA==",
"dev": true,
"funding": [
{
@ -5024,6 +5024,11 @@
"node": ">=12.10"
}
},
"node_modules/crypto-js": {
"version": "4.2.0",
"resolved": "https://registry.npmmirror.com/crypto-js/-/crypto-js-4.2.0.tgz",
"integrity": "sha512-KALDyEYgpY+Rlob/iriUtjV6d5Eq+Y191A5g4UqLAi8CyGP9N1+FdVbkc1SxKc2r4YAYqG8JzO2KGL+AizD70Q=="
},
"node_modules/csstype": {
"version": "3.1.3",
"resolved": "https://registry.npmmirror.com/csstype/-/csstype-3.1.3.tgz",
@ -6126,9 +6131,9 @@
"integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="
},
"node_modules/electron-to-chromium": {
"version": "1.4.819",
"resolved": "https://registry.npmmirror.com/electron-to-chromium/-/electron-to-chromium-1.4.819.tgz",
"integrity": "sha512-8RwI6gKUokbHWcN3iRij/qpvf/wCbIVY5slODi85werwqUQwpFXM+dvUBND93Qh7SB0pW3Hlq3/wZsqQ3M9Jaw==",
"version": "1.4.823",
"resolved": "https://registry.npmmirror.com/electron-to-chromium/-/electron-to-chromium-1.4.823.tgz",
"integrity": "sha512-4h+oPeAiGQOHFyUJOqpoEcPj/xxlicxBzOErVeYVMMmAiXUXsGpsFd0QXBMaUUbnD8hhSfLf9uw+MlsoIA7j5w==",
"dev": true
},
"node_modules/electron-winstaller": {
@ -8847,11 +8852,6 @@
"node": ">= 4"
}
},
"node_modules/js-md5": {
"version": "0.8.3",
"resolved": "https://registry.npmmirror.com/js-md5/-/js-md5-0.8.3.tgz",
"integrity": "sha512-qR0HB5uP6wCuRMrWPTrkMaev7MJZwJuuw4fnwAzRgP4J4/F8RwtodOKpGp4XpqsLBFzzgqIO42efFAyz2Et6KQ=="
},
"node_modules/js-tokens": {
"version": "4.0.0",
"resolved": "https://registry.npmmirror.com/js-tokens/-/js-tokens-4.0.0.tgz",
@ -11200,9 +11200,9 @@
}
},
"node_modules/rc-picker": {
"version": "4.6.7",
"resolved": "https://registry.npmmirror.com/rc-picker/-/rc-picker-4.6.7.tgz",
"integrity": "sha512-ZntxLH863jdNPZq2i6e2+1iXpRfYKHjNfUGgoObA1YExuWAnTCHpZzOkBuS43GnVcnp2MPDp78pH9OZJFd2hLw==",
"version": "4.6.8",
"resolved": "https://registry.npmmirror.com/rc-picker/-/rc-picker-4.6.8.tgz",
"integrity": "sha512-Lq2m68YGcmWXhzAmxTcL3vOjik7NQjcZ6fmZqBlgdrMCg3VnuKHmtk5CHGWd3wCiy2qNxSYIqWAidB1EQViPpQ==",
"dependencies": {
"@babel/runtime": "^7.24.7",
"@rc-component/trigger": "^2.0.0",
@ -12311,9 +12311,9 @@
"optional": true
},
"node_modules/sass": {
"version": "1.77.6",
"resolved": "https://registry.npmmirror.com/sass/-/sass-1.77.6.tgz",
"integrity": "sha512-ByXE1oLD79GVq9Ht1PeHWCPMPB8XHpBuz1r85oByKHjZY6qV6rWnQovQzXJXuQ/XyE1Oj3iPk3lo28uzaRA2/Q==",
"version": "1.77.7",
"resolved": "https://registry.npmmirror.com/sass/-/sass-1.77.7.tgz",
"integrity": "sha512-9ywH75cO+rLjbrZ6en3Gp8qAMwPGBapFtlsMJoDTkcMU/bSe5a6cjKVUn5Jr4Gzg5GbP3HE8cm+02pLCgcoMow==",
"dependencies": {
"chokidar": ">=3.0.0 <4.0.0",
"immutable": "^4.0.0",
@ -15660,9 +15660,9 @@
"dev": true
},
"@jridgewell/sourcemap-codec": {
"version": "1.4.15",
"resolved": "https://registry.npmmirror.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz",
"integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==",
"version": "1.5.0",
"resolved": "https://registry.npmmirror.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz",
"integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==",
"dev": true
},
"@jridgewell/trace-mapping": {
@ -15685,9 +15685,9 @@
}
},
"@microsoft/signalr": {
"version": "8.0.0",
"resolved": "https://registry.npmmirror.com/@microsoft/signalr/-/signalr-8.0.0.tgz",
"integrity": "sha512-K/wS/VmzRWePCGqGh8MU8OWbS1Zvu7DG7LSJS62fBB8rJUXwwj4axQtqrAAwKGUZHQF6CuteuQR9xMsVpM2JNA==",
"version": "8.0.7",
"resolved": "https://registry.npmmirror.com/@microsoft/signalr/-/signalr-8.0.7.tgz",
"integrity": "sha512-PHcdMv8v5hJlBkRHAuKG5trGViQEkPYee36LnJQx4xHOQ5LL4X0nEWIxOp5cCtZ7tu+30quz5V3k0b1YNuc6lw==",
"requires": {
"abort-controller": "^3.0.0",
"eventsource": "^2.0.2",
@ -17419,15 +17419,15 @@
}
},
"browserslist": {
"version": "4.23.1",
"resolved": "https://registry.npmmirror.com/browserslist/-/browserslist-4.23.1.tgz",
"integrity": "sha512-TUfofFo/KsK/bWZ9TWQ5O26tsWW4Uhmt8IYklbnUa70udB6P2wA7w7o4PY4muaEPBQaAX+CEnmmIA41NVHtPVw==",
"version": "4.23.2",
"resolved": "https://registry.npmmirror.com/browserslist/-/browserslist-4.23.2.tgz",
"integrity": "sha512-qkqSyistMYdxAcw+CzbZwlBy8AGmS/eEWs+sEV5TnLRGDOL+C5M2EnH6tlZyg0YoAxGJAFKh61En9BR941GnHA==",
"dev": true,
"requires": {
"caniuse-lite": "^1.0.30001629",
"electron-to-chromium": "^1.4.796",
"caniuse-lite": "^1.0.30001640",
"electron-to-chromium": "^1.4.820",
"node-releases": "^2.0.14",
"update-browserslist-db": "^1.0.16"
"update-browserslist-db": "^1.1.0"
}
},
"buffer": {
@ -17604,9 +17604,9 @@
"integrity": "sha512-4nhGqUkc4BqbBBB4Q6zLuD7lzzrHYrjKGeYaEji/3tFR5VdJu9v+LilhGIVe8wxEJPPOeWo7eg8dwY13TZ1BNg=="
},
"caniuse-lite": {
"version": "1.0.30001640",
"resolved": "https://registry.npmmirror.com/caniuse-lite/-/caniuse-lite-1.0.30001640.tgz",
"integrity": "sha512-lA4VMpW0PSUrFnkmVuEKBUovSWKhj7puyCg8StBChgu298N1AtuF1sKWEvfDuimSEDbhlb/KqPKC3fs1HbuQUA==",
"version": "1.0.30001641",
"resolved": "https://registry.npmmirror.com/caniuse-lite/-/caniuse-lite-1.0.30001641.tgz",
"integrity": "sha512-Phv5thgl67bHYo1TtMY/MurjkHhV4EDaCosezRXgZ8jzA/Ub+wjxAvbGvjoFENStinwi5kCyOYV3mi5tOGykwA==",
"dev": true
},
"canvas-size": {
@ -18073,6 +18073,11 @@
"integrity": "sha512-n63i0lZ0rvQ6FXiGQ+/JFCKAUyPFhLQYJIqKaa+tSJtfKeULF/IDNDAbdnSIxgS4NTuw2b0+lj8LzfITuq+ZxQ==",
"dev": true
},
"crypto-js": {
"version": "4.2.0",
"resolved": "https://registry.npmmirror.com/crypto-js/-/crypto-js-4.2.0.tgz",
"integrity": "sha512-KALDyEYgpY+Rlob/iriUtjV6d5Eq+Y191A5g4UqLAi8CyGP9N1+FdVbkc1SxKc2r4YAYqG8JzO2KGL+AizD70Q=="
},
"csstype": {
"version": "3.1.3",
"resolved": "https://registry.npmmirror.com/csstype/-/csstype-3.1.3.tgz",
@ -18973,9 +18978,9 @@
}
},
"electron-to-chromium": {
"version": "1.4.819",
"resolved": "https://registry.npmmirror.com/electron-to-chromium/-/electron-to-chromium-1.4.819.tgz",
"integrity": "sha512-8RwI6gKUokbHWcN3iRij/qpvf/wCbIVY5slODi85werwqUQwpFXM+dvUBND93Qh7SB0pW3Hlq3/wZsqQ3M9Jaw==",
"version": "1.4.823",
"resolved": "https://registry.npmmirror.com/electron-to-chromium/-/electron-to-chromium-1.4.823.tgz",
"integrity": "sha512-4h+oPeAiGQOHFyUJOqpoEcPj/xxlicxBzOErVeYVMMmAiXUXsGpsFd0QXBMaUUbnD8hhSfLf9uw+MlsoIA7j5w==",
"dev": true
},
"electron-winstaller": {
@ -20916,11 +20921,6 @@
"is-object": "^1.0.1"
}
},
"js-md5": {
"version": "0.8.3",
"resolved": "https://registry.npmmirror.com/js-md5/-/js-md5-0.8.3.tgz",
"integrity": "sha512-qR0HB5uP6wCuRMrWPTrkMaev7MJZwJuuw4fnwAzRgP4J4/F8RwtodOKpGp4XpqsLBFzzgqIO42efFAyz2Et6KQ=="
},
"js-tokens": {
"version": "4.0.0",
"resolved": "https://registry.npmmirror.com/js-tokens/-/js-tokens-4.0.0.tgz",
@ -22669,9 +22669,9 @@
}
},
"rc-picker": {
"version": "4.6.7",
"resolved": "https://registry.npmmirror.com/rc-picker/-/rc-picker-4.6.7.tgz",
"integrity": "sha512-ZntxLH863jdNPZq2i6e2+1iXpRfYKHjNfUGgoObA1YExuWAnTCHpZzOkBuS43GnVcnp2MPDp78pH9OZJFd2hLw==",
"version": "4.6.8",
"resolved": "https://registry.npmmirror.com/rc-picker/-/rc-picker-4.6.8.tgz",
"integrity": "sha512-Lq2m68YGcmWXhzAmxTcL3vOjik7NQjcZ6fmZqBlgdrMCg3VnuKHmtk5CHGWd3wCiy2qNxSYIqWAidB1EQViPpQ==",
"requires": {
"@babel/runtime": "^7.24.7",
"@rc-component/trigger": "^2.0.0",
@ -23430,9 +23430,9 @@
"optional": true
},
"sass": {
"version": "1.77.6",
"resolved": "https://registry.npmmirror.com/sass/-/sass-1.77.6.tgz",
"integrity": "sha512-ByXE1oLD79GVq9Ht1PeHWCPMPB8XHpBuz1r85oByKHjZY6qV6rWnQovQzXJXuQ/XyE1Oj3iPk3lo28uzaRA2/Q==",
"version": "1.77.7",
"resolved": "https://registry.npmmirror.com/sass/-/sass-1.77.7.tgz",
"integrity": "sha512-9ywH75cO+rLjbrZ6en3Gp8qAMwPGBapFtlsMJoDTkcMU/bSe5a6cjKVUn5Jr4Gzg5GbP3HE8cm+02pLCgcoMow==",
"requires": {
"chokidar": ">=3.0.0 <4.0.0",
"immutable": "^4.0.0",

View File

@ -31,9 +31,9 @@
"agora-electron-sdk": "^4.3.2",
"antd": "^5.18.2",
"axios": "^1.7.2",
"crypto-js": "^4.2.0",
"dayjs": "^1.11.11",
"electron-squirrel-startup": "^1.0.1",
"js-md5": "^0.8.3",
"path": "^0.12.7",
"postcss-px-to-viewport-8-plugin": "^1.2.5",
"react": "^18.3.1",

View File

@ -1,321 +1,24 @@
// 在 preload 脚本中。
const { ipcRenderer, contextBridge } = require('electron')
const {
createAgoraRtcEngine,
ClientRoleType,
VideoSourceType,
VideoViewSetupMode,
ScreenCaptureSourceType,
RenderModeType,
ChannelProfileType,
MediaRecorderContainerFormat,
MediaRecorderStreamType
} = require("agora-electron-sdk");
const { message } = require('antd');
const rtcEngine = createAgoraRtcEngine();
const option = {
appId: 'dcfc466a6ecb4a1f972630065dfb1e75',
token: '',
channelId: '',
userid: '',
}
rtcEngine.initialize({
appId: option.appId,
});
let videoID = '';
let iMediaRecorder = '';
const getDom = () => {
return document.getElementById('video-1');
}
// 离开频道
const leaveChannel = () => {
rtcEngine.leaveChannel({
stopAudioMixing: true,
stopAllEffect: true,
stopMicrophoneRecording: true,
})
}
// 离开频道
const joinChannel = (bool) => {
if (bool) {
rtcEngine.joinChannel(option.token, option.channelId, option.userid, {
channelProfile: ChannelProfileType.ChannelProfileLiveBroadcasting, //设置频道场景为直播场景
clientRoleType: ClientRoleType.ClientRoleBroadcaster, //用户角色 1主播 2观众
publishMicrophoneTrack: true, //设置是否发布麦克风采集到的音频
publishCameraTrack: false, //设置是否发布摄像头采集的视频
publishScreenTrack: true, //设置是否发布屏幕采集的视频
autoSubscribeAudio: true, //设置是否自动订阅所有音频流
autoSubscribeVideo: true, //设置是否自动订阅所有视频流
});
} else {
rtcEngine.joinChannel(option.token, option.channelId, option.userid, {
channelProfile: ChannelProfileType.ChannelProfileLiveBroadcasting, //设置频道场景为直播场景
clientRoleType: ClientRoleType.ClientRoleBroadcaster, //设置用户角色为主播;如果要将用户角色设置为观众,保持默认值即可
publishMicrophoneTrack: true, //发布麦克风采集的音频
publishCameraTrack: true, //发布摄像头采集的视频
publishScreenTrack: false, //设置是否发布屏幕采集的视频
autoSubscribeAudio: true, //自动订阅所有音频流
autoSubscribeVideo: true, //自动订阅所有视频流
});
// // 在 preload 脚本中。
const { ipcRenderer } = require('electron')
window.electron = {
// 设置窗口大小
setMainWindowSize: (config) => {
ipcRenderer.invoke('setMainWindowSize', { ...config })
},
// 设置窗口状态
setViewStatus: (status) => {
ipcRenderer.invoke('setViewStatus', status)
},
// 获取当前是否全屏
getIsMaximized: () => {
return ipcRenderer.invoke('getIsMaximized')
},
// 复制文字
setWriteText: (text) => {
return ipcRenderer.invoke('setWriteText', text)
},
// 下载文件并放置选择的文件夹
dwFile: (url) => {
ipcRenderer.invoke('dwFile', url)
}
}
// 停止共享屏幕
const stopScreenCapture = () => {
rtcEngine.stopScreenCapture();
}
rtcEngine.registerEventHandler({
// 监听本地用户加入频道事件
onJoinChannelSuccess: ({ channelId, localUid }, elapsed) => {
console.log({ channelId, localUid }, elapsed, '加入房间');
// 本地用户加入频道后,设置本地视频窗口
rtcEngine.setupLocalVideo({
renderMode: RenderModeType.RenderModeFit,
// sourceType: VideoSourceType.VideoSourceScreen,
sourceType: VideoSourceType.VideoSourceCameraPrimary,
uid: localUid,
view: getDom(),
setupMode: VideoViewSetupMode.VideoViewSetupAdd,
});
},
// 监听远端用户加入频道事件
onUserJoined: ({ channelId, localUid }, remoteUid, elapsed) => {
// 远端用户加入频道后,设置远端视频窗口
rtcEngine.setupRemoteVideo(
{
renderMode: RenderModeType.RenderModeFit,
sourceType: VideoSourceType.VideoSourceRemote,
uid: remoteUid,
view: getDom(),
setupMode: VideoViewSetupMode.VideoViewSetupAdd,
},
{ channelId },
);
},
// 视频发布状态改变回调
onVideoPublishStateChanged: (source, channel, oldState, newState, elapseSinceLastState) => {
if (newState === 1) {
}
},
// 音频发布状态改变回调
onAudioPublishStateChanged: (channel, oldState, newState, elapseSinceLastState) => {
if (newState === 1) {
}
},
// 监听用户离开频道事件
onUserOffline: ({ channelId, localUid }, remoteUid, reason) => {
// 远端用户离开频道后,关闭远端视频窗口
rtcEngine.setupRemoteVideo(
{
renderMode: RenderModeType.RenderModeFit,
sourceType: VideoSourceType.VideoSourceRemote,
uid: remoteUid,
view: getDom(),
setupMode: VideoViewSetupMode.VideoViewSetupRemove,
},
);
},
// 用户音量提示回调。
onAudioVolumeIndication: (connection, speakers, speakerNumber, totalVolume) => {
const percentage = (totalVolume / 255) * 100
if (document.getElementById('recordingDeviceTest')) {
document.getElementById('recordingDeviceTest').style.width = `${percentage}%`
}
}
});
contextBridge.exposeInMainWorld(
'electron',
{
// 桌面捕获音频和视频的媒体源的信息
getDesktopCapturerVideo: async () => {
return rtcEngine.getScreenCaptureSources({ width: 300, height: 300 }, { width: 300, height: 300 }, true);
},
// 共享屏幕采集
setDesktopCapturerVideo: (targetSource) => {
stopScreenCapture()
if (
targetSource.type ===
ScreenCaptureSourceType.ScreencapturesourcetypeScreen
) {
rtcEngine.startScreenCaptureByDisplayId(
targetSource.sourceId,
{},
{
windowFocus: true,
enableHighLight: true,
highLightColor: 0xFF99CC00,
}
);
} else {
rtcEngine.startScreenCaptureByWindowId(
targetSource.sourceId,
{},
{
windowFocus: true,
enableHighLight: true,
highLightColor: 0xFF99CC00,
}
);
}
joinChannel(true)
},
// 摄像头采集
setCameraCapture: () => {
rtcEngine.startCameraCapture(VideoSourceType.VideoSourceCamera, {})
joinChannel(false)
},
// 加入频道
setJoinChannel: (data) => {
option.token = data.token;
option.channelId = data.channelId;
option.userid = Number(data.userid);
rtcEngine.startCameraCapture(VideoSourceType.VideoSourceCamera, {})
joinChannel(false)
},
// 离开频道
leaveChannel: () => {
leaveChannel()
},
// 停止共享屏幕
stopScreenCapture: () => {
stopScreenCapture()
},
// 取消或恢复发布本地音频流
muteLocalAudioStream: (mute) => {
rtcEngine.muteLocalAudioStream(mute)
},
// 取消或恢复发布本地视频流
muteLocalVideoStream: (mute) => {
rtcEngine.muteLocalVideoStream(mute)
},
// 获取当前生成的视频id
getVideoId: () => {
return videoID;
},
// 获取音频设备列表
getAudioMediaList: () => {
return {
currentDevice: rtcEngine.getAudioDeviceManager().getRecordingDefaultDevice(),
currentDevices: rtcEngine.getAudioDeviceManager().enumerateRecordingDevices(),
currentVolume: rtcEngine.getAudioDeviceManager().getRecordingDeviceVolume()
}
},
// 设置音频设备音量
setRecordingDeviceVolume: (volume) => {
rtcEngine.getAudioDeviceManager().setRecordingDeviceVolume(volume)
},
// 设置音频采集设备
setRecordingDevice: (deviceId) => {
rtcEngine.getAudioDeviceManager().setRecordingDevice(deviceId)
},
// 启动音频采集设备测试
startRecordingDeviceTest: (indicationInterval) => {
rtcEngine.getAudioDeviceManager().startRecordingDeviceTest(indicationInterval)
navigator.mediaDevices.getUserMedia({ audio: true })
.then((stream) => {
let dom = document.getElementById('startAudio');
dom.srcObject = stream;
dom.play()
})
.catch((error) => {
message.error('无法获取麦克风!');
});
},
// 停止音频设备回路测试
stopAudioDeviceLoopbackTest: () => {
rtcEngine.getAudioDeviceManager().stopAudioDeviceLoopbackTest()
rtcEngine.getAudioDeviceManager().stopRecordingDeviceTest()
let video = document.getElementById('startPreview');
if (video.srcObject) {
const tracks = video.srcObject.getTracks();
tracks.forEach((track) => {
track.stop();
});
video.srcObject = null;
}
let audio = document.getElementById('startAudio');
if (audio.srcObject) {
const tracks = audio.srcObject.getTracks();
tracks.forEach((track) => {
track.stop();
});
audio.srcObject = null;
}
},
// 开启本地视频预览
startPreview: async () => {
return new Promise((resolve, reject) => {
navigator.mediaDevices.getUserMedia({
video: true,
audio: true,
}).then((stream) => {
let dom = document.getElementById('startPreview');
dom.srcObject = stream;
dom.play()
resolve(true)
}).catch((error) => {
message.error('无法获取摄像头!');
resolve(true)
});
})
},
// 开始录制音视频
startRecording: () => {
iMediaRecorder = rtcEngine.createMediaRecorder({
channelId: option.channelId,
uid: 123,
})
iMediaRecorder.setMediaRecorderObserver({
// 录制状态发生改变回调。
onRecorderStateChanged: (channelId, uid, state, reason) => {
console.log(channelId, uid, state, reason, '录制状态发生改变回调。');
},
// 录制信息更新回调。
onRecorderInfoUpdated: (channelId, uid, info) => {
console.log(channelId, uid, info, '录制信息更新回调。');
},
})
iMediaRecorder.startRecording({
storagePath: `D:/word/${+new Date()}.mp4`, //录音文件在本地保存的绝对路径,需精确到文件名及格式
containerFormat: MediaRecorderContainerFormat.FormatMp4, //录制文件的格式
streamType: MediaRecorderStreamType.StreamTypeBoth, //录制内容
maxDurationMs: 7200000, //maxDurationMs
})
},
// 停止录制音视频
stopRecording: () => {
iMediaRecorder.stopRecording()
rtcEngine.destroyMediaRecorder(iMediaRecorder)
iMediaRecorder = ""
},
// 设置窗口大小
setMainWindowSize: (config) => {
ipcRenderer.invoke('setMainWindowSize', { ...config })
},
// 设置窗口状态
setViewStatus: (status) => {
ipcRenderer.invoke('setViewStatus', status)
},
// 获取当前是否全屏
getIsMaximized: () => {
return ipcRenderer.invoke('getIsMaximized')
},
// 复制文字
setWriteText: (text) => {
return ipcRenderer.invoke('setWriteText', text)
},
// 下载文件并放置选择的文件夹
dwFile: (url) => {
ipcRenderer.invoke('dwFile', url)
},
}
)

View File

@ -24,3 +24,9 @@ export const GetRoomRtcToken = (roomNum: string) =>
method: 'get',
})
export const GetRoomInfo = (roomNum: string) =>
request({
url: `/room/${roomNum}`,
method: 'get',
})

View File

@ -26,9 +26,9 @@ export const GetRoomUpFileurl = (roomNum: string, fileSuffix: string) =>
method: 'get'
})
export const GetRoomFileDwUrl = (fileUrl: string) =>
export const GetRoomFileDwUrl = (fileUrl: string, fileId: string) =>
request({
url: `/room/file-dw-url?fileUrl=${fileUrl}`,
url: `/room/file-dw-url?fileUrl=${fileUrl}&fileId=${fileId}`,
method: 'get'
})

View File

@ -3,7 +3,7 @@ import { useEffect, useState } from "react";
import Operation from '@/components/Operation';
import { useNavigate } from 'react-router-dom';
import { Button, Input, Modal, Pagination, Empty, message } from "antd";
import { GetRoom, PostRomm, GetCheckoutRoomNum, GetRoomRtcToken } from '@/api/Home/Index';
import { GetRoom, PostRomm, GetCheckoutRoomNum, GetRoomRtcToken, GetRoomInfo } from '@/api/Home/Index';
const Index: React.FC = () => {
const navigate = useNavigate();
const [list, setList] = useState({
@ -119,7 +119,8 @@ const Index: React.FC = () => {
navigate(`/meeting`, {
state: {
channelId: item.roomNum,
token: res
token: res,
roomId: item.id
}
})
}
@ -249,12 +250,18 @@ const Index: React.FC = () => {
}
isGetCheckoutRoomNum(joinRoomFrom, (bool: boolean) => {
if (bool) {
getRoomRtcToken(joinRoomFrom, (res: any) => {
if (res) {
navigate(`/meeting`, {
state: {
channelId: joinRoomFrom,
token: res
getRoomRtcToken(joinRoomFrom, (token: string) => {
if (token) {
setJoinRoomModal(false)
GetRoomInfo(joinRoomFrom).then(res => {
if (res.code === 200) {
navigate(`/meeting`, {
state: {
channelId: joinRoomFrom,
token,
roomId: res.data.id
}
})
}
})
}

View File

@ -4,7 +4,7 @@ import Operation from '@/components/Operation';
import { Button, Input, Table, Pagination, Modal, message, Select } from "antd";
import { SearchOutlined } from '@ant-design/icons';
import { GetUserList, PostUser, PutUser, DeleteUser, PutUserPwd, GetRoleDpList } from '@/api/Home/User';
import { md5 } from 'js-md5';
import * as CryptoJS from 'crypto-js';
const { Column } = Table
const User: React.FC = () => {
const [selectedRowKeys, setSelectedRowKeys] = useState<React.Key[]>([]);
@ -288,7 +288,7 @@ const User: React.FC = () => {
if (isCreateUser) {
await PostUser({
...addUserFrom,
Pwd: md5(addUserFrom.Pwd)
Pwd: CryptoJS.MD5(addUserFrom.Pwd).toString(CryptoJS.enc.Hex)
}).then(res => {
if (res.code === 200) {
setAddUserModal(false)
@ -356,7 +356,8 @@ const User: React.FC = () => {
if (changeUserPawFrom.Pwd !== changeUserPawFrom.newPwd) {
return message.error('新密码与确认密码不一致!')
}
await PutUserPwd({ id: addUserFrom.Id, pwd: md5(changeUserPawFrom.Pwd) }).then(res => {
await PutUserPwd({ id: addUserFrom.Id, pwd: CryptoJS.MD5(changeUserPawFrom.Pwd).toString(CryptoJS.enc.Hex) }).then(res => {
if (res.code === 200) {
setChangeUserPawModal(false)
message.success('修改成功')

View File

@ -5,7 +5,7 @@ import { useNavigate } from 'react-router-dom';
import { Input, Button, Checkbox, message } from "antd"
import { storage } from '@/utils'
import { GetCheckUser, PostLogin } from '@/api/Login'
import { md5 } from 'js-md5';
import * as CryptoJS from 'crypto-js';
import { startSignalr } from '@/utils/package/signalr'
const Login: React.FC = () => {
const navigate = useNavigate();
@ -102,7 +102,7 @@ const Login: React.FC = () => {
const loginClick = (): void => {
PostLogin({
account: operation.account,
pwd: md5(operation.password)
pwd: CryptoJS.MD5(operation.password).toString(CryptoJS.enc.Hex)
}).then(res => {
if (res.code === 200) {
message.success('登录成功!')
@ -118,8 +118,8 @@ const Login: React.FC = () => {
width: 1200,
height: 800,
})
startSignalr()
navigate('/home')
startSignalr()
}
})
}

View File

@ -114,7 +114,7 @@ const Meeting: React.FC = () => {
useEffect(() => {
if (isInit) {
setUser(JSON.parse(storage.getItem('user') as string))
// window.electron.setJoinChannel({
// window.agora.setJoinChannel({
// channelId: state.channelId,
// userid: user.userName,
// token: state.token,
@ -149,49 +149,49 @@ const Meeting: React.FC = () => {
setIsSharedScreenModal(true)
break;
case '停止共享':
window.electron.stopScreenCapture()
window.agora.stopScreenCapture()
footerListTemplate[itemIndex][rowIndex].title = '共享屏幕'
break;
case '关闭声音':
footerListTemplate[itemIndex][rowIndex].title = '开启声音'
footerListTemplate[itemIndex][rowIndex].active = true
setFooterList(footerListTemplate)
window.electron.muteLocalAudioStream(true)
window.agora.muteLocalAudioStream(true)
break;
case '开启声音':
footerListTemplate[itemIndex][rowIndex].title = '关闭声音'
footerListTemplate[itemIndex][rowIndex].active = false
setFooterList(footerListTemplate)
window.electron.muteLocalAudioStream(false)
window.agora.muteLocalAudioStream(false)
break;
case '关闭视频':
footerListTemplate[itemIndex][rowIndex].title = '开启视频'
footerListTemplate[itemIndex][rowIndex].active = true
setFooterList(footerListTemplate)
window.electron.muteLocalVideoStream(true)
window.agora.muteLocalVideoStream(true)
break;
case '开启视频':
footerListTemplate[itemIndex][rowIndex].title = '关闭视频'
footerListTemplate[itemIndex][rowIndex].active = false
setFooterList(footerListTemplate)
window.electron.muteLocalVideoStream(false)
window.agora.muteLocalVideoStream(false)
break;
case '设置向导':
getAudioMediaList()
window.electron.startRecordingDeviceTest(200)
window.agora.startRecordingDeviceTest(200)
setIsStupWizard(true)
break;
case '录制':
footerListTemplate[itemIndex][rowIndex].title = '录制中'
footerListTemplate[itemIndex][rowIndex].active = true
setFooterList(footerListTemplate)
window.electron.startRecording()
window.agora.startRecording()
break;
case '录制中':
footerListTemplate[itemIndex][rowIndex].title = '录制'
footerListTemplate[itemIndex][rowIndex].active = false
setFooterList(footerListTemplate)
window.electron.stopRecording()
window.agora.stopRecording()
break;
case '共享文件':
await getRoomFile()
@ -209,8 +209,8 @@ const Meeting: React.FC = () => {
const footerListTemplate = [...footerList]
footerListTemplate[footerListIndex.itemIndex][footerListIndex.rowIndex].title = '停止共享'
setIsSharedScreenModal(false)
window.electron.setDesktopCapturerVideo(sharedScreenItem)
setVideoID(window.electron.getVideoId())
window.agora.setDesktopCapturerVideo(sharedScreenItem)
setVideoID(window.agora.getVideoId())
} else {
message.error('请选择应用!')
}
@ -218,7 +218,7 @@ const Meeting: React.FC = () => {
}
const getDesktopCapturerVideo = (): void => {
window.electron.getDesktopCapturerVideo().then((res: any) => {
window.agora.getDesktopCapturerVideo().then((res: any) => {
if (sharedScreenList.length !== res.length) {
res.forEach((item: any) => {
if (item.thumbImage.buffer) {
@ -234,7 +234,7 @@ const Meeting: React.FC = () => {
};
const getAudioMediaList = (): void => {
const { currentDevices, currentDevice, currentVolume } = window.electron.getAudioMediaList();
const { currentDevices, currentDevice, currentVolume } = window.agora.getAudioMediaList();
setAudioDeviceManager({
currentDevices: currentDevices.map((row: any) => {
return {
@ -252,7 +252,7 @@ const Meeting: React.FC = () => {
pageIndex: fileList.pageIndex,
pageSize: fileList.pageSize,
keyword: fileList.keyword,
roomId: state.channelId
roomId: state.roomId
}).then(res => {
if (res.code === 200) {
setFileList({
@ -400,13 +400,13 @@ const Meeting: React.FC = () => {
content={
<div className='meetingContentFooterPopover'>
<div onClick={() => {
window.electron.leaveChannel()
window.electron.stopScreenCapture()
window.agora.leaveChannel()
window.agora.stopScreenCapture()
navigate(-1)
}}></div>
<div onClick={() => {
window.electron.leaveChannel()
window.electron.stopScreenCapture()
window.agora.leaveChannel()
window.agora.stopScreenCapture()
navigate(-1)
}}></div>
<div onClick={() => { setOpen(false) }}></div>
@ -477,7 +477,7 @@ const Meeting: React.FC = () => {
...audioDeviceManager,
currentDevice: e
})
window.electron.setRecordingDevice(e);
window.agora.setRecordingDevice(e);
getAudioMediaList()
}} />;
<audio src="" id='startAudio'></audio>
@ -489,7 +489,7 @@ const Meeting: React.FC = () => {
...audioDeviceManager,
currentVolume: e
})
window.electron.setRecordingDeviceVolume(e)
window.agora.setRecordingDeviceVolume(e)
}} style={{ flexGrow: 1 }} />
</div> :
<div>
@ -526,7 +526,7 @@ const Meeting: React.FC = () => {
audio.srcObject = null;
}
setStepsStatus(false)
window.electron.startPreview().then((res: boolean) => {
window.agora.startPreview().then((res: boolean) => {
setIsVideoLoad(res)
})
}}></Button>
@ -538,9 +538,9 @@ const Meeting: React.FC = () => {
onClick={() => {
if (isVideoLoad) {
setIsVideoLoad(false)
window.electron.stopAudioDeviceLoopbackTest()
window.agora.stopAudioDeviceLoopbackTest()
setStepsStatus(true)
window.electron.startRecordingDeviceTest(200)
window.agora.startRecordingDeviceTest(200)
} else {
message.error('视频加载中!')
}
@ -551,8 +551,8 @@ const Meeting: React.FC = () => {
className='m-ant-btn'
onClick={() => {
if (isVideoLoad) {
window.electron.stopAudioDeviceLoopbackTest()
window.electron.setRecordingDeviceVolume(audioDeviceManager.currentVolume)
window.agora.stopAudioDeviceLoopbackTest()
window.agora.setRecordingDeviceVolume(audioDeviceManager.currentVolume)
setIsStupWizard(false)
setStepsStatus(true)
setIsVideoLoad(false)
@ -654,7 +654,7 @@ const Meeting: React.FC = () => {
fileUrl: res.data.key,
size: fileInfo.size,
fileName: fileInfo.name,
roomId: state.channelId
roomId: state.roomId
})
getRoomFile()
})
@ -696,7 +696,7 @@ const Meeting: React.FC = () => {
<Column title="操作" render={(item) => (
<>
<VerticalAlignBottomOutlined title='下载' style={{ color: '#5575F2', cursor: 'pointer' }} onClick={() => {
GetRoomFileDwUrl(item.fileUrl).then(res => {
GetRoomFileDwUrl(item.fileUrl, item.id).then(res => {
if (res.code === 200) {
window.electron.dwFile(res.data)
}

14
src/render.d.ts vendored
View File

@ -1,14 +1,18 @@
// electron-env.d.ts
export interface IElectronAPI {
setMainWindowSize: (config: any) => void;
setViewStatus: (status: 'quit' | 'maximize' | 'minimize' | 'unmaximize') => void;
getIsMaximized: () => Promise<boolean>;
setWriteText: (text: string) => void;
dwFile: (url: string) => void;
}
export interface Agora {
getDesktopCapturerVideo: () => Promise<void>;
setDesktopCapturerVideo: (data: any) => void;
setCameraCapture: (data: any) => void;
getAudioMediaList: () => { currentDevice: any, currentDevices: any, currentVolume: number };
setRecordingDeviceVolume: (volume: number) => void;
setRecordingDevice: (deviceId: string) => void;
setMainWindowSize: (config: any) => void;
getIsMaximized: () => Promise<boolean>;
setViewStatus: (status: 'quit' | 'maximize' | 'minimize' | 'unmaximize') => void;
setJoinChannel: (data: { channelId: string, userid: string, token: string }) => Promise<void>;
getVideoId: () => string;
startRecordingDeviceTest: (indicationInterval: number) => void;
@ -20,12 +24,10 @@ export interface IElectronAPI {
stopScreenCapture: () => void;
muteLocalAudioStream: (mute: boolean) => void;
muteLocalVideoStream: (mute: boolean) => void;
setWriteText: (text: string) => void;
dwFile: (url: string) => void;
}
declare global {
interface Window {
electron: IElectronAPI;
agora: Agora
}
}

View File

@ -1 +1,2 @@
declare module 'react-dom/client';
declare module 'crypto-js';

295
src/utils/package/agora.js Normal file
View File

@ -0,0 +1,295 @@
const {
createAgoraRtcEngine,
ClientRoleType,
VideoSourceType,
VideoViewSetupMode,
ScreenCaptureSourceType,
RenderModeType,
ChannelProfileType,
MediaRecorderContainerFormat,
MediaRecorderStreamType
} = require("agora-electron-sdk");
const { message } = require('antd');
const rtcEngine = createAgoraRtcEngine();
const option = {
appId: 'dcfc466a6ecb4a1f972630065dfb1e75',
token: '',
channelId: '',
userid: '',
}
rtcEngine.initialize({
appId: option.appId,
});
rtcEngine.registerEventHandler({
// 监听本地用户加入频道事件
onJoinChannelSuccess: ({ channelId, localUid }, elapsed) => {
console.log({ channelId, localUid }, elapsed, '加入房间');
// 本地用户加入频道后,设置本地视频窗口
rtcEngine.setupLocalVideo({
renderMode: RenderModeType.RenderModeFit,
// sourceType: VideoSourceType.VideoSourceScreen,
sourceType: VideoSourceType.VideoSourceCameraPrimary,
uid: localUid,
view: getDom(),
setupMode: VideoViewSetupMode.VideoViewSetupAdd,
});
},
// 监听远端用户加入频道事件
onUserJoined: ({ channelId, localUid }, remoteUid, elapsed) => {
// 远端用户加入频道后,设置远端视频窗口
rtcEngine.setupRemoteVideo(
{
renderMode: RenderModeType.RenderModeFit,
sourceType: VideoSourceType.VideoSourceRemote,
uid: remoteUid,
view: getDom(),
setupMode: VideoViewSetupMode.VideoViewSetupAdd,
},
{ channelId },
);
},
// 视频发布状态改变回调
onVideoPublishStateChanged: (source, channel, oldState, newState, elapseSinceLastState) => {
if (newState === 1) {
}
},
// 音频发布状态改变回调
onAudioPublishStateChanged: (channel, oldState, newState, elapseSinceLastState) => {
if (newState === 1) {
}
},
// 监听用户离开频道事件
onUserOffline: ({ channelId, localUid }, remoteUid, reason) => {
// 远端用户离开频道后,关闭远端视频窗口
rtcEngine.setupRemoteVideo(
{
renderMode: RenderModeType.RenderModeFit,
sourceType: VideoSourceType.VideoSourceRemote,
uid: remoteUid,
view: getDom(),
setupMode: VideoViewSetupMode.VideoViewSetupRemove,
},
);
},
// 用户音量提示回调。
onAudioVolumeIndication: (connection, speakers, speakerNumber, totalVolume) => {
const percentage = (totalVolume / 255) * 100
if (document.getElementById('recordingDeviceTest')) {
document.getElementById('recordingDeviceTest').style.width = `${percentage}%`
}
}
});
let videoID = '';
let iMediaRecorder = '';
const agora = {
getDom: () => {
return document.getElementById('video-1');
},
// 离开频道
leaveChannel: () => {
rtcEngine.leaveChannel({
stopAudioMixing: true,
stopAllEffect: true,
stopMicrophoneRecording: true,
})
},
// 加入频道
joinChannel: (bool) => {
if (bool) {
rtcEngine.joinChannel(option.token, option.channelId, option.userid, {
channelProfile: ChannelProfileType.ChannelProfileLiveBroadcasting, //设置频道场景为直播场景
clientRoleType: ClientRoleType.ClientRoleBroadcaster, //用户角色 1主播 2观众
publishMicrophoneTrack: true, //设置是否发布麦克风采集到的音频
publishCameraTrack: false, //设置是否发布摄像头采集的视频
publishScreenTrack: true, //设置是否发布屏幕采集的视频
autoSubscribeAudio: true, //设置是否自动订阅所有音频流
autoSubscribeVideo: true, //设置是否自动订阅所有视频流
});
} else {
rtcEngine.joinChannel(option.token, option.channelId, option.userid, {
channelProfile: ChannelProfileType.ChannelProfileLiveBroadcasting, //设置频道场景为直播场景
clientRoleType: ClientRoleType.ClientRoleBroadcaster, //设置用户角色为主播;如果要将用户角色设置为观众,保持默认值即可
publishMicrophoneTrack: true, //发布麦克风采集的音频
publishCameraTrack: true, //发布摄像头采集的视频
publishScreenTrack: false, //设置是否发布屏幕采集的视频
autoSubscribeAudio: true, //自动订阅所有音频流
autoSubscribeVideo: true, //自动订阅所有视频流
});
}
},
// 停止录制音视频
stopRecording: () => {
iMediaRecorder.stopRecording()
rtcEngine.destroyMediaRecorder(iMediaRecorder)
iMediaRecorder = ""
},
// 开始录制音视频
startRecording: () => {
iMediaRecorder = rtcEngine.createMediaRecorder({
channelId: option.channelId,
uid: 123,
})
iMediaRecorder.setMediaRecorderObserver({
// 录制状态发生改变回调。
onRecorderStateChanged: (channelId, uid, state, reason) => {
console.log(channelId, uid, state, reason, '录制状态发生改变回调。');
},
// 录制信息更新回调。
onRecorderInfoUpdated: (channelId, uid, info) => {
console.log(channelId, uid, info, '录制信息更新回调。');
},
})
iMediaRecorder.startRecording({
storagePath: `D:/word/${+new Date()}.mp4`, //录音文件在本地保存的绝对路径,需精确到文件名及格式
containerFormat: MediaRecorderContainerFormat.FormatMp4, //录制文件的格式
streamType: MediaRecorderStreamType.StreamTypeBoth, //录制内容
maxDurationMs: 7200000, //maxDurationMs
})
},
// 停止共享屏幕
stopScreenCapture: () => {
rtcEngine.stopScreenCapture();
},
// 开启本地视频预览
startPreview: async () => {
return new Promise((resolve, reject) => {
navigator.mediaDevices.getUserMedia({
video: true,
audio: true,
}).then((stream) => {
let dom = document.getElementById('startPreview');
dom.srcObject = stream;
dom.play()
resolve(true)
}).catch((error) => {
message.error('无法获取摄像头!');
resolve(true)
});
})
},
// 停止音频设备回路测试
stopAudioDeviceLoopbackTest: () => {
rtcEngine.getAudioDeviceManager().stopAudioDeviceLoopbackTest()
rtcEngine.getAudioDeviceManager().stopRecordingDeviceTest()
let video = document.getElementById('startPreview');
if (video.srcObject) {
const tracks = video.srcObject.getTracks();
tracks.forEach((track) => {
track.stop();
});
video.srcObject = null;
}
let audio = document.getElementById('startAudio');
if (audio.srcObject) {
const tracks = audio.srcObject.getTracks();
tracks.forEach((track) => {
track.stop();
});
audio.srcObject = null;
}
},
// 启动音频采集设备测试
startRecordingDeviceTest: (indicationInterval) => {
rtcEngine.getAudioDeviceManager().startRecordingDeviceTest(indicationInterval)
navigator.mediaDevices.getUserMedia({ audio: true })
.then((stream) => {
let dom = document.getElementById('startAudio');
dom.srcObject = stream;
dom.play()
})
.catch((error) => {
message.error('无法获取麦克风!');
});
},
// 获取音频设备列表
getAudioMediaList: () => {
return {
currentDevice: rtcEngine.getAudioDeviceManager().getRecordingDefaultDevice(),
currentDevices: rtcEngine.getAudioDeviceManager().enumerateRecordingDevices(),
currentVolume: rtcEngine.getAudioDeviceManager().getRecordingDeviceVolume()
}
},
// 设置音频设备音量
setRecordingDeviceVolume: (volume) => {
rtcEngine.getAudioDeviceManager().setRecordingDeviceVolume(volume)
},
// 设置音频采集设备
setRecordingDevice: (deviceId) => {
rtcEngine.getAudioDeviceManager().setRecordingDevice(deviceId)
},
// 摄像头采集
setCameraCapture: () => {
rtcEngine.startCameraCapture(VideoSourceType.VideoSourceCamera, {})
// joinChannel(false)
},
// 加入频道
setJoinChannel: (data) => {
option.token = data.token;
option.channelId = data.channelId;
option.userid = Number(data.userid);
rtcEngine.startCameraCapture(VideoSourceType.VideoSourceCamera, {})
// joinChannel(false)
},
// 离开频道
leaveChannel: () => {
// leaveChannel()
},
// 停止共享屏幕
stopScreenCapture: () => {
// stopScreenCapture()
},
// 取消或恢复发布本地音频流
muteLocalAudioStream: (mute) => {
rtcEngine.muteLocalAudioStream(mute)
},
// 取消或恢复发布本地视频流
muteLocalVideoStream: (mute) => {
rtcEngine.muteLocalVideoStream(mute)
},
// 获取当前生成的视频id
getVideoId: () => {
return videoID;
},
// 桌面捕获音频和视频的媒体源的信息
getDesktopCapturerVideo: async () => {
return rtcEngine.getScreenCaptureSources({ width: 300, height: 300 }, { width: 300, height: 300 }, true);
},
// 共享屏幕采集
setDesktopCapturerVideo: (targetSource) => {
// stopScreenCapture()
if (
targetSource.type ===
ScreenCaptureSourceType.ScreencapturesourcetypeScreen
) {
rtcEngine.startScreenCaptureByDisplayId(
targetSource.sourceId,
{},
{
windowFocus: true,
enableHighLight: true,
highLightColor: 0xFF99CC00,
}
);
} else {
rtcEngine.startScreenCaptureByWindowId(
targetSource.sourceId,
{},
{
windowFocus: true,
enableHighLight: true,
highLightColor: 0xFF99CC00,
}
);
}
// joinChannel(true)
},
}
window.agora = agora;