1
0

Video reconnect is now solid

Signed-off-by: James Ketrenos <james_eikona@ketrenos.com>
This commit is contained in:
James Ketrenos 2022-03-16 09:17:33 -07:00
parent 238c4edff1
commit 1924f969bc

View File

@ -20,13 +20,13 @@ const Video = ({ srcObject, local, ...props }) => {
return; return;
} }
const ref = refVideo.current; const ref = refVideo.current;
if (debug) console.log('media-controls <video> bind'); if (debug) console.log('media-control - video <video> bind');
ref.srcObject = srcObject; ref.srcObject = srcObject;
if (local) { if (local) {
ref.muted = true; ref.muted = true;
} }
return () => { return () => {
if (debug) console.log('media-controls <video> unbind'); if (debug) console.log('media-control - <video> unbind');
if (ref) { if (ref) {
ref.srcObject = undefined; ref.srcObject = undefined;
} }
@ -49,6 +49,8 @@ const MediaAgent = ({setPeers}) => {
Object.assign(peers[peer].attributes, { Object.assign(peers[peer].attributes, {
srcObject: event.streams[0] srcObject: event.streams[0]
}); });
/* Trigger update of MediaControl now that a stream is available */
setPeers(Object.assign({}, peers));
} }
} }
}, [peers]); }, [peers]);
@ -69,9 +71,12 @@ const MediaAgent = ({setPeers}) => {
const peer_id = config.peer_id; const peer_id = config.peer_id;
if (peer_id in peers) { if (peer_id in peers) {
/* This is normal */ if (!peers[peer_id].dead) {
console.log(`media-agent - addPeer - ${peer_id} already in peers`); /* This is normal when peers are added by other connecting
return; * peers through the signaling server */
console.log(`media-agent - addPeer - ${peer_id} already in peers`);
return;
}
} }
const connection = new RTCPeerConnection({ const connection = new RTCPeerConnection({
configuration: { configuration: {
@ -93,14 +98,24 @@ const MediaAgent = ({setPeers}) => {
] ]
}); });
peers[peer_id] = { /* Even if reviving, allocate a new Object so <MediaControl> will
* have its peer state change and trigger an update from
* <PlayerList> */
const peer = {
name: peer_id, name: peer_id,
muted: false,
videoOn: true,
connection, connection,
initialized: false, attributes: {},
attributes: {}
}; };
if (peer_id in peers) {
peer.muted = peers[peer_id].muted;
peer.videoOn = peers[peer_id].videoOn;
console.log(`media-agent - addPeer - reviving dead peer ${peer_id}`, peer);
} else {
peer.muted = false;
peer.videoOn = true;
}
peers[peer_id] = peer;
console.log(`media-agent - addPeer - remote`, peers); console.log(`media-agent - addPeer - remote`, peers);
setPeers(Object.assign({}, peers)); setPeers(Object.assign({}, peers));
@ -222,10 +237,13 @@ const MediaAgent = ({setPeers}) => {
if (peer_id in peers) { if (peer_id in peers) {
if (peers[peer_id].connection) { if (peers[peer_id].connection) {
peers[peer_id].connection.close(); peers[peer_id].connection.close();
peers[peer_id].connection = undefined;
} }
} }
delete peers[peer_id]; /* To maintain mute/videoOn states, we don't remove the peer but
* instead mark it as dead */
peers[peer_id].dead = true;
if (debug) console.log(`media-agent - removePeer`, peers); if (debug) console.log(`media-agent - removePeer`, peers);
setPeers(Object.assign({}, peers)); setPeers(Object.assign({}, peers));
}; };
@ -273,10 +291,12 @@ const MediaAgent = ({setPeers}) => {
continue; continue;
} }
peers[peer_id].connection.close(); peers[peer_id].connection.close();
peers[peer_id].connection = undefined;
} }
for (let id in peers) { for (let id in peers) {
delete peers[id]; peers[id].dead = true;
peers[id].connection = undefined;
} }
if (debug) console.log(`media-agent - close`, peers); if (debug) console.log(`media-agent - close`, peers);
setPeers(Object.assign({}, peers)); setPeers(Object.assign({}, peers));
@ -316,7 +336,6 @@ const MediaAgent = ({setPeers}) => {
local: true, local: true,
muted: true, muted: true,
videoOn: false, videoOn: false,
initialized: false,
attributes: { attributes: {
local: true, local: true,
srcObject: stream srcObject: stream
@ -325,6 +344,8 @@ const MediaAgent = ({setPeers}) => {
} }
} }
/* Renaming the local connection requires the peer to be deleted
* and re-established with the signaling server */
for (let key in peers) { for (let key in peers) {
if (peers[key].local && key !== name) { if (peers[key].local && key !== name) {
delete peers[key]; delete peers[key];
@ -399,7 +420,9 @@ const MediaAgent = ({setPeers}) => {
return () => { return () => {
abort = true; abort = true;
console.log(`media-agent - abort media setup!`); if (!stream) {
console.log(`media-agent - abort media setup!`);
}
}; };
}, [ws, setStream, stream, name, sendMessage]); }, [ws, setStream, stream, name, sendMessage]);
@ -424,72 +447,71 @@ const MediaControl = ({isSelf, peer}) => {
setMedia(peer); setMedia(peer);
}, [peer, setMedia, setMuted, setVideoOn]); }, [peer, setMedia, setMuted, setVideoOn]);
console.log(`media-control - render`);
const toggleMute = (event) => { const toggleMute = (event) => {
if (debug) console.log(`MediaControl - toggleMute - ${peer.name}`, !muted); if (debug) console.log(`media-control - toggleMute - ${peer.name}`, !muted);
peer.muted = !muted; peer.muted = !muted;
setMuted(peer.muted); setMuted(peer.muted);
event.stopPropagation(); event.stopPropagation();
} }
const toggleVideo = (event) => { const toggleVideo = (event) => {
if (debug) console.log(`MediaControl - toggleVideo - ${peer.name}`, !videoOn); if (debug) console.log(`media-control - toggleVideo - ${peer.name}`, !videoOn);
peer.videoOn = !videoOn; peer.videoOn = !videoOn;
setVideoOn(peer.videoOn); setVideoOn(peer.videoOn);
event.stopPropagation(); event.stopPropagation();
} }
useEffect(() => { useEffect(() => {
if (!media) { if (!media || media.dead) {
return; return;
} }
if (media.attributes.srcObject) { if (media.attributes.srcObject) {
console.log(`media-control - audio enable - ${peer.name}:${!muted}`);
media.attributes.srcObject.getAudioTracks().forEach((track) => { media.attributes.srcObject.getAudioTracks().forEach((track) => {
track.enabled = !muted; track.enabled = !muted;
}); });
} }
}, [media, muted]); }); /* run after every render to hit when ontrack has received and set
* the stream //, [media, muted]); */
useEffect(() => { useEffect(() => {
if (!media) { if (!media || media.dead) {
return; return;
} }
if (media.attributes.srcObject) { if (media.attributes.srcObject) {
console.log(`media-control - video enable - ${peer.name}:${videoOn}`);
media.attributes.srcObject.getVideoTracks().forEach((track) => { media.attributes.srcObject.getVideoTracks().forEach((track) => {
track.enabled = videoOn; track.enabled = videoOn;
}); });
} }
}, [media, videoOn]); }); /* run after every render to hit when ontrack has received and set
* the stream //, [media, videoOn]); */
if (!media) { const isValid = media && !media.dead,
return <div className="MediaControl"> color = isValid ? 'primary' : 'disabled';
<div>
{ isSelf && <MicOff color={'disabled'}/> }
{ !isSelf && <VolumeOff color={'disabled'}/> }
<VideocamOff color={'disabled'}/>
</div>
<video className="Video"></video>
</div>;
}
return <div className="MediaControl"> return <div className="MediaControl">
<div> <div>
{ isSelf && <div onClick={toggleMute}> { isSelf && <div onClick={toggleMute}>
{ muted && <MicOff color={'primary'}/> } { muted && <MicOff color={color}/> }
{ !muted && <Mic color={'primary'}/> } { !muted && <Mic color={color}/> }
</div> } </div> }
{ !isSelf && <div onClick={toggleMute}> { !isSelf && <div onClick={toggleMute}>
{ muted && <VolumeOff color={'primary'}/> } { muted && <VolumeOff color={color}/> }
{ !muted && <VolumeUp color={'primary'}/> } { !muted && <VolumeUp color={color}/> }
</div> } </div> }
<div onClick={toggleVideo}> <div onClick={toggleVideo}>
{ !videoOn && <VideocamOff color={'primary'}/> } { !videoOn && <VideocamOff color={color}/> }
{ videoOn && <Videocam color={'primary'}/> } { videoOn && <Videocam color={color}/> }
</div> </div>
</div> </div>
{ media && <Video className="Video" { isValid && <Video className="Video"
autoPlay='autoplay' autoPlay='autoplay'
{...media.attributes}/> {...media.attributes}/>
} }
{ !isValid && <video className="Video"></video> }
</div>; </div>;
}; };