rendering logo when video off

This commit is contained in:
Roland Osborne 2023-03-27 23:41:20 -07:00
parent 09e0ffbe34
commit 201861c8b9
4 changed files with 65 additions and 22 deletions

View File

@ -11,9 +11,11 @@ export function useRingContext() {
ringing: new Map(), ringing: new Map(),
callStatus: null, callStatus: null,
localStream: null, localStream: null,
localVideo: false,
localAudio: false,
remoteStream: null, remoteStream: null,
video: false, removeVideo: false,
audio: false, removeAudio: false,
}); });
const access = useRef(null); const access = useRef(null);
@ -93,15 +95,21 @@ export function useRingContext() {
// connect signal socket // connect signal socket
calling.current = { state: "connecting", callId, contactNode, contactToken, host: false }; calling.current = { state: "connecting", callId, contactNode, contactToken, host: false };
updateState({ callStatus: "connecting" }); updateState({ callStatus: "connecting", remoteVideo: false, remoteAudio: false });
// form peer connection // form peer connection
pc.current = new RTCPeerConnection(); pc.current = new RTCPeerConnection();
pc.current.ontrack = (ev) => { //{streams: [stream]}) => { pc.current.ontrack = (ev) => {
if (!stream.current) { if (!stream.current) {
stream.current = new MediaStream(); stream.current = new MediaStream();
updateState({ remoteStream: stream.current }); updateState({ remoteStream: stream.current });
} }
if (ev.track.kind === 'audio') {
updateState({ remoteAudio: true });
}
else if (ev.track.kind === 'video') {
updateState({ remoteVideo: true });
}
stream.current.addTrack(ev.track); stream.current.addTrack(ev.track);
}; };
pc.current.onicecandidate = ({candidate}) => { pc.current.onicecandidate = ({candidate}) => {
@ -245,7 +253,7 @@ export function useRingContext() {
}, RING); }, RING);
calling.current = { state: "connecting", callId: id, host: true }; calling.current = { state: "connecting", callId: id, host: true };
updateState({ callStatus: "connecting" }); updateState({ callStatus: "connecting", remoteVideo: false, remoteAudio: false });
// form peer connection // form peer connection
pc.current = new RTCPeerConnection(); pc.current = new RTCPeerConnection();
@ -255,6 +263,12 @@ export function useRingContext() {
stream.current = new MediaStream(); stream.current = new MediaStream();
updateState({ remoteStream: stream.current }); updateState({ remoteStream: stream.current });
} }
if (ev.track.kind === 'audio') {
updateState({ remoteAudio: true });
}
else if (ev.track.kind === 'video') {
updateState({ remoteVideo: true });
}
stream.current.addTrack(ev.track); stream.current.addTrack(ev.track);
}; };
pc.current.onicecandidate = ({candidate}) => { pc.current.onicecandidate = ({candidate}) => {
@ -278,7 +292,7 @@ export function useRingContext() {
video: false, video: false,
audio: true, audio: true,
}); });
updateState({ video: false, audio: true, localStream: stream }); updateState({ localVideo: false, localAudio: true, localStream: stream });
for (const track of stream.getTracks()) { for (const track of stream.getTracks()) {
if (track.kind === 'audio') { if (track.kind === 'audio') {
audioTrack.current = track; audioTrack.current = track;
@ -371,21 +385,21 @@ export function useRingContext() {
else { else {
videoTrack.current.enabled = true; videoTrack.current.enabled = true;
} }
updateState({ video: true }); updateState({ localVideo: true });
}, },
disableVideo: async () => { disableVideo: async () => {
if (videoTrack.current) { if (videoTrack.current) {
videoTrack.current.enabled = false; videoTrack.current.enabled = false;
} }
updateState({ video: false }); updateState({ localVideo: false });
}, },
enableAudio: async () => { enableAudio: async () => {
audioTrack.current.enabled = true; audioTrack.current.enabled = true;
updateState({ audio: true }); updateState({ localAudio: true });
}, },
disableAudio: async () => { disableAudio: async () => {
audioTrack.current.enabled = false; audioTrack.current.enabled = false;
updateState({ audio: false }); updateState({ loaclAudio: false });
}, },
} }

View File

@ -21,8 +21,8 @@ export function Session() {
const { state, actions } = useSession(); const { state, actions } = useSession();
const [ringing, setRinging] = useState([]); const [ringing, setRinging] = useState([]);
const [callWidth, setCallWidth] = useState(320); const [callWidth, setCallWidth] = useState(256);
const [callHeight, setCallHeight] = useState(240); const [callHeight, setCallHeight] = useState(256);
const remote = useRef(); const remote = useRef();
const local = useRef(); const local = useRef();
@ -44,10 +44,24 @@ export function Session() {
setRinging(incoming); setRinging(incoming);
}, [state.ringing]); }, [state.ringing]);
const getWidth = () => {
if (state.remoteVideo) {
return callWidth;
}
return 256;
}
const getHeight = () => {
if (state.remoteVideo) {
return callHeight;
}
return 256;
}
useEffect(() => { useEffect(() => {
if (remote.current) { if (remote.current) {
remote.current.onloadedmetadata = (ev) => { remote.current.onloadedmetadata = (ev) => {
const { videoWidth, videoHeight } = ev.target || { videoWidth: 320, videoHeight: 240 } const { videoWidth, videoHeight } = ev.target || { videoWidth: 256, videoHeight: 256 }
if ((window.innerWidth * 8) / 10 < videoWidth) { if ((window.innerWidth * 8) / 10 < videoWidth) {
const scaledWidth = window.innerWidth * 8 / 10; const scaledWidth = window.innerWidth * 8 / 10;
const scaledHeight = videoHeight * (scaledWidth / videoWidth) const scaledHeight = videoHeight * (scaledWidth / videoWidth)
@ -308,10 +322,13 @@ export function Session() {
</div> </div>
</RingingWrapper> </RingingWrapper>
</Modal> </Modal>
<Modal centered visible={state.callStatus} footer={null} closable={false} width={callWidth + 12} height={callHeight + 12} bodyStyle={{ paddingBottom: 0, paddingTop: 6, paddingLeft: 6, paddingRight: 6, paddingBottom: 6 }}> <Modal centered visible={state.callStatus} footer={null} closable={false} width={getWidth() + 12} height={getHeight() + 12} bodyStyle={{ paddingBottom: 0, paddingTop: 6, paddingLeft: 6, paddingRight: 6, paddingBottom: 6 }}>
<CallingWrapper> <CallingWrapper>
{ !state.remoteVideo && (
<Logo url={null} width={256} height={256} radius={8} />
)}
{ state.remoteStream && ( { state.remoteStream && (
<video ref={remote} disablepictureinpicture autoPlay style={{ width: '100%', height: '100%' }} <video ref={remote} disablepictureinpicture autoPlay style={{ display: state.remoteVideo ? 'block' : 'none', width: '100%', height: '100%' }}
complete={() => console.log("VIDEO COMPLETE")} progress={() => console.log("VIDEO PROGRESS")} error={() => console.log("VIDEO ERROR")} waiting={() => console.log("VIDEO WAITING")} /> complete={() => console.log("VIDEO COMPLETE")} progress={() => console.log("VIDEO PROGRESS")} error={() => console.log("VIDEO ERROR")} waiting={() => console.log("VIDEO WAITING")} />
)} )}
{ state.localStream && ( { state.localStream && (
@ -321,22 +338,22 @@ export function Session() {
</div> </div>
)} )}
<div className="calling-options"> <div className="calling-options">
{ state.video && ( { state.localVideo && (
<div className="calling-option" onClick={actions.disableVideo}> <div className="calling-option" onClick={actions.disableVideo}>
<IoVideocamOutline /> <IoVideocamOutline />
</div> </div>
)} )}
{ !state.video && ( { !state.localVideo && (
<div className="calling-option" onClick={actions.enableVideo}> <div className="calling-option" onClick={actions.enableVideo}>
<IoVideocamOffOutline /> <IoVideocamOffOutline />
</div> </div>
)} )}
{ state.audio && ( { state.localAudio && (
<div className="calling-option" onClick={actions.disableAudio}> <div className="calling-option" onClick={actions.disableAudio}>
<IoMicOutline /> <IoMicOutline />
</div> </div>
)} )}
{ !state.audio && ( { !state.localAudio && (
<div className="calling-option" onClick={actions.enableAudio}> <div className="calling-option" onClick={actions.enableAudio}>
<IoMicOffOutline /> <IoMicOffOutline />
</div> </div>

View File

@ -85,6 +85,15 @@ export const CallingWrapper = styled.div`
position: absolute; position: absolute;
} }
.calling-logo {
position: absolute;
top: 0;
left: 0;
width: 256px;
height: 256px;
background-color: yellow;
}
.calling-end { .calling-end {
position: absolute; position: absolute;
bottom: 16px; bottom: 16px;

View File

@ -26,9 +26,11 @@ export function useSession() {
ringing: [], ringing: [],
callStatus: null, callStatus: null,
localStream: null, localStream: null,
localVideo: false,
localAudio: false,
remoteStream: null, remoteStream: null,
video: false, remoteVideo: false,
audio: false, remoteAudio: false,
}); });
const app = useContext(AppContext); const app = useContext(AppContext);
@ -64,7 +66,8 @@ export function useSession() {
} }
}); });
updateState({ ringing, video: ring.state.video, audio: ring.state.audio, localStream: ring.state.localStream, remoteStream: ring.state.remoteStream, callStatus: ring.state.callStatus }); const { callStatus, localStream, localVideo, localAudio, remoteStream, remoteVideo, remoteAudio } = ring.state;
updateState({ ringing, callStatus, localStream, localVideo, localAudio, remoteStream, remoteVideo, remoteAudio });
}, [ring.state]); }, [ring.state]);
useEffect(() => { useEffect(() => {