// 在 preload 脚本中。 const { ipcRenderer, contextBridge } = require('electron') const { createAgoraRtcEngine, ClientRoleType, VideoSourceType, VideoViewSetupMode, ScreenCaptureSourceType, RenderModeType, ChannelProfileType } = require("agora-electron-sdk"); const agoraAonfig = require('./src/utils/package/agoraConfig'); const { message } = require('antd'); const rtcEngine = createAgoraRtcEngine(); rtcEngine.initialize({ appId: agoraAonfig.appid, }); let videoID = ''; const getDom = () => { return document.getElementById(videoID); } const EventHandles = { // 监听本地用户加入频道事件 onJoinChannelSuccess: ({ channelId, localUid }, elapsed) => { console.log({ channelId, localUid }); // 本地用户加入频道后,设置本地视频窗口 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 }, ); }, // 监听用户离开频道事件 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}%` } } }; rtcEngine.registerEventHandler(EventHandles); contextBridge.exposeInMainWorld( 'electron', { // 桌面捕获音频和视频的媒体源的信息 getDesktopCapturerVideo: async () => { return rtcEngine.getScreenCaptureSources({ width: 300, height: 300 }, { width: 300, height: 300 }, true); }, // 共享屏幕采集 setDesktopCapturerVideo: (targetSource) => { rtcEngine.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, } ); } videoID = `vidoe-${123}-${agoraAonfig.channelId}`; rtcEngine.joinChannelEx(agoraAonfig.token, { channelId: agoraAonfig.channelId, localUid: 123, }, { autoSubscribeAudio: true, //设置是否自动订阅所有音频流 autoSubscribeVideo: true, //设置是否自动订阅所有视频流 publishMicrophoneTrack: false, //设置是否发布麦克风采集到的音频 publishCameraTrack: false, //设置是否发布摄像头采集的视频 clientRoleType: ClientRoleType.ClientRoleBroadcaster, //用户角色 1主播 2观众 publishScreenTrack: true, //设置是否发布屏幕采集的视频 }); }, // 摄像头采集 setCameraCapture: () => { rtcEngine.startCameraCapture(VideoSourceType.VideoSourceCamera, {}) videoID = `vidoe-${123}-${agoraAonfig.channelId}`; rtcEngine.joinChannelEx(agoraAonfig.token, { channelId: agoraAonfig.channelId, localUid: 123, }, { channelProfile: ChannelProfileType.ChannelProfileLiveBroadcasting, //设置频道场景为直播场景 clientRoleType: ClientRoleType.ClientRoleBroadcaster, //设置用户角色为主播;如果要将用户角色设置为观众,保持默认值即可 publishMicrophoneTrack: true, //发布麦克风采集的音频 publishCameraTrack: true, //发布摄像头采集的视频 autoSubscribeAudio: true, //自动订阅所有音频流 autoSubscribeVideo: true, //自动订阅所有视频流 publishScreenTrack: false, //设置是否发布屏幕采集的视频 }); }, // 加入频道 setJoinChannel: () => { videoID = `vidoe-${234}-${agoraAonfig.channelId}`; rtcEngine.joinChannelEx(agoraAonfig.token, { channelId: agoraAonfig.channelId, localUid: 234, }, { autoSubscribeAudio: true, //设置是否自动订阅所有音频流 autoSubscribeVideo: true, //设置是否自动订阅所有视频流 publishMicrophoneTrack: false, //设置是否发布麦克风采集到的音频 publishCameraTrack: false, //设置是否发布摄像头采集的视频 clientRoleType: ClientRoleType.ClientRoleAudience, //用户角色 1主播 2观众 publishScreenTrack: true, //设置是否发布屏幕采集的视频 }); }, // 获取当前生成的视频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) }); }) }, // 设置窗口大小 setMainWindowSize: (config) => { ipcRenderer.invoke('setMainWindowSize', { ...config }) }, // 设置窗口状态 setViewStatus: (status) => { ipcRenderer.invoke('setViewStatus', status) }, // 获取当前是否全屏 getIsMaximized: () => { return ipcRenderer.invoke('getIsMaximized') } } )