WGShare.Client.Electron/src/utils/package/agora.ts

369 lines
12 KiB
TypeScript

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<boolean> => {
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;