This commit is contained in:
parent
459d5c1a49
commit
998f7f781a
|
|
@ -74,11 +74,11 @@ const Meeting: React.FC = () => {
|
||||||
iconActive: ImageUrl.icon27Active,
|
iconActive: ImageUrl.icon27Active,
|
||||||
active: false,
|
active: false,
|
||||||
},
|
},
|
||||||
{
|
// {
|
||||||
title: '设置向导',
|
// title: '设置向导',
|
||||||
icon: ImageUrl.icon28,
|
// icon: ImageUrl.icon28,
|
||||||
active: false,
|
// active: false,
|
||||||
},
|
// },
|
||||||
{
|
{
|
||||||
title: '结束',
|
title: '结束',
|
||||||
icon: ImageUrl.icon29,
|
icon: ImageUrl.icon29,
|
||||||
|
|
@ -182,7 +182,6 @@ const Meeting: React.FC = () => {
|
||||||
uid: userInfo.uid,
|
uid: userInfo.uid,
|
||||||
token: state.token,
|
token: state.token,
|
||||||
})
|
})
|
||||||
setCurrentVideoId(userInfo.uid)
|
|
||||||
storage.setItem('noViewChatList', 0)
|
storage.setItem('noViewChatList', 0)
|
||||||
window.addEventListener('customStorageChange', handleCustomStorageChange);
|
window.addEventListener('customStorageChange', handleCustomStorageChange);
|
||||||
window.addEventListener('online', handleNetworkChange);
|
window.addEventListener('online', handleNetworkChange);
|
||||||
|
|
@ -304,6 +303,7 @@ const Meeting: React.FC = () => {
|
||||||
if (String(res.data).length === 9) {
|
if (String(res.data).length === 9) {
|
||||||
// 共享屏幕
|
// 共享屏幕
|
||||||
setCurrentLookUserStatus(2)
|
setCurrentLookUserStatus(2)
|
||||||
|
setCurrentVideoId('2')
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
agora.setupLocalVideo({
|
agora.setupLocalVideo({
|
||||||
uid: Number(res.data),
|
uid: Number(res.data),
|
||||||
|
|
@ -314,6 +314,7 @@ const Meeting: React.FC = () => {
|
||||||
}, 1000);
|
}, 1000);
|
||||||
} else {
|
} else {
|
||||||
setCurrentLookUserStatus(1)
|
setCurrentLookUserStatus(1)
|
||||||
|
setCurrentVideoId('1')
|
||||||
// 摄像头
|
// 摄像头
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
agora.setupLocalVideo({
|
agora.setupLocalVideo({
|
||||||
|
|
@ -328,6 +329,7 @@ const Meeting: React.FC = () => {
|
||||||
if (String(res.data).length === 9) {
|
if (String(res.data).length === 9) {
|
||||||
// 摄像头
|
// 摄像头
|
||||||
setCurrentLookUserStatus(3)
|
setCurrentLookUserStatus(3)
|
||||||
|
setCurrentVideoId('3')
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
agora.setupRemoteVideoJoin({
|
agora.setupRemoteVideoJoin({
|
||||||
uid: Number(res.data),
|
uid: Number(res.data),
|
||||||
|
|
@ -338,6 +340,7 @@ const Meeting: React.FC = () => {
|
||||||
} else {
|
} else {
|
||||||
// 共享屏幕
|
// 共享屏幕
|
||||||
setCurrentLookUserStatus(4)
|
setCurrentLookUserStatus(4)
|
||||||
|
setCurrentVideoId('4')
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
agora.setupRemoteVideoJoin({
|
agora.setupRemoteVideoJoin({
|
||||||
uid: Number(res.data),
|
uid: Number(res.data),
|
||||||
|
|
@ -425,22 +428,18 @@ const Meeting: React.FC = () => {
|
||||||
break;
|
break;
|
||||||
case '录制':
|
case '录制':
|
||||||
const setting = await JSON.parse(storage.getItem('setting') as string)
|
const setting = await JSON.parse(storage.getItem('setting') as string)
|
||||||
if (currentVideoId === user.uid) {
|
try {
|
||||||
message.error('请勿自己录制自己!')
|
await fs.access(setting.recordingFilesPath, fs.constants.F_OK)
|
||||||
} else {
|
footerListTemplate[itemIndex][rowIndex].title = '录制中'
|
||||||
try {
|
footerListTemplate[itemIndex][rowIndex].active = true
|
||||||
await fs.access(setting.recordingFilesPath, fs.constants.F_OK)
|
setFooterList(footerListTemplate)
|
||||||
footerListTemplate[itemIndex][rowIndex].title = '录制中'
|
// setting.recordingFilesPath
|
||||||
footerListTemplate[itemIndex][rowIndex].active = true
|
} catch (error: any) {
|
||||||
setFooterList(footerListTemplate)
|
if (error.code === 'ENOENT') {
|
||||||
agora.startRecording(Number(currentVideoId))
|
message.error('文件夹不存在!')
|
||||||
} catch (error: any) {
|
return
|
||||||
if (error.code === 'ENOENT') {
|
} else {
|
||||||
message.error('文件夹不存在!')
|
message.error(error)
|
||||||
return
|
|
||||||
} else {
|
|
||||||
message.error(error)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
@ -448,7 +447,6 @@ const Meeting: React.FC = () => {
|
||||||
footerListTemplate[itemIndex][rowIndex].title = '录制'
|
footerListTemplate[itemIndex][rowIndex].title = '录制'
|
||||||
footerListTemplate[itemIndex][rowIndex].active = false
|
footerListTemplate[itemIndex][rowIndex].active = false
|
||||||
setFooterList(footerListTemplate)
|
setFooterList(footerListTemplate)
|
||||||
agora.stopRecording()
|
|
||||||
break;
|
break;
|
||||||
case '共享文件':
|
case '共享文件':
|
||||||
sharedFilesModelRef.current.getData()
|
sharedFilesModelRef.current.getData()
|
||||||
|
|
@ -639,8 +637,8 @@ const Meeting: React.FC = () => {
|
||||||
return ''
|
return ''
|
||||||
}
|
}
|
||||||
// 设置单个视频样式
|
// 设置单个视频样式
|
||||||
const setMeetingContentSwiperCardClass = (uid: string, bool: boolean = false): string => {
|
const setMeetingContentSwiperCardClass = (uid: string): string => {
|
||||||
if ((bool || currentVideoId === uid) && (meetingMode === 'StandardMode' || meetingMode === 'SpeakerMode')) {
|
if ((currentVideoId === uid) && (meetingMode === 'StandardMode' || meetingMode === 'SpeakerMode')) {
|
||||||
switch (meetingMode) {
|
switch (meetingMode) {
|
||||||
case 'StandardMode':
|
case 'StandardMode':
|
||||||
return styles.meetingContentSwiperCardStandardMode
|
return styles.meetingContentSwiperCardStandardMode
|
||||||
|
|
@ -690,17 +688,13 @@ const Meeting: React.FC = () => {
|
||||||
<div className={styles.meetingContentBody}>
|
<div className={styles.meetingContentBody}>
|
||||||
<div className={`${styles.meetingContentBodyLeft} drag`}>
|
<div className={`${styles.meetingContentBodyLeft} drag`}>
|
||||||
<div className={getMeetingContentBodyLeftModeClass()} >
|
<div className={getMeetingContentBodyLeftModeClass()} >
|
||||||
{/* ${setMeetingContentSwiperCardClass(item.uid)} */}
|
|
||||||
{allUserList.map((item: any, index: number) => {
|
{allUserList.map((item: any, index: number) => {
|
||||||
return (
|
return (
|
||||||
item.isRoom ?
|
item.isRoom ?
|
||||||
<div
|
<div
|
||||||
className={`${styles.meetingContentSwiperCard}`}
|
className={`${styles.meetingContentSwiperCard} ${setMeetingContentSwiperCardClass(item.uid)}`}
|
||||||
key={index}
|
key={index}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
if (footerList[1][3].active) {
|
|
||||||
return message.error('视频录制中请勿切换,或结束录制再切换!')
|
|
||||||
}
|
|
||||||
setCurrentVideoId(item.uid)
|
setCurrentVideoId(item.uid)
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
|
|
@ -715,42 +709,46 @@ const Meeting: React.FC = () => {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
)}
|
)}
|
||||||
{currentLookUserStatus === 1 ? <div className={`${styles.meetingContentSwiperCard} ${setMeetingContentSwiperCardClass(currentLookUserAccount.uid, true)}`}>
|
{currentLookUserStatus === 1 ?
|
||||||
<div className={`${styles.meetingContentSwiperCardVdeio}`} id='video-source-camera-primary'>
|
<div className={`${styles.meetingContentSwiperCard} ${setMeetingContentSwiperCardClass('1')}`} onClick={() => setCurrentVideoId('1')}>
|
||||||
{<div className={styles.meetingContentSwiperCardVdeioLoading}>
|
<div className={`${styles.meetingContentSwiperCardVdeio}`} id='video-source-camera-primary'>
|
||||||
<Avatar name={currentLookUserAccount.userName} />
|
{<div className={styles.meetingContentSwiperCardVdeioLoading}>
|
||||||
</div>}
|
<Avatar name={currentLookUserAccount.userName} />
|
||||||
</div>
|
</div>}
|
||||||
{meetingContentUser(currentLookUserAccount)}
|
|
||||||
{currentLookUserAccount.enableCamera ? null : meetingContentError(currentVideoId, currentLookUserAccount)}
|
|
||||||
</div> : null}
|
|
||||||
{currentLookUserStatus === 2 ? <div className={`${styles.meetingContentSwiperCard} ${setMeetingContentSwiperCardClass(currentLookUserAccount.uid, true)}`}>
|
|
||||||
<div className={`${styles.meetingContentSwiperCardVdeio}`} id='video-source-screen'>
|
|
||||||
<div className={styles.meetingContentSwiperCardVdeioLoading}>
|
|
||||||
<Avatar name={currentLookUserAccount.userName} />
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
{meetingContentUser(currentLookUserAccount)}
|
||||||
{meetingContentUser(currentLookUserAccount)}
|
{currentLookUserAccount.enableCamera ? null : meetingContentError(currentVideoId, currentLookUserAccount)}
|
||||||
{currentLookUserAccount.enableCamera ? null : meetingContentError(currentVideoId, currentLookUserAccount)}
|
</div> : null}
|
||||||
</div> : null}
|
{currentLookUserStatus === 2 ?
|
||||||
{currentLookUserStatus === 3 ? <div className={`${styles.meetingContentSwiperCard} ${setMeetingContentSwiperCardClass(currentLookUserAccount.uid, true)}`}>
|
<div className={`${styles.meetingContentSwiperCard} ${setMeetingContentSwiperCardClass('2')}`} onClick={() => setCurrentVideoId('2')}>
|
||||||
<div className={`${styles.meetingContentSwiperCardVdeio}`} id='video-source-remote-camera'>
|
<div className={`${styles.meetingContentSwiperCardVdeio}`} id='video-source-screen'>
|
||||||
<div className={styles.meetingContentSwiperCardVdeioLoading}>
|
<div className={styles.meetingContentSwiperCardVdeioLoading}>
|
||||||
<Avatar name={currentLookUserAccount.userName} />
|
<Avatar name={currentLookUserAccount.userName} />
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
{meetingContentUser(currentLookUserAccount)}
|
||||||
{meetingContentUser(currentLookUserAccount)}
|
{currentLookUserAccount.enableCamera ? null : meetingContentError(currentVideoId, currentLookUserAccount)}
|
||||||
{currentLookUserAccount.enableCamera ? null : meetingContentError(currentVideoId, currentLookUserAccount)}
|
</div> : null}
|
||||||
</div> : null}
|
{currentLookUserStatus === 3 ?
|
||||||
{currentLookUserStatus === 4 ? <div className={`${styles.meetingContentSwiperCard} ${setMeetingContentSwiperCardClass(currentLookUserAccount.uid, true)}`}>
|
<div className={`${styles.meetingContentSwiperCard} ${setMeetingContentSwiperCardClass('3')}`} onClick={() => setCurrentVideoId('3')}>
|
||||||
<div className={`${styles.meetingContentSwiperCardVdeio}`} id='video-source-remote-screen'>
|
<div className={`${styles.meetingContentSwiperCardVdeio}`} id='video-source-remote-camera'>
|
||||||
<div className={styles.meetingContentSwiperCardVdeioLoading}>
|
<div className={styles.meetingContentSwiperCardVdeioLoading}>
|
||||||
<Avatar name={currentLookUserAccount.userName} />
|
<Avatar name={currentLookUserAccount.userName} />
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
{meetingContentUser(currentLookUserAccount)}
|
||||||
{meetingContentUser(currentLookUserAccount)}
|
{currentLookUserAccount.enableCamera ? null : meetingContentError(currentVideoId, currentLookUserAccount)}
|
||||||
{currentLookUserAccount.enableCamera ? null : meetingContentError(currentVideoId, currentLookUserAccount)}
|
</div> : null}
|
||||||
</div> : null}
|
{currentLookUserStatus === 4 ?
|
||||||
|
<div className={`${styles.meetingContentSwiperCard} ${setMeetingContentSwiperCardClass('4')}`} onClick={() => setCurrentVideoId('4')}>
|
||||||
|
<div className={`${styles.meetingContentSwiperCardVdeio}`} id='video-source-remote-screen'>
|
||||||
|
<div className={styles.meetingContentSwiperCardVdeioLoading}>
|
||||||
|
<Avatar name={currentLookUserAccount.userName} />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{meetingContentUser(currentLookUserAccount)}
|
||||||
|
{currentLookUserAccount.enableCamera ? null : meetingContentError(currentVideoId, currentLookUserAccount)}
|
||||||
|
</div> : null}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,3 @@
|
||||||
import { message } from "antd";
|
|
||||||
import {
|
import {
|
||||||
createAgoraRtcEngine,
|
createAgoraRtcEngine,
|
||||||
ClientRoleType,
|
ClientRoleType,
|
||||||
|
|
@ -6,9 +5,7 @@ import {
|
||||||
VideoViewSetupMode,
|
VideoViewSetupMode,
|
||||||
ScreenCaptureSourceType,
|
ScreenCaptureSourceType,
|
||||||
RenderModeType,
|
RenderModeType,
|
||||||
ChannelProfileType,
|
ChannelProfileType
|
||||||
MediaRecorderContainerFormat,
|
|
||||||
MediaRecorderStreamType
|
|
||||||
} from "agora-electron-sdk";
|
} from "agora-electron-sdk";
|
||||||
import { GetRoomRtcToken } from "@/api/Home/Index";
|
import { GetRoomRtcToken } from "@/api/Home/Index";
|
||||||
import { storage } from '@/utils';
|
import { storage } from '@/utils';
|
||||||
|
|
@ -18,7 +15,6 @@ const option: any = {
|
||||||
channelId: '',
|
channelId: '',
|
||||||
uid: ''
|
uid: ''
|
||||||
}
|
}
|
||||||
let iMediaRecorder: any = '';
|
|
||||||
let rtcEngine: any = '';
|
let rtcEngine: any = '';
|
||||||
|
|
||||||
const agora = {
|
const agora = {
|
||||||
|
|
@ -228,46 +224,6 @@ const agora = {
|
||||||
}
|
}
|
||||||
await agora.joinChannelEx(user.screenShareId)
|
await agora.joinChannelEx(user.screenShareId)
|
||||||
},
|
},
|
||||||
// 停止录制音视频
|
|
||||||
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}`)
|
|
||||||
},
|
|
||||||
})
|
|
||||||
const setting = JSON.parse(storage.getItem('setting') as string)
|
|
||||||
iMediaRecorder.startRecording({
|
|
||||||
storagePath: `${setting.recordingFilesPath}${+new Date()}.mp4`, //录音文件在本地保存的绝对路径,需精确到文件名及格式
|
|
||||||
containerFormat: MediaRecorderContainerFormat.FormatMp4, //录制文件的格式
|
|
||||||
streamType: MediaRecorderStreamType.StreamTypeBoth, //录制内容
|
|
||||||
maxDurationMs: 7200000, //maxDurationMs
|
|
||||||
})
|
|
||||||
},
|
|
||||||
// 获取系统中所有的视频设备列表。
|
// 获取系统中所有的视频设备列表。
|
||||||
getVideoDeviceManager: async (): Promise<any> => {
|
getVideoDeviceManager: async (): Promise<any> => {
|
||||||
return {
|
return {
|
||||||
|
|
|
||||||
|
|
@ -57,8 +57,6 @@ export default defineConfig({
|
||||||
createAgoraRtcEngine,
|
createAgoraRtcEngine,
|
||||||
ChannelProfileType,
|
ChannelProfileType,
|
||||||
ClientRoleType,
|
ClientRoleType,
|
||||||
MediaRecorderContainerFormat,
|
|
||||||
MediaRecorderStreamType,
|
|
||||||
RenderModeType,
|
RenderModeType,
|
||||||
ScreenCaptureSourceType,
|
ScreenCaptureSourceType,
|
||||||
VideoSourceType,
|
VideoSourceType,
|
||||||
|
|
@ -68,8 +66,6 @@ export default defineConfig({
|
||||||
createAgoraRtcEngine,
|
createAgoraRtcEngine,
|
||||||
ChannelProfileType,
|
ChannelProfileType,
|
||||||
ClientRoleType,
|
ClientRoleType,
|
||||||
MediaRecorderContainerFormat,
|
|
||||||
MediaRecorderStreamType,
|
|
||||||
RenderModeType,
|
RenderModeType,
|
||||||
ScreenCaptureSourceType,
|
ScreenCaptureSourceType,
|
||||||
VideoSourceType,
|
VideoSourceType,
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue