import { message } from "antd"; const os = require('os'); import storage from "./storage"; import { createAgoraRtcEngine, ClientRoleType, VideoSourceType, VideoViewSetupMode, ScreenCaptureSourceType, RenderModeType, ChannelProfileType, MediaRecorderContainerFormat, MediaRecorderStreamType } from "agora-electron-sdk"; const option: any = { appId: 'dcfc466a6ecb4a1f972630065dfb1e75', token: '', channelId: '', userid: '', sourceType: VideoSourceType.VideoSourceCameraPrimary, } let iMediaRecorder: any = ''; let rtcEngine: any = ''; const agora = { // 初始化 init: () => { rtcEngine = createAgoraRtcEngine(); rtcEngine.initialize({ appId: option.appId, }); rtcEngine.registerEventHandler({ // 监听本地用户加入频道事件 onJoinChannelSuccess: async (info: any, elapsed: any) => { storage.setItem('isJoin', true) }, // 监听远端用户加入频道事件 onUserJoined: (info: any, remoteUid: any, elapsed: any) => { storage.setItem('isRemotJoin', true) }, // 监听用户离开频道事件 onUserOffline: async (info: any, remoteUid: any, reason: any) => { // 远端用户离开频道后,关闭远端视频窗口 await rtcEngine.setupRemoteVideo( { renderMode: RenderModeType.RenderModeFit, sourceType: VideoSourceType.VideoSourceRemote, uid: Number(info.localUid), view: document.getElementById(`video-${remoteUid}`), setupMode: VideoViewSetupMode.VideoViewSetupRemove, }, ); storage.setItem('isRemotJoin', false) }, // 视频发布状态改变回调 onVideoPublishStateChanged: (source: any, channel: any, oldState: any, newState: any, elapseSinceLastState: any) => { if (newState === 1) { } }, // 音频发布状态改变回调 onAudioPublishStateChanged: (channel: any, oldState: any, newState: any, elapseSinceLastState: any) => { if (newState === 1) { } }, // 用户音量提示回调。 onAudioVolumeIndication: (connection: any, speakers: any, speakerNumber: any, totalVolume: any,) => { const percentage = (totalVolume / 255) * 100 const dom = document.getElementById('recordingDeviceTest') as any; if (dom) { dom.style.width = `${percentage}%` } } }); }, // 本地加入 setupLocalVideo: (item: any) => { rtcEngine.setupLocalVideo({ renderMode: RenderModeType.RenderModeFit, sourceType: option.sourceType, uid: item.account, view: item.view, setupMode: VideoViewSetupMode.VideoViewSetupAdd, }); switch (option.sourceType) { case VideoSourceType.VideoSourceCameraPrimary: agora.updateChannelMediaOptions(true) break; case VideoSourceType.VideoSourceScreen: agora.updateChannelMediaOptions(false) break; } }, // 远端加入 setupRemoteVideoJoin: (item: any) => { rtcEngine.setupRemoteVideo( { renderMode: RenderModeType.RenderModeFit, sourceType: VideoSourceType.VideoSourceRemote, uid: item.account, view: item.view, setupMode: VideoViewSetupMode.VideoViewSetupAdd, }, { channelId: item.channelId }, ); }, // 渲染视频 setVideo: (item: any) => { if (option.userid === item.account) { agora.setupLocalVideo(item) } else { agora.setupRemoteVideoJoin(item) } }, // 离开频道 leaveChannel: () => { rtcEngine.leaveChannel({ stopAudioMixing: true, stopAllEffect: true, stopMicrophoneRecording: true, }) rtcEngine.release() storage.setItem('isJoin', false) }, // 加入频道 joinChannel: () => { rtcEngine.joinChannel(option.token, option.channelId, option.userid, {}); }, // 更新频道信息 updateChannelMediaOptions: (bool: boolean) => { if (bool) { // 摄像头 rtcEngine.updateChannelMediaOptions({ channelProfile: ChannelProfileType.ChannelProfileLiveBroadcasting, //设置频道场景为直播场景 clientRoleType: ClientRoleType.ClientRoleBroadcaster, //设置用户角色为主播;如果要将用户角色设置为观众,保持默认值即可 publishMicrophoneTrack: true, //发布麦克风采集的音频 publishCameraTrack: true, //发布摄像头采集的视频 publishScreenTrack: false, //设置是否发布屏幕采集的视频 autoSubscribeAudio: true, //自动订阅所有音频流 autoSubscribeVideo: true, //自动订阅所有视频流 }) } else { // 屏幕 rtcEngine.updateChannelMediaOptions({ channelProfile: ChannelProfileType.ChannelProfileLiveBroadcasting, //设置频道场景为直播场景 clientRoleType: ClientRoleType.ClientRoleBroadcaster, //用户角色 1主播 2观众 publishMicrophoneTrack: true, //设置是否发布麦克风采集到的音频 publishCameraTrack: false, //设置是否发布摄像头采集的视频 publishScreenTrack: true, //设置是否发布屏幕采集的视频 autoSubscribeAudio: true, //设置是否自动订阅所有音频流 autoSubscribeVideo: true, //设置是否自动订阅所有视频流 }) } }, // 停止共享屏幕 stopScreenCapture: () => { rtcEngine.stopScreenCapture(); }, // 取消或恢复发布本地音频流 muteLocalAudioStream: (mute: any) => { rtcEngine.muteLocalAudioStream(mute) }, // 取消或恢复发布本地视频流 muteLocalVideoStream: (mute: any) => { rtcEngine.muteLocalVideoStream(mute) }, // 摄像头采集 setCameraCapture: (sourceType: number) => { agora.stopScreenCapture() if (sourceType !== option.sourceType) { rtcEngine.destroyRendererByConfig(option.sourceType, option.channelId, option.account) option.sourceType = sourceType agora.setupLocalVideo({ account: Number(option.userid), view: document.getElementById(`video-${option.userid}`), channelId: option.channelId, }) } rtcEngine.startCameraCapture(VideoSourceType.VideoSourceCamera, {}) }, // 加入频道 setJoinChannel: async (data: any) => { option.token = data.token; option.channelId = data.channelId; option.userid = Number(data.userid); agora.joinChannel() }, // 桌面捕获音频和视频的媒体源的信息 getDesktopCapturerVideo: async () => { return rtcEngine.getScreenCaptureSources({ width: 300, height: 300 }, { width: 300, height: 300 }, true); }, // 共享屏幕采集 setDesktopCapturerVideo: async (targetSource: any, sourceType: number) => { if (sourceType !== option.sourceType) { await rtcEngine.stopCameraCapture(option.sourceType) rtcEngine.destroyRendererByConfig(option.sourceType, option.channelId, option.account) option.sourceType = sourceType agora.setupLocalVideo({ account: Number(option.userid), view: document.getElementById(`video-${option.userid}`), channelId: option.channelId, }) } agora.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, } ); } }, // 停止录制音视频 stopRecording: () => { iMediaRecorder.stopRecording() rtcEngine.destroyMediaRecorder(iMediaRecorder) iMediaRecorder = "" }, // 开始录制音视频 startRecording: (uid: number) => { iMediaRecorder = rtcEngine.createMediaRecorder({ channelId: option.channelId, uid, }) iMediaRecorder.setMediaRecorderObserver({ // 录制状态发生改变回调。 onRecorderStateChanged: (channelId: any, uid: any, state: any, reason: any) => { switch (reason) { case 1: message.error('录制文件写入失败') break; case 2: message.error('没有可录制的音视频流或者录制的音视频流中断超过 5 秒') break; case 3: message.error('录制时长超出上限') break; } }, // 录制信息更新回调。 onRecorderInfoUpdated: (channelId: any, uid: any, info: any) => { message.success(`文件已保存至${info.fileName}`) }, }) iMediaRecorder.startRecording({ storagePath: `${os.homedir()}/Desktop/${+new Date()}.mp4`, //录音文件在本地保存的绝对路径,需精确到文件名及格式 containerFormat: MediaRecorderContainerFormat.FormatMp4, //录制文件的格式 streamType: MediaRecorderStreamType.StreamTypeBoth, //录制内容 maxDurationMs: 7200000, //maxDurationMs }) }, // 开启本地视频预览 startPreview: async (): Promise => { return new Promise((resolve, reject) => { navigator.mediaDevices.getUserMedia({ video: true, audio: true, }).then((stream) => { let dom = document.getElementById('startPreview') as any; 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') as any; if (video.srcObject) { const tracks = video.srcObject.getTracks(); tracks.forEach((track: any) => { track.stop(); }); video.srcObject = null; } let audio = document.getElementById('startAudio') as any; if (audio.srcObject) { const tracks = audio.srcObject.getTracks(); tracks.forEach((track: any) => { track.stop(); }); audio.srcObject = null; } }, // 启动音频采集设备测试 startRecordingDeviceTest: (indicationInterval: number) => { rtcEngine.getAudioDeviceManager().startRecordingDeviceTest(indicationInterval) navigator.mediaDevices.getUserMedia({ audio: true }) .then((stream) => { let dom = document.getElementById('startAudio') as any; dom.srcObject = stream; dom.play() }) .catch((error) => { message.error('无法获取麦克风!'); }); }, // 获取音频设备列表 getAudioMediaList: (bool: boolean) => { if (bool) { return { currentDevices: rtcEngine.getAudioDeviceManager().enumeratePlaybackDevices(), currentDevice: rtcEngine.getAudioDeviceManager().getPlaybackDefaultDevice(), currentVolume: 100, } } else { return { currentDevices: rtcEngine.getAudioDeviceManager().enumerateRecordingDevices(), currentDevice: rtcEngine.getAudioDeviceManager().getRecordingDefaultDevice(), currentVolume: rtcEngine.getAudioDeviceManager().getRecordingDeviceVolume() } } }, // 设置音频设备音量 setRecordingDeviceVolume: (volume: number) => { rtcEngine.getAudioDeviceManager().setRecordingDeviceVolume(volume) }, // 设置音频采集设备 setRecordingDevice: (deviceId: string) => { rtcEngine.getAudioDeviceManager().setRecordingDevice(deviceId) }, // 启动音频播放设备测试。 startPlaybackDeviceTest: () => { rtcEngine.getAudioDeviceManager().startPlaybackDeviceTest('https://wgshare.oss-cn-chengdu.aliyuncs.com/TestAudio.mp3') }, // 停止音频播放设备测试。 stopPlaybackDeviceTest: () => { rtcEngine.getAudioDeviceManager().stopPlaybackDeviceTest() }, // 设置播放设备音量 setPlaybackDeviceVolume: (volume: number) => { rtcEngine.getAudioDeviceManager().setPlaybackDeviceVolume(volume) }, // 指定播放设备 setPlaybackDevice: (deviceId: string) => { rtcEngine.getAudioDeviceManager().setPlaybackDevice(deviceId) }, } export default agora;