Compare commits
5 Commits
72e0c1b101
...
7f1c7722ec
| Author | SHA1 | Date |
|---|---|---|
|
|
7f1c7722ec | |
|
|
ef932fd3a8 | |
|
|
a913c6520b | |
|
|
5c7d0d7649 | |
|
|
a5d755ffc8 |
|
|
@ -68,7 +68,11 @@ const JoinSetting = forwardRef((_props: any, ref: any) => {
|
|||
await GetCheckoutRoomNum(roomNum).then(res => {
|
||||
if (res.code === 200) {
|
||||
callBack(res.data)
|
||||
} else {
|
||||
storage.setItem('loading', false)
|
||||
}
|
||||
}).catch(() => {
|
||||
storage.setItem('loading', false)
|
||||
})
|
||||
}
|
||||
const getRoomRtcToken = async (roomNum: string, callBack: Function): Promise<void> => {
|
||||
|
|
@ -78,7 +82,11 @@ const JoinSetting = forwardRef((_props: any, ref: any) => {
|
|||
token: res[0].data,
|
||||
tokenA: res[1].data,
|
||||
})
|
||||
} else {
|
||||
storage.setItem('loading', false)
|
||||
}
|
||||
}).catch(() => {
|
||||
storage.setItem('loading', false)
|
||||
})
|
||||
}
|
||||
const postRefresh = async (callBack: Function): Promise<void> => {
|
||||
|
|
@ -87,7 +95,11 @@ const JoinSetting = forwardRef((_props: any, ref: any) => {
|
|||
storage.setItem('user', JSON.stringify(res.data))
|
||||
storage.setItem('userLogin', true)
|
||||
callBack(res.data)
|
||||
} else {
|
||||
storage.setItem('loading', false)
|
||||
}
|
||||
}).catch(() => {
|
||||
storage.setItem('loading', false)
|
||||
})
|
||||
}
|
||||
return (
|
||||
|
|
@ -172,6 +184,7 @@ const JoinSetting = forwardRef((_props: any, ref: any) => {
|
|||
message.error('请输入会议号!')
|
||||
return
|
||||
}
|
||||
storage.setItem('loading', true)
|
||||
isGetCheckoutRoomNum(roomNumber, (bool: boolean) => {
|
||||
if (bool) {
|
||||
getRoomRtcToken(roomNumber, (options: any) => {
|
||||
|
|
@ -194,6 +207,8 @@ const JoinSetting = forwardRef((_props: any, ref: any) => {
|
|||
}
|
||||
})
|
||||
}
|
||||
}).finally(() => {
|
||||
storage.setItem('loading', false)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -48,11 +48,12 @@ const UpdateModal = forwardRef((props: any, ref: any) => {
|
|||
title=""
|
||||
open={isUpdateModal}
|
||||
footer={null}
|
||||
onCancel={() => closeModal()}
|
||||
// onCancel={() => closeModal()}
|
||||
centered
|
||||
width={'400px'}
|
||||
className='modal-padding'
|
||||
maskClosable={false}
|
||||
closeIcon={false}
|
||||
>
|
||||
<div className={styles.isUpdateModal} style={{ backgroundImage: `url(${ImageUrl.icon7})` }}>
|
||||
<div className={styles.remarks} dangerouslySetInnerHTML={{ __html: updateContent }}>
|
||||
|
|
@ -62,10 +63,10 @@ const UpdateModal = forwardRef((props: any, ref: any) => {
|
|||
<div className={styles.buttons}>
|
||||
<Button type="primary"
|
||||
onClick={() => window.electron.onDownload('1')}
|
||||
style={{ width: '100%', height: '40px' }}
|
||||
style={{ width: '100%', height: '40px', marginBottom: '10px' }}
|
||||
className={`m-ant-btn`}
|
||||
>立即更新</Button>
|
||||
<div className={styles.button2} onClick={() => setIsUpdateModal(false)}>暂不更新</div>
|
||||
{import.meta.env.VITE_ENV === "development" ? <div className={styles.button2} onClick={() => setIsUpdateModal(false)}>暂不更新</div> : null}
|
||||
</div> : progress < 100 ?
|
||||
<div style={{ margin: '20px 0' }}>
|
||||
下载进度:{progress}%
|
||||
|
|
|
|||
|
|
@ -87,6 +87,8 @@ const Index: React.FC = () => {
|
|||
tokenA: res[1].data,
|
||||
})
|
||||
}
|
||||
}).finally(() => {
|
||||
storage.setItem('loading', false)
|
||||
})
|
||||
}
|
||||
const postRefresh = async (callBack: Function): Promise<void> => {
|
||||
|
|
@ -95,7 +97,11 @@ const Index: React.FC = () => {
|
|||
storage.setItem('user', JSON.stringify(res.data))
|
||||
storage.setItem('userLogin', true)
|
||||
callBack(res.data)
|
||||
} else {
|
||||
storage.setItem('loading', false)
|
||||
}
|
||||
}).catch(() => {
|
||||
storage.setItem('loading', false)
|
||||
})
|
||||
}
|
||||
|
||||
|
|
@ -206,7 +212,7 @@ const Index: React.FC = () => {
|
|||
<img src={ImageUrl.icon10} alt="" />
|
||||
</div>
|
||||
<div>
|
||||
{role.ID.includes(userInfo.roleId) ? <Popover
|
||||
{role.ID.includes(userInfo.roleId) ? <Popover
|
||||
content={
|
||||
<div className='meetingContentFooterPopover'>
|
||||
{userInfo.roleId === '1' ? <Popconfirm
|
||||
|
|
@ -254,6 +260,7 @@ const Index: React.FC = () => {
|
|||
if (role.ID.includes(userInfo.roleId)) {
|
||||
joinSettingRef.current.changeModal(item.roomNum)
|
||||
} else {
|
||||
storage.setItem('loading', true)
|
||||
postRefresh(() => {
|
||||
getRoomRtcToken(item.roomNum, (options: any) => {
|
||||
if (options) {
|
||||
|
|
|
|||
|
|
@ -111,6 +111,14 @@
|
|||
>div:nth-child(1) {
|
||||
margin-right: 20px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
cursor: pointer;
|
||||
|
||||
>span {
|
||||
color: #1677ff;
|
||||
font-size: 16px;
|
||||
margin-left: 4px;
|
||||
}
|
||||
}
|
||||
|
||||
>div:nth-child(2) {
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ import Operation from '@/components/Operation';
|
|||
import SpeakerModeModal from '@/components/SpeakerModeModal';
|
||||
import InvitingPersonnelModal from '@/components/InvitingPersonnelModal';
|
||||
import { Button, Input, Popover, Modal, Checkbox, message, Popconfirm, notification } from "antd";
|
||||
import { SearchOutlined, EllipsisOutlined, ExclamationCircleFilled, FullscreenExitOutlined, FullscreenOutlined } from '@ant-design/icons';
|
||||
import { SearchOutlined, EllipsisOutlined, ExclamationCircleFilled, FullscreenExitOutlined, FullscreenOutlined, QuestionCircleOutlined } from '@ant-design/icons';
|
||||
import { useLocation, useNavigate } from 'react-router-dom';
|
||||
import { thumbImageBufferToBase64 } from '@/utils/package/base64'
|
||||
import { storage } from '@/utils';
|
||||
|
|
@ -14,7 +14,7 @@ import { agora } from '@/utils/package/agora'
|
|||
import { onInvoke, onSignalr, offSignalr, onStart } from '@/utils/package/signalr';
|
||||
import dayjs from 'dayjs';
|
||||
import durationPlugin from 'dayjs/plugin/duration';
|
||||
import { VideoSourceType, VideoStreamType } from 'agora-electron-sdk';
|
||||
import { AudioVolumeInfo, QualityType, RtcConnection, RtcStats, UserOfflineReasonType, VideoSourceType, VideoStreamType } from 'agora-electron-sdk';
|
||||
import Avatar from '@/components/Avatar';
|
||||
import SharedFilesModel from '@/components/SharedFilesModel';
|
||||
import StupWizard from '@/components/StupWizard';
|
||||
|
|
@ -146,7 +146,14 @@ const Meeting: React.FC = () => {
|
|||
const [chatList, setChatList] = useState<any>([])
|
||||
const [currentVideoId, setCurrentVideoId] = useState('')
|
||||
let [currentSeconds, setCurrentSeconds] = useState(0)
|
||||
const [currentEffective, setCurrentEffective] = useState(0)
|
||||
const [currentEffective, setCurrentEffective] = useState(4)
|
||||
const [currentNetworkInfo, setCurrentNetworkInfo] = useState({
|
||||
networkQuality: {
|
||||
level: '佳',
|
||||
text: '网络质量极好。'
|
||||
},
|
||||
networkOther: {} as RtcStats
|
||||
})
|
||||
const [isComputerAudio, setIsComputerAudio] = useState(true)
|
||||
const [isFluencyPriority, setIsFluencyPriority] = useState(false)
|
||||
const [open, setOpen] = useState(false)
|
||||
|
|
@ -231,14 +238,54 @@ const Meeting: React.FC = () => {
|
|||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
const connection = (navigator as any).connection
|
||||
if (connection.downlink === 0) {
|
||||
setCurrentEffective(0)
|
||||
} else {
|
||||
let effectiveTypeLength = ['slow-2g', '2g', '3g', '4g'].indexOf((navigator as any).connection.effectiveType)
|
||||
setCurrentEffective(effectiveTypeLength + 1)
|
||||
switch (currentEffective) {
|
||||
case 0:
|
||||
setCurrentNetworkInfo({
|
||||
...currentNetworkInfo,
|
||||
networkQuality: {
|
||||
level: '断开连接',
|
||||
text: '网络连接断开。'
|
||||
}
|
||||
})
|
||||
break;
|
||||
case 1:
|
||||
setCurrentNetworkInfo({
|
||||
...currentNetworkInfo,
|
||||
networkQuality: {
|
||||
level: '非常差',
|
||||
text: '完全无法沟通。'
|
||||
}
|
||||
})
|
||||
break;
|
||||
case 2:
|
||||
setCurrentNetworkInfo({
|
||||
...currentNetworkInfo,
|
||||
networkQuality: {
|
||||
level: '差',
|
||||
text: '勉强能沟通但不顺畅,网络质量非常差,基本不能沟通。'
|
||||
}
|
||||
})
|
||||
break;
|
||||
case 3:
|
||||
setCurrentNetworkInfo({
|
||||
...currentNetworkInfo,
|
||||
networkQuality: {
|
||||
level: '良好',
|
||||
text: ' 用户主观感受有瑕疵但不影响沟通。'
|
||||
}
|
||||
})
|
||||
break;
|
||||
case 4:
|
||||
setCurrentNetworkInfo({
|
||||
...currentNetworkInfo,
|
||||
networkQuality: {
|
||||
level: '佳',
|
||||
text: '网络质量极好。'
|
||||
}
|
||||
})
|
||||
break;
|
||||
}
|
||||
}, [(navigator as any).connection.effectiveType]);
|
||||
}, [currentEffective]);
|
||||
|
||||
useEffect(() => {
|
||||
let currentVideoUserItem = roomUserList.find((item: any) => item.uid === currentVideoId || item.screenShareId === currentVideoId)
|
||||
|
|
@ -644,14 +691,14 @@ const Meeting: React.FC = () => {
|
|||
await getJoin(state.enableMicr, state.enableCamera)
|
||||
await agora.init(true)
|
||||
agora.registerEventHandler({
|
||||
onJoinChannelSuccess: async (info: any, _elapsed: any) => {
|
||||
if (info.channelId === state.channelId) {
|
||||
if (String(info.localUid).length !== 9) {
|
||||
onJoinChannelSuccess: async (connection: RtcConnection, _elapsed: number) => {
|
||||
if (connection.channelId === state.channelId) {
|
||||
if (String(connection.localUid).length !== 9) {
|
||||
setTimeout(async () => {
|
||||
await agora.setupLocalVideo({
|
||||
uid: Number(info.localUid),
|
||||
view: document.getElementById(`video-${info.localUid}`),
|
||||
channelId: info.channelId,
|
||||
uid: Number(connection.localUid),
|
||||
view: document.getElementById(`video-${connection.localUid}`),
|
||||
channelId: connection.channelId,
|
||||
sourceType: VideoSourceType.VideoSourceCameraPrimary,
|
||||
})
|
||||
getShowUser();
|
||||
|
|
@ -659,8 +706,8 @@ const Meeting: React.FC = () => {
|
|||
}
|
||||
}
|
||||
},
|
||||
onUserJoined: async (info: any, remoteUid: any, _elapsed: any) => {
|
||||
if (info.channelId === state.channelId) {
|
||||
onUserJoined: async (connection: RtcConnection, remoteUid: number, _elapsed: number) => {
|
||||
if (connection.channelId === state.channelId) {
|
||||
if (String(remoteUid).length === 9) {
|
||||
setIsShare(remoteUid)
|
||||
} else {
|
||||
|
|
@ -668,21 +715,21 @@ const Meeting: React.FC = () => {
|
|||
await agora.setupRemoteVideoJoin({
|
||||
uid: Number(remoteUid),
|
||||
view: document.getElementById(`video-${remoteUid}`),
|
||||
channelId: info.channelId,
|
||||
channelId: connection.channelId,
|
||||
})
|
||||
}, 1500);
|
||||
}
|
||||
}
|
||||
},
|
||||
onUserOffline: async (info: any, remoteUid: any, _reason: any) => {
|
||||
if (info.channelId === state.channelId) {
|
||||
onUserOffline: async (connection: RtcConnection, remoteUid: number, _reason: UserOfflineReasonType) => {
|
||||
if (connection.channelId === state.channelId) {
|
||||
if (String(remoteUid).length === 9) {
|
||||
setIsShare(null)
|
||||
}
|
||||
await agora.setupRemoteVideo({
|
||||
uid: Number(remoteUid),
|
||||
view: null,
|
||||
channelId: info.channelId,
|
||||
channelId: connection.channelId,
|
||||
});
|
||||
setCurrentVideoId((res: any) => {
|
||||
if (Number(res) === remoteUid) {
|
||||
|
|
@ -692,7 +739,7 @@ const Meeting: React.FC = () => {
|
|||
})
|
||||
}
|
||||
},
|
||||
onAudioVolumeIndication: async (speakers: any) => {
|
||||
onAudioVolumeIndication: async (speakers: AudioVolumeInfo[]) => {
|
||||
speakers.forEach((item: any) => {
|
||||
let domMe = document.getElementById(`micr-item-${userInfo.uid}`);
|
||||
let dom = document.getElementById(`micr-${item.uid ? item.uid : userInfo.uid}`);
|
||||
|
|
@ -705,6 +752,35 @@ const Meeting: React.FC = () => {
|
|||
domMe.style.height = `${percentage}%`
|
||||
}
|
||||
});
|
||||
},
|
||||
onNetworkQuality: async (_connection: RtcConnection, remoteUid: number, _txQuality: QualityType, rxQuality: QualityType) => {
|
||||
if (remoteUid === 0) {
|
||||
switch (rxQuality) {
|
||||
case 1:
|
||||
setCurrentEffective(4)
|
||||
break;
|
||||
case 2:
|
||||
case 3:
|
||||
setCurrentEffective(3)
|
||||
break;
|
||||
case 4:
|
||||
case 5:
|
||||
setCurrentEffective(2)
|
||||
break;
|
||||
case 6:
|
||||
setCurrentEffective(1)
|
||||
break;
|
||||
default:
|
||||
setCurrentEffective(navigator.onLine ? 4 : 0)
|
||||
break;
|
||||
}
|
||||
}
|
||||
},
|
||||
onRtcStats: async (stats: RtcStats) => {
|
||||
setCurrentNetworkInfo({
|
||||
...currentNetworkInfo,
|
||||
networkOther: stats
|
||||
})
|
||||
}
|
||||
})
|
||||
if (state.enableCamera) {
|
||||
|
|
@ -1550,9 +1626,51 @@ const Meeting: React.FC = () => {
|
|||
{contextHolder}
|
||||
<div className={styles.meetingHeader}>
|
||||
<div>
|
||||
<div>
|
||||
{networkIcon(currentEffective)}
|
||||
</div>
|
||||
<Popover
|
||||
content={
|
||||
<div style={{ color: 'white' }}>
|
||||
<div>
|
||||
<span>网络质量:</span>
|
||||
<span>{currentNetworkInfo.networkQuality.level}</span>
|
||||
<span>
|
||||
<Popover
|
||||
content={
|
||||
<span
|
||||
style={{ color: 'white' }}>
|
||||
{currentNetworkInfo.networkQuality.text}
|
||||
</span>
|
||||
}
|
||||
title=""
|
||||
>
|
||||
<QuestionCircleOutlined style={{
|
||||
cursor: 'pointer',
|
||||
marginLeft: '10px'
|
||||
}} />
|
||||
</Popover>
|
||||
</span>
|
||||
</div>
|
||||
<div>
|
||||
<span>带宽占用:</span>
|
||||
<span>↑{currentNetworkInfo.networkOther.txKBitRate}kbps ↓{currentNetworkInfo.networkOther.rxKBitRate}kbps</span>
|
||||
</div>
|
||||
<div>
|
||||
<span>丢包率:</span>
|
||||
<span>↑{currentNetworkInfo.networkOther.txPacketLossRate}% ↓{currentNetworkInfo.networkOther.rxPacketLossRate}%</span>
|
||||
</div>
|
||||
<div>
|
||||
<span>延迟:</span>
|
||||
<span>{currentNetworkInfo.networkOther.lastmileDelay}ms</span>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
title=""
|
||||
trigger="hover"
|
||||
>
|
||||
<div className='drag'>
|
||||
{networkIcon(currentEffective)}
|
||||
<span>详情</span>
|
||||
</div>
|
||||
</Popover>
|
||||
<div>{changeCurrentSeconds()}</div>
|
||||
</div>
|
||||
<div>会议号:{state.channelId} 会议名称:{state.roomName}</div>
|
||||
|
|
@ -2339,30 +2457,30 @@ const meetingContentError = (item: any) => {
|
|||
const networkIcon = (network: number) => {
|
||||
switch (network) {
|
||||
case 0:
|
||||
return <svg width="16" height="16" viewBox="0 0 32 33" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g clipPath="url(#clip0_5499_5160)">
|
||||
<path d="M1.9 32.8398C0.85 32.8398 0 31.9898 0 30.9398V23.3398C0 22.2898 0.85 21.4398 1.9 21.4398C2.95 21.4398 3.8 22.2898 3.8 23.3398V30.9398C3.8 31.9898 2.95 32.8398 1.9 32.8398ZM11.3 32.8398C10.25 32.8398 9.4 31.9898 9.4 30.9398V16.1398C9.4 15.0898 10.25 14.2398 11.3 14.2398C12.35 14.2398 13.2 15.0898 13.2 16.1398V30.9398C13.2 31.9898 12.35 32.8398 11.3 32.8398ZM20.7 32.8398C19.65 32.8398 18.8 31.9898 18.8 30.9398V9.73984C18.8 8.68984 19.65 7.83984 20.7 7.83984C21.75 7.83984 22.6 8.68984 22.6 9.73984V30.9398C22.6 31.9898 21.75 32.8398 20.7 32.8398ZM30.1 32.8398C29.05 32.8398 28.2 31.9898 28.2 30.9398V2.73984C28.2 1.68984 29.05 0.839844 30.1 0.839844C31.15 0.839844 32 1.68984 32 2.73984V30.9398C32 31.9898 31.15 32.8398 30.1 32.8398Z" fill="#7C8280" />
|
||||
<path d="M8.86265 3.02995L6.10877 5.78383L3.35489 3.02995C2.99725 2.67231 2.40713 2.67231 2.04948 3.02995C1.69184 3.3876 1.69184 3.97772 2.04948 4.33536L4.80336 7.08924L2.04948 9.84312C1.69184 10.2008 1.69184 10.7909 2.04948 11.1485C2.40713 11.5062 2.99725 11.5062 3.35489 11.1485L6.10877 8.39465L8.86265 11.1485C9.22029 11.5062 9.81041 11.5062 10.1681 11.1485C10.5257 10.7909 10.5257 10.2008 10.1681 9.84312L7.41418 7.08924L10.1681 4.33536C10.5257 3.97772 10.5257 3.3876 10.1681 3.02995C9.81041 2.67231 9.22029 2.67231 8.86265 3.02995Z" fill="#A5A5A5" />
|
||||
return <svg width="33" height="33" viewBox="0 0 33 33" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g clip-path="url(#clip0_5499_5160)">
|
||||
<path d="M2.01914 32.4824C0.969141 32.4824 0.119141 31.6324 0.119141 30.5824V22.9824C0.119141 21.9324 0.969141 21.0824 2.01914 21.0824C3.06914 21.0824 3.91914 21.9324 3.91914 22.9824V30.5824C3.91914 31.6324 3.06914 32.4824 2.01914 32.4824ZM11.4191 32.4824C10.3691 32.4824 9.51914 31.6324 9.51914 30.5824V15.7824C9.51914 14.7324 10.3691 13.8824 11.4191 13.8824C12.4691 13.8824 13.3191 14.7324 13.3191 15.7824V30.5824C13.3191 31.6324 12.4691 32.4824 11.4191 32.4824ZM20.8191 32.4824C19.7691 32.4824 18.9191 31.6324 18.9191 30.5824V9.38242C18.9191 8.33242 19.7691 7.48242 20.8191 7.48242C21.8691 7.48242 22.7191 8.33242 22.7191 9.38242V30.5824C22.7191 31.6324 21.8691 32.4824 20.8191 32.4824ZM30.2191 32.4824C29.1691 32.4824 28.3191 31.6324 28.3191 30.5824V2.38242C28.3191 1.33242 29.1691 0.482422 30.2191 0.482422C31.2691 0.482422 32.1191 1.33242 32.1191 2.38242V30.5824C32.1191 31.6324 31.2691 32.4824 30.2191 32.4824Z" fill="#7C8280" />
|
||||
<path d="M8.98179 2.67253L6.22791 5.42641L3.47403 2.67253C3.11639 2.31489 2.52627 2.31489 2.16863 2.67253C1.81098 3.03018 1.81098 3.62029 2.16863 3.97794L4.9225 6.73182L2.16863 9.48569C1.81098 9.84334 1.81098 10.4335 2.16863 10.7911C2.52627 11.1488 3.11639 11.1488 3.47403 10.7911L6.22791 8.03723L8.98179 10.7911C9.33943 11.1488 9.92955 11.1488 10.2872 10.7911C10.6448 10.4335 10.6448 9.84334 10.2872 9.48569L7.53332 6.73182L10.2872 3.97794C10.6448 3.62029 10.6448 3.03018 10.2872 2.67253C9.92955 2.31489 9.33943 2.31489 8.98179 2.67253Z" fill="#F90000" />
|
||||
</g>
|
||||
<defs>
|
||||
<clipPath id="clip0_5499_5160">
|
||||
<rect width="32" height="32" fill="white" transform="translate(0 0.839844)" />
|
||||
<rect width="32" height="32" fill="white" transform="translate(0.119141 0.482422)" />
|
||||
</clipPath>
|
||||
</defs>
|
||||
</svg>
|
||||
case 1:
|
||||
return <svg width="16" height="16" viewBox="0 0 32 33" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M1.9 32.8385C0.85 32.8385 0 31.9885 0 30.9385V23.3385C0 22.2885 0.85 21.4385 1.9 21.4385C2.95 21.4385 3.8 22.2885 3.8 23.3385V30.9385C3.8 31.9885 2.95 32.8385 1.9 32.8385Z" fill="#02B188" />
|
||||
<path d="M28.1992 30.9389C28.1992 31.9889 29.0492 32.8389 30.0992 32.8389C31.1492 32.8389 31.9992 31.9889 31.9992 30.9389V2.73887C31.9992 1.68887 31.1492 0.838867 30.0992 0.838867C29.0492 0.838867 28.1992 1.68887 28.1992 2.73887V30.9389Z" fill="#7C8280" />
|
||||
<path d="M18.8008 30.9389C18.8008 31.9889 19.6508 32.8389 20.7008 32.8389C21.7508 32.8389 22.6008 31.9889 22.6008 30.9389V9.73887C22.6008 8.68887 21.7508 7.83887 20.7008 7.83887C19.6508 7.83887 18.8008 8.68887 18.8008 9.73887V30.9389Z" fill="#7C8280" />
|
||||
<path d="M9.40039 30.9393C9.40039 31.9893 10.2504 32.8393 11.3004 32.8393C12.3504 32.8393 13.2004 31.9893 13.2004 30.9393V16.1393C13.2004 15.0893 12.3504 14.2393 11.3004 14.2393C10.2504 14.2393 9.40039 15.0893 9.40039 16.1393V30.9393Z" fill="#7C8280" />
|
||||
return <svg width="33" height="33" viewBox="0 0 33 33" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M2.01914 32.482C0.969141 32.482 0.119141 31.632 0.119141 30.582V22.982C0.119141 21.932 0.969141 21.082 2.01914 21.082C3.06914 21.082 3.91914 21.932 3.91914 22.982V30.582C3.91914 31.632 3.06914 32.482 2.01914 32.482Z" fill="#FF800B" />
|
||||
<path d="M28.3184 30.5824C28.3184 31.6324 29.1684 32.4824 30.2184 32.4824C31.2684 32.4824 32.1184 31.6324 32.1184 30.5824V2.38242C32.1184 1.33242 31.2684 0.482422 30.2184 0.482422C29.1684 0.482422 28.3184 1.33242 28.3184 2.38242V30.5824Z" fill="#7C8280" />
|
||||
<path d="M18.9199 30.5824C18.9199 31.6324 19.7699 32.4824 20.8199 32.4824C21.8699 32.4824 22.7199 31.6324 22.7199 30.5824V9.38242C22.7199 8.33242 21.8699 7.48242 20.8199 7.48242C19.7699 7.48242 18.9199 8.33242 18.9199 9.38242V30.5824Z" fill="#7C8280" />
|
||||
<path d="M9.51953 30.5828C9.51953 31.6328 10.3695 32.4828 11.4195 32.4828C12.4695 32.4828 13.3195 31.6328 13.3195 30.5828V15.7828C13.3195 14.7328 12.4695 13.8828 11.4195 13.8828C10.3695 13.8828 9.51953 14.7328 9.51953 15.7828V30.5828Z" fill="#7C8280" />
|
||||
</svg>
|
||||
case 2:
|
||||
return <svg width="16" height="16" viewBox="0 0 32 33" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M1.9 32.8385C0.85 32.8385 0 31.9885 0 30.9385V23.3385C0 22.2885 0.85 21.4385 1.9 21.4385C2.95 21.4385 3.8 22.2885 3.8 23.3385V30.9385C3.8 31.9885 2.95 32.8385 1.9 32.8385Z" fill="#02B188" />
|
||||
<path d="M28.1992 30.9389C28.1992 31.9889 29.0492 32.8389 30.0992 32.8389C31.1492 32.8389 31.9992 31.9889 31.9992 30.9389V2.73887C31.9992 1.68887 31.1492 0.838867 30.0992 0.838867C29.0492 0.838867 28.1992 1.68887 28.1992 2.73887V30.9389Z" fill="#7C8280" />
|
||||
<path d="M18.8008 30.9389C18.8008 31.9889 19.6508 32.8389 20.7008 32.8389C21.7508 32.8389 22.6008 31.9889 22.6008 30.9389V9.73887C22.6008 8.68887 21.7508 7.83887 20.7008 7.83887C19.6508 7.83887 18.8008 8.68887 18.8008 9.73887V30.9389Z" fill="#7C8280" />
|
||||
<path d="M9.40039 30.9393C9.40039 31.9893 10.2504 32.8393 11.3004 32.8393C12.3504 32.8393 13.2004 31.9893 13.2004 30.9393V16.1393C13.2004 15.0893 12.3504 14.2393 11.3004 14.2393C10.2504 14.2393 9.40039 15.0893 9.40039 16.1393V30.9393Z" fill="#02B188" />
|
||||
return <svg width="33" height="33" viewBox="0 0 33 33" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M2.01914 32.482C0.969141 32.482 0.119141 31.632 0.119141 30.582V22.982C0.119141 21.932 0.969141 21.082 2.01914 21.082C3.06914 21.082 3.91914 21.932 3.91914 22.982V30.582C3.91914 31.632 3.06914 32.482 2.01914 32.482Z" fill="#FF800B" />
|
||||
<path d="M28.3184 30.5824C28.3184 31.6324 29.1684 32.4824 30.2184 32.4824C31.2684 32.4824 32.1184 31.6324 32.1184 30.5824V2.38242C32.1184 1.33242 31.2684 0.482422 30.2184 0.482422C29.1684 0.482422 28.3184 1.33242 28.3184 2.38242V30.5824Z" fill="#7C8280" />
|
||||
<path d="M18.9199 30.5824C18.9199 31.6324 19.7699 32.4824 20.8199 32.4824C21.8699 32.4824 22.7199 31.6324 22.7199 30.5824V9.38242C22.7199 8.33242 21.8699 7.48242 20.8199 7.48242C19.7699 7.48242 18.9199 8.33242 18.9199 9.38242V30.5824Z" fill="#7C8280" />
|
||||
<path d="M9.51953 30.5828C9.51953 31.6328 10.3695 32.4828 11.4195 32.4828C12.4695 32.4828 13.3195 31.6328 13.3195 30.5828V15.7828C13.3195 14.7328 12.4695 13.8828 11.4195 13.8828C10.3695 13.8828 9.51953 14.7328 9.51953 15.7828V30.5828Z" fill="#FF800B" />
|
||||
</svg>
|
||||
case 3:
|
||||
return <svg width="16" height="16" viewBox="0 0 32 33" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
|
|
|
|||
|
|
@ -8,7 +8,12 @@ import {
|
|||
ChannelProfileType,
|
||||
AudioAinsMode,
|
||||
SimulcastStreamMode,
|
||||
VideoStreamType
|
||||
VideoStreamType,
|
||||
QualityType,
|
||||
RtcConnection,
|
||||
RtcStats,
|
||||
AudioVolumeInfo,
|
||||
UserOfflineReasonType
|
||||
} from "agora-electron-sdk";
|
||||
import { GetRoomRtcToken, GetAgoraConf } from "@/api/Home/Index";
|
||||
import { storage } from '@/utils';
|
||||
|
|
@ -104,19 +109,19 @@ export const agora = {
|
|||
}, 1000);
|
||||
},
|
||||
// 事件回调
|
||||
registerEventHandler: ({ onJoinChannelSuccess, onUserJoined, onUserOffline, onAudioVolumeIndication }: any) => {
|
||||
registerEventHandler: ({ onJoinChannelSuccess, onUserJoined, onUserOffline, onAudioVolumeIndication, onNetworkQuality, onRtcStats }: any) => {
|
||||
rtcEngine.registerEventHandler({
|
||||
// 监听本地用户加入频道事件
|
||||
onJoinChannelSuccess: async (info: any, elapsed: any) => {
|
||||
await onJoinChannelSuccess(info, elapsed)
|
||||
onJoinChannelSuccess: async (connection: RtcConnection, elapsed: number) => {
|
||||
await onJoinChannelSuccess(connection, elapsed)
|
||||
},
|
||||
// 监听远端用户加入频道事件
|
||||
onUserJoined: async (info: any, remoteUid: any, elapsed: any) => {
|
||||
await onUserJoined(info, remoteUid, elapsed)
|
||||
onUserJoined: async (connection: RtcConnection, remoteUid: number, elapsed: number) => {
|
||||
await onUserJoined(connection, remoteUid, elapsed)
|
||||
},
|
||||
// 监听用户离开频道事件
|
||||
onUserOffline: async (info: any, remoteUid: any, reason: any) => {
|
||||
await onUserOffline(info, remoteUid, reason)
|
||||
onUserOffline: async (connection: RtcConnection, remoteUid: number, reason: UserOfflineReasonType) => {
|
||||
await onUserOffline(connection, remoteUid, reason)
|
||||
},
|
||||
// // 视频发布状态改变回调
|
||||
// onVideoPublishStateChanged: (source: any, channel: any, oldState: any, newState: any, elapseSinceLastState: any) => {
|
||||
|
|
@ -131,9 +136,17 @@ export const agora = {
|
|||
// }
|
||||
// },
|
||||
// // 用户音量提示回调。
|
||||
onAudioVolumeIndication: async (_connection: any, speakers: any, _speakerNumber: any, _totalVolume: any,) => {
|
||||
onAudioVolumeIndication: async (_connection: RtcConnection, speakers: AudioVolumeInfo[], _speakerNumber: number, _totalVolume: number) => {
|
||||
await onAudioVolumeIndication(speakers)
|
||||
}
|
||||
},
|
||||
//通话中每个用户的网络上下行 last mile 质量报告回调。
|
||||
onNetworkQuality: async (connection: RtcConnection, remoteUid: number, txQuality: QualityType, rxQuality: QualityType) => {
|
||||
await onNetworkQuality(connection, remoteUid, txQuality, rxQuality)
|
||||
},
|
||||
//当前通话相关的统计信息回调。
|
||||
onRtcStats: async (_connection: RtcConnection, stats: RtcStats) => {
|
||||
await onRtcStats(stats)
|
||||
},
|
||||
});
|
||||
},
|
||||
// 获取视图模式
|
||||
|
|
|
|||
|
|
@ -381,3 +381,7 @@ $pagination-hover-background-color: #5575F2;
|
|||
.ant-message {
|
||||
-webkit-app-region: no-drag;
|
||||
}
|
||||
|
||||
.ant-spin-fullscreen {
|
||||
z-index: 10000;
|
||||
}
|
||||
|
|
@ -63,7 +63,12 @@ export default defineConfig({
|
|||
VideoViewSetupMode,
|
||||
AudioAinsMode,
|
||||
SimulcastStreamMode,
|
||||
VideoStreamType
|
||||
VideoStreamType,
|
||||
QualityType,
|
||||
RtcConnection,
|
||||
RtcStats,
|
||||
AudioVolumeInfo,
|
||||
UserOfflineReasonType
|
||||
} = require("agora-electron-sdk")
|
||||
export {
|
||||
createAgoraRtcEngine,
|
||||
|
|
@ -75,7 +80,12 @@ export default defineConfig({
|
|||
VideoViewSetupMode,
|
||||
AudioAinsMode,
|
||||
SimulcastStreamMode,
|
||||
VideoStreamType
|
||||
VideoStreamType,
|
||||
QualityType,
|
||||
RtcConnection,
|
||||
RtcStats,
|
||||
AudioVolumeInfo,
|
||||
UserOfflineReasonType
|
||||
}
|
||||
`,
|
||||
})
|
||||
|
|
|
|||
Loading…
Reference in New Issue