Allow non-media players to connect to other players
Signed-off-by: James Ketrenos <james_eikona@ketrenos.com>
This commit is contained in:
parent
0bab275447
commit
ec557e6926
@ -78,6 +78,29 @@ const MediaAgent = ({setPeers}) => {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
/* 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,
|
||||||
|
hasAudio: config.hasAudio,
|
||||||
|
hasVideo: config.hasVideo,
|
||||||
|
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);
|
||||||
|
setPeers(Object.assign({}, peers));
|
||||||
|
|
||||||
const connection = new RTCPeerConnection({
|
const connection = new RTCPeerConnection({
|
||||||
configuration: {
|
configuration: {
|
||||||
offerToReceiveAudio: true,
|
offerToReceiveAudio: true,
|
||||||
@ -97,30 +120,16 @@ const MediaAgent = ({setPeers}) => {
|
|||||||
*/
|
*/
|
||||||
]
|
]
|
||||||
});
|
});
|
||||||
|
peer.connection = connection;
|
||||||
/* 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,
|
|
||||||
connection,
|
|
||||||
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);
|
|
||||||
setPeers(Object.assign({}, peers));
|
|
||||||
|
|
||||||
connection.addEventListener('connectionstatechange', (event) => {
|
connection.addEventListener('connectionstatechange', (event) => {
|
||||||
console.log(`media-agent - connectionstatechange - `, connection.connectionState, event);
|
console.log(`media-agent - connectionstatechange - `,
|
||||||
|
connection.connectionState, event);
|
||||||
|
});
|
||||||
|
|
||||||
|
connection.addEventListener('negotiationneeded', (event) => {
|
||||||
|
console.log(`media-agent - negotiationneeded - `,
|
||||||
|
connection.connectionState, event);
|
||||||
});
|
});
|
||||||
|
|
||||||
connection.addEventListener('icecandidateerror', (event) => {
|
connection.addEventListener('icecandidateerror', (event) => {
|
||||||
@ -163,7 +172,7 @@ const MediaAgent = ({setPeers}) => {
|
|||||||
connection.ontrack = e => refOnTrack.current(e);
|
connection.ontrack = e => refOnTrack.current(e);
|
||||||
|
|
||||||
/* Add our local stream */
|
/* Add our local stream */
|
||||||
connection.addStream(stream);
|
connection.addStream(stream.media);
|
||||||
|
|
||||||
/* Only one side of the peer connection should create the
|
/* Only one side of the peer connection should create the
|
||||||
* offer, the signaling server picks one to be the offerer.
|
* offer, the signaling server picks one to be the offerer.
|
||||||
@ -172,10 +181,12 @@ const MediaAgent = ({setPeers}) => {
|
|||||||
* to us
|
* to us
|
||||||
*/
|
*/
|
||||||
if (config.should_create_offer) {
|
if (config.should_create_offer) {
|
||||||
if (debug) console.log(`media-agent - Creating RTC offer to ${peer_id}`);
|
if (debug) console.log(`media-agent - Creating RTC offer to ` +
|
||||||
|
`${peer_id}`);
|
||||||
return connection.createOffer()
|
return connection.createOffer()
|
||||||
.then((local_description) => {
|
.then((local_description) => {
|
||||||
if (debug) console.log(`media-agent - Local offer description is: `, local_description);
|
if (debug) console.log(`media-agent - Local offer ` +
|
||||||
|
`description is: `, local_description);
|
||||||
return connection.setLocalDescription(local_description)
|
return connection.setLocalDescription(local_description)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
sendMessage({
|
sendMessage({
|
||||||
@ -185,7 +196,8 @@ const MediaAgent = ({setPeers}) => {
|
|||||||
'session_description': local_description
|
'session_description': local_description
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
if (debug) console.log(`media-agent - Offer setLocalDescription succeeded`);
|
if (debug) console.log(`media-agent - Offer ` +
|
||||||
|
`setLocalDescription succeeded`);
|
||||||
})
|
})
|
||||||
.catch((error) => {
|
.catch((error) => {
|
||||||
console.error(`media-agent - Offer setLocalDescription failed!`);
|
console.error(`media-agent - Offer setLocalDescription failed!`);
|
||||||
@ -200,17 +212,21 @@ const MediaAgent = ({setPeers}) => {
|
|||||||
const sessionDescription = ({ peer_id, session_description }) => {
|
const sessionDescription = ({ peer_id, session_description }) => {
|
||||||
const peer = peers[peer_id];
|
const peer = peers[peer_id];
|
||||||
if (!peer) {
|
if (!peer) {
|
||||||
console.error(`media-agent - sessionDescription - No peer for ${peer_id}`);
|
console.error(`media-agent - sessionDescription - ` +
|
||||||
|
`No peer for ${peer_id}`);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const { connection } = peer;
|
const { connection } = peer;
|
||||||
const desc = new RTCSessionDescription(session_description);
|
const desc = new RTCSessionDescription(session_description);
|
||||||
return connection.setRemoteDescription(desc, () => {
|
return connection.setRemoteDescription(desc, () => {
|
||||||
if (debug) console.log(`media-agent - sessionDescription - setRemoteDescription succeeded`);
|
if (debug) console.log(`media-agent - sessionDescription - ` +
|
||||||
|
`setRemoteDescription succeeded`);
|
||||||
if (session_description.type === "offer") {
|
if (session_description.type === "offer") {
|
||||||
if (debug) console.log(`media-agent - sessionDescription - Creating answer`);
|
if (debug) console.log(`media-agent - sessionDescription - ` +
|
||||||
|
`Creating answer`);
|
||||||
connection.createAnswer((local_description) => {
|
connection.createAnswer((local_description) => {
|
||||||
if (debug) console.log(`media-agent - sessionDescription - Answer description is: `, local_description);
|
if (debug) console.log(`media-agent - sessionDescription - ` +
|
||||||
|
`Answer description is: `, local_description);
|
||||||
connection.setLocalDescription(local_description, () => {
|
connection.setLocalDescription(local_description, () => {
|
||||||
sendMessage({
|
sendMessage({
|
||||||
type: 'relaySessionDescription',
|
type: 'relaySessionDescription',
|
||||||
@ -219,21 +235,25 @@ const MediaAgent = ({setPeers}) => {
|
|||||||
session_description: local_description
|
session_description: local_description
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
if (debug) console.log(`media-agent - sessionDescription - Answer setLocalDescription succeeded`);
|
if (debug) console.log(`media-agent - sessionDescription ` +
|
||||||
|
`- Answer setLocalDescription succeeded`);
|
||||||
}, () => {
|
}, () => {
|
||||||
console.error(`media-agent - sessionDescription - Answer setLocalDescription failed!`);
|
console.error(`media-agent - sessionDescription - ` +
|
||||||
|
`Answer setLocalDescription failed!`);
|
||||||
});
|
});
|
||||||
}, (error) => {
|
}, (error) => {
|
||||||
console.error(error);
|
console.error(error);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}, (error) => {
|
}, (error) => {
|
||||||
console.log(`media-agent - sessionDescription - setRemoteDescription error: `, error);
|
console.log(`media-agent - sessionDescription - ` +
|
||||||
|
`setRemoteDescription error: `, error);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const removePeer = ({peer_id}) => {
|
const removePeer = ({peer_id}) => {
|
||||||
console.log(`media-agent - removePeer - Signaling server said to remove peer ${peer_id}`);
|
console.log(`media-agent - removePeer - Signaling server said to ` +
|
||||||
|
`remove peer ${peer_id}`);
|
||||||
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();
|
||||||
@ -256,12 +276,14 @@ const MediaAgent = ({setPeers}) => {
|
|||||||
*/
|
*/
|
||||||
const peer = peers[peer_id];
|
const peer = peers[peer_id];
|
||||||
if (!peer) {
|
if (!peer) {
|
||||||
console.error(`media-agent - iceCandidate - No peer for ${peer_id}`, peers);
|
console.error(`media-agent - iceCandidate - No peer for ` +
|
||||||
|
`${peer_id}`, peers);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
peer.connection.addIceCandidate(new RTCIceCandidate(candidate))
|
peer.connection.addIceCandidate(new RTCIceCandidate(candidate))
|
||||||
.then(() => {
|
.then(() => {
|
||||||
if (debug) console.log(`media-agent - iceCandidate - Successfully added Ice Candidate for ${peer_id}`);
|
if (debug) console.log(`media-agent - iceCandidate - ` +
|
||||||
|
`Successfully added Ice Candidate for ${peer_id}`);
|
||||||
})
|
})
|
||||||
.catch((error) => {
|
.catch((error) => {
|
||||||
console.error(error, peer, candidate);
|
console.error(error, peer, candidate);
|
||||||
@ -269,7 +291,8 @@ const MediaAgent = ({setPeers}) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const data = JSON.parse(event.data);
|
const data = JSON.parse(event.data);
|
||||||
if (data.type in [ 'addPeer', 'removePeer', 'iceCandidate', 'sessionDescription' ]) {
|
if (data.type in [ 'addPeer', 'removePeer',
|
||||||
|
'iceCandidate', 'sessionDescription' ]) {
|
||||||
console.log(`media-agent - message - ${data.type}`, peers);
|
console.log(`media-agent - message - ${data.type}`, peers);
|
||||||
}
|
}
|
||||||
switch (data.type) {
|
switch (data.type) {
|
||||||
@ -329,7 +352,13 @@ const MediaAgent = ({setPeers}) => {
|
|||||||
console.log(`media-control - WebSocket or Stream changed`);
|
console.log(`media-control - WebSocket or Stream changed`);
|
||||||
|
|
||||||
const join = () => {
|
const join = () => {
|
||||||
sendMessage({ type: 'join' });
|
sendMessage({
|
||||||
|
type: 'join',
|
||||||
|
config: {
|
||||||
|
hasAudio: stream.audio,
|
||||||
|
hasVideo: stream.video
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ws && stream) {
|
if (ws && stream) {
|
||||||
@ -359,9 +388,11 @@ const MediaAgent = ({setPeers}) => {
|
|||||||
local: true,
|
local: true,
|
||||||
muted: true,
|
muted: true,
|
||||||
videoOn: false,
|
videoOn: false,
|
||||||
|
hasVideo: stream.video,
|
||||||
|
hasAudio: stream.audio,
|
||||||
attributes: {
|
attributes: {
|
||||||
local: true,
|
local: true,
|
||||||
srcObject: stream
|
srcObject: stream.media
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -390,10 +421,11 @@ const MediaAgent = ({setPeers}) => {
|
|||||||
const setup_local_media = () => {
|
const setup_local_media = () => {
|
||||||
/* Ask user for permission to use the computers microphone and/or camera,
|
/* Ask user for permission to use the computers microphone and/or camera,
|
||||||
* attach it to an <audio> or <video> tag if they give us access. */
|
* attach it to an <audio> or <video> tag if they give us access. */
|
||||||
console.log("media-agent - Requesting access to local audio / video inputs");
|
console.log(`media-agent - Requesting access to local ` +
|
||||||
|
`audio / video inputs`);
|
||||||
|
|
||||||
/* See Dummy Tracks for more ideas...
|
/* See Dummy Tracks for more ideas...
|
||||||
https://blog.mozilla.org/webrtc/warm-up-with-replacetrack/
|
* https://blog.mozilla.org/webrtc/warm-up-with-replacetrack/
|
||||||
*/
|
*/
|
||||||
navigator.getUserMedia = (navigator.getUserMedia ||
|
navigator.getUserMedia = (navigator.getUserMedia ||
|
||||||
navigator.webkitGetUserMedia ||
|
navigator.webkitGetUserMedia ||
|
||||||
@ -453,7 +485,7 @@ const MediaAgent = ({setPeers}) => {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
return context.media;
|
return context;
|
||||||
}
|
}
|
||||||
|
|
||||||
const black = ({ width = 640, height = 480 } = {}) => {
|
const black = ({ width = 640, height = 480 } = {}) => {
|
||||||
@ -489,23 +521,26 @@ const MediaAgent = ({setPeers}) => {
|
|||||||
enabled: true
|
enabled: true
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
return new MediaStream([context.media, black()]);
|
context.media = new MediaStream([context.media, black()]);
|
||||||
|
return context;
|
||||||
}
|
}
|
||||||
|
|
||||||
return new MediaStream([black(), silence()]);
|
context.media = new MediaStream([black(), silence()]);
|
||||||
|
return context;
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
let abort = false;
|
let abort = false;
|
||||||
if (!stream) {
|
if (!stream) {
|
||||||
if (debug) console.log(`media-agent - WebSocket open request. Attempting to create local media.`);
|
if (debug) console.log(`media-agent - WebSocket open request. ` +
|
||||||
setup_local_media().then((media) => {
|
`Attempting to create local media.`);
|
||||||
|
setup_local_media().then((context) => {
|
||||||
/* once the user has given us access to their
|
/* once the user has given us access to their
|
||||||
* microphone/camcorder, join the channel and start peering up */
|
* microphone/camcorder, join the channel and start peering up */
|
||||||
if (abort) {
|
if (abort) {
|
||||||
console.log(`media-agent - aborting setting local media`);
|
console.log(`media-agent - aborting setting local media`);
|
||||||
} else {
|
} else {
|
||||||
setStream(media);
|
setStream(context);
|
||||||
}
|
}
|
||||||
}).catch((error) => { /* user denied access to a/v */
|
}).catch((error) => { /* user denied access to a/v */
|
||||||
console.error(error);
|
console.error(error);
|
||||||
@ -565,7 +600,7 @@ const MediaControl = ({isSelf, peer, className}) => {
|
|||||||
if (media.attributes.srcObject) {
|
if (media.attributes.srcObject) {
|
||||||
console.log(`media-control - audio enable - ${peer.name}:${!muted}`);
|
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 = media.hasAudio && !muted;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}); /* run after every render to hit when ontrack has received and set
|
}); /* run after every render to hit when ontrack has received and set
|
||||||
@ -578,28 +613,29 @@ const MediaControl = ({isSelf, peer, className}) => {
|
|||||||
if (media.attributes.srcObject) {
|
if (media.attributes.srcObject) {
|
||||||
console.log(`media-control - video enable - ${peer.name}:${videoOn}`);
|
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 = media.hasVideo && videoOn;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}); /* run after every render to hit when ontrack has received and set
|
}); /* run after every render to hit when ontrack has received and set
|
||||||
* the stream //, [media, videoOn]); */
|
* the stream //, [media, videoOn]); */
|
||||||
|
|
||||||
const isValid = media && !media.dead,
|
const isValid = media && !media.dead,
|
||||||
color = isValid ? 'primary' : 'disabled';
|
colorAudio = (isValid && media.hasAudio) ? 'primary' : 'disabled',
|
||||||
|
colorVideo = (isValid && media.hasVideo) ? 'primary' : 'disabled';
|
||||||
|
|
||||||
return <div className={`MediaControl ${className}`}>
|
return <div className={`MediaControl ${className}`}>
|
||||||
<div className="Controls" >
|
<div className="Controls" >
|
||||||
{ isSelf && <div onClick={toggleMute}>
|
{ isSelf && <div onClick={toggleMute}>
|
||||||
{ muted && <MicOff color={color}/> }
|
{ muted && <MicOff color={colorAudio}/> }
|
||||||
{ !muted && <Mic color={color}/> }
|
{!muted && <Mic color={colorAudio}/> }
|
||||||
</div> }
|
</div> }
|
||||||
{ !isSelf && <div onClick={toggleMute}>
|
{ !isSelf && <div onClick={toggleMute}>
|
||||||
{ muted && <VolumeOff color={color}/> }
|
{muted && <VolumeOff color={colorAudio}/> }
|
||||||
{ !muted && <VolumeUp color={color}/> }
|
{!muted && <VolumeUp color={colorAudio}/> }
|
||||||
</div> }
|
</div> }
|
||||||
<div onClick={toggleVideo}>
|
<div onClick={toggleVideo}>
|
||||||
{ !videoOn && <VideocamOff color={color}/> }
|
{ !videoOn && <VideocamOff color={colorVideo}/> }
|
||||||
{ videoOn && <Videocam color={color}/> }
|
{videoOn && <Videocam color={colorVideo}/> }
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{ isValid && <Video className="Video"
|
{ isValid && <Video className="Video"
|
||||||
|
@ -2961,7 +2961,7 @@ const resetDisconnectCheck = (game, req) => {
|
|||||||
//req.disconnectCheck = setTimeout(() => { wsInactive(game, req) }, 20000);
|
//req.disconnectCheck = setTimeout(() => { wsInactive(game, req) }, 20000);
|
||||||
}
|
}
|
||||||
|
|
||||||
const join = (peers, session) => {
|
const join = (peers, session, { hasVideo, hasAudio }) => {
|
||||||
const ws = session.ws;
|
const ws = session.ws;
|
||||||
|
|
||||||
if (!session.name) {
|
if (!session.name) {
|
||||||
@ -2978,19 +2978,34 @@ const join = (peers, session) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (let peer in peers) {
|
for (let peer in peers) {
|
||||||
peers[peer].send(JSON.stringify({
|
/* Add this caller to all peers */
|
||||||
|
peers[peer].ws.send(JSON.stringify({
|
||||||
type: 'addPeer',
|
type: 'addPeer',
|
||||||
data: { 'peer_id': session.name, 'should_create_offer': false }
|
data: {
|
||||||
|
peer_id: session.name,
|
||||||
|
should_create_offer: false,
|
||||||
|
hasAudio, hasVideo
|
||||||
|
}
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
/* Add each other peer to the caller */
|
||||||
ws.send(JSON.stringify({
|
ws.send(JSON.stringify({
|
||||||
type: 'addPeer',
|
type: 'addPeer',
|
||||||
data: {'peer_id': peer, 'should_create_offer': true}
|
data: {
|
||||||
|
peer_id: peer,
|
||||||
|
should_create_offer: true,
|
||||||
|
hasAudio: peers[peer].hasAudio,
|
||||||
|
hasVideo: peers[peer].hasVideo
|
||||||
|
}
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Add this user as a peer connected to this WebSocket */
|
/* Add this user as a peer connected to this WebSocket */
|
||||||
peers[session.name] = ws;
|
peers[session.name] = {
|
||||||
|
ws,
|
||||||
|
hasAudio,
|
||||||
|
hasVideo
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
const part = (peers, session) => {
|
const part = (peers, session) => {
|
||||||
@ -3014,7 +3029,7 @@ const part = (peers, session) => {
|
|||||||
/* Remove this peer from all other peers, and remove each
|
/* Remove this peer from all other peers, and remove each
|
||||||
* peer from this peer */
|
* peer from this peer */
|
||||||
for (let peer in peers) {
|
for (let peer in peers) {
|
||||||
peers[peer].send(JSON.stringify({
|
peers[peer].ws.send(JSON.stringify({
|
||||||
type: 'removePeer',
|
type: 'removePeer',
|
||||||
data: {'peer_id': session.name}
|
data: {'peer_id': session.name}
|
||||||
}));
|
}));
|
||||||
@ -3533,7 +3548,7 @@ router.ws("/ws/:id", async (ws, req) => {
|
|||||||
|
|
||||||
switch (data.type) {
|
switch (data.type) {
|
||||||
case 'join':
|
case 'join':
|
||||||
join(audio[id], session);
|
join(audio[id], session, data.config);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'part':
|
case 'part':
|
||||||
@ -3556,7 +3571,7 @@ router.ws("/ws/:id", async (ws, req) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (peer_id in audio[id]) {
|
if (peer_id in audio[id]) {
|
||||||
audio[id][peer_id].send(message);
|
audio[id][peer_id].ws.send(message);
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
@ -3573,7 +3588,7 @@ router.ws("/ws/:id", async (ws, req) => {
|
|||||||
data: {'peer_id': getName(session), 'session_description': session_description }
|
data: {'peer_id': getName(session), 'session_description': session_description }
|
||||||
});
|
});
|
||||||
if (peer_id in audio[id]) {
|
if (peer_id in audio[id]) {
|
||||||
audio[id][peer_id].send(message);
|
audio[id][peer_id].ws.send(message);
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user