diff --git a/src/assets/icons/camera.off.svg b/src/assets/icons/camera.off.svg new file mode 100644 index 00000000..9452484e --- /dev/null +++ b/src/assets/icons/camera.off.svg @@ -0,0 +1,4 @@ + diff --git a/src/assets/icons/camera.svg b/src/assets/icons/camera.svg new file mode 100644 index 00000000..6572494d --- /dev/null +++ b/src/assets/icons/camera.svg @@ -0,0 +1,3 @@ + diff --git a/src/assets/icons/share.screen.svg b/src/assets/icons/share.screen.svg new file mode 100644 index 00000000..27696d4b --- /dev/null +++ b/src/assets/icons/share.screen.svg @@ -0,0 +1,3 @@ + diff --git a/src/common/component/Voice.tsx b/src/common/component/Voice.tsx index 827f21a5..dc9ecfcb 100644 --- a/src/common/component/Voice.tsx +++ b/src/common/component/Voice.tsx @@ -44,14 +44,16 @@ const Voice = () => { if (mediaType == "audio") { // 播放远端音频 user.audioTrack?.play(); - // const playing= user.audioTrack?.isPlaying; - // const level = user.audioTrack?.getVolumeLevel(); - // if (level === 0) { - // // 远端静音 - // dispatch(updateVoicingMember({ uid: +user.uid, info: { muted: true } })); - // } window.VOICE_TRACK_MAP[+user.uid] = user.audioTrack; } + if (mediaType == "video") { + const id = `CAMERA_${user.uid}`; + console.log("video container id", id); + + // 播放远端视频 + user.videoTrack?.play(id); + window.VOICE_TRACK_MAP[+user.uid] = user.videoTrack; + } agoraEngine.on("user-unpublished", (user) => { // 远端用户取消了音频(muted) dispatch(updateVoicingMember({ uid: +user.uid, info: { muted: true } })); @@ -102,8 +104,6 @@ const Voice = () => { default: break; } - // const { downlinkNetworkQuality } = qlt; - // dispatch(updateVoicingNetworkQuality(downlinkNetworkQuality)); }); }); // 有新用户加入 @@ -127,13 +127,6 @@ const Voice = () => { return () => { window.removeEventListener("beforeunload", handlePageUnload, { capture: true }); - // if (window.VOICE_CLIENT && localTrack) { - // localTrack.close(); - // localTrack = null; - // window.VOICE_CLIENT.leave(); - // dispatch(updateVoicingInfo(null)); - // } - // window.VOICE_CLIENT=null }; }, []); @@ -148,9 +141,9 @@ type VoiceProps = { const audioJoin = new Audio(AudioJoin); const useVoice = ({ id, context = "channel" }: VoiceProps) => { const dispatch = useDispatch(); - const { voicingInfo } = useAppSelector(store => { + const { voicingInfo, loginUid } = useAppSelector(store => { return { - // loginUid: store.authData.user?.uid, + loginUid: store.authData.user?.uid, voicingInfo: store.voice.voicing }; }); @@ -197,6 +190,25 @@ const useVoice = ({ id, context = "channel" }: VoiceProps) => { } // setJoining(false); }; + const openCamera = async () => { + if (localTrack) { + localTrack.close(); + localTrack = null; + } + localTrack = await AgoraRTC.createCameraVideoTrack(); + await window.VOICE_CLIENT?.publish(localTrack); + const id = `CAMERA_${loginUid}`; + localTrack?.play(id); + }; + const closeCamera = async () => { + if (localTrack) { + localTrack.close(); + localTrack = null; + } + localTrack = await AgoraRTC.createMicrophoneAudioTrack(); + await window.VOICE_CLIENT?.publish(localTrack); + }; + const leave = async () => { if (window.VOICE_CLIENT && localTrack) { localTrack.close(); @@ -250,7 +262,9 @@ const useVoice = ({ id, context = "channel" }: VoiceProps) => { joining: voicingInfo ? voicingInfo.joining : undefined, joinedAtThisContext, joined: !!voicingInfo, - joinVoice + joinVoice, + openCamera, + closeCamera }; }; export { useVoice }; diff --git a/src/routes/chat/RTCWidget.tsx b/src/routes/chat/RTCWidget.tsx index 685800fe..74bf7e43 100644 --- a/src/routes/chat/RTCWidget.tsx +++ b/src/routes/chat/RTCWidget.tsx @@ -8,6 +8,9 @@ import IconMicOff from '../../assets/icons/mic.off.svg'; import IconCallOff from '../../assets/icons/headphone.svg'; import IconSoundOn from '../../assets/icons/sound.on.svg'; import IconSoundOff from '../../assets/icons/sound.off.svg'; +import IconCameraOff from '../../assets/icons/camera.off.svg'; +import IconCamera from '../../assets/icons/camera.svg'; +import IconScreen from '../../assets/icons/share.screen.svg'; import { useVoice } from '../../common/component/Voice'; import Signal from '../../common/component/Signal'; import Tooltip from '../../common/component/Tooltip'; @@ -19,7 +22,7 @@ type Props = { const RTCWidget = ({ id, context = "channel" }: Props) => { const { t } = useTranslation("chat"); - const { leave, voicingInfo, setMute, setDeafen, joining = true } = useVoice({ context, id }); + const { leave, voicingInfo, setMute, setDeafen, joining = true, openCamera } = useVoice({ context, id }); const { loginUser, channelData, userData } = useAppSelector(store => { return { userData: store.users.byId, @@ -28,25 +31,36 @@ const RTCWidget = ({ id, context = "channel" }: Props) => { }; }); if (!loginUser || !voicingInfo || joining) return null; - const name = voicingInfo.context == "channel" ? channelData[voicingInfo.id]?.name : userData[voicingInfo.id]?.name; - if (!name) return null; + // const name = voicingInfo.context == "channel" ? channelData[voicingInfo.id]?.name : userData[voicingInfo.id]?.name; + // if (!name) return null; const isReConnecting = voicingInfo.connectionState == "RECONNECTING"; return (