Basically i was creating a full mesh network for a video conferencing application and I cant understand how to display other peers video for every user. The part of sending offer and receiving answer along with ICE candidates have been achieved but i still cant figure out how to make peer.ontrack
work. Below i will be attaching my server side(Node js) code with front-end code(React).
The code is fairly easy and simple i would love and be grateful if someone can help. I have almst spent three days figuring out and have wasted alot of time. I would be glad for any sort of response.
Server Side:
import express from 'express'
import bodyParser from 'body-parser'
import * as socket from "socket.io";
import cors from 'cors'
const app = express()
app.use(bodyParser.urlencoded({ extended: false }))
app.use(bodyParser.json())
const corsOptions = {
origin: 'http://localhost:3000',
credentials: true,
methods: 'GET,POST,PUT, DELETE, OPTIONS',
allowedHeaders: "Origin, Content-type, Accept, Authorization, x-xsrf-token"
}
app.use(cors(corsOptions))
const server = require('http').Server(app);
let io = require("socket.io")(server, {
cors: {
origin: "http://localhost:3000",
methods: ["GET", "POST"]
}
});
app.get("/something", (req, res, next) => {
// (req as any).name = "faheel"
})
interface RoomType {
[key: string]: {
[key: string]: socket.Socket
}
}
interface SocketToRoomType {
[key: string]: string
}
interface SocketType {
[key: string]: socket.Socket
}
const rooms: RoomType = {}
const sockets: SocketType = {}
const sockettoroom: SocketToRoomType = {};
io.on("connection", (socket: socket.Socket) => {
sockets[socket.id] = socket
console.log('[' + socket.id + '] connection accepted')
socket.on('join', config => {
console.log('[' + socket.id + '] join ', config);
if (!rooms[config.roomid]) {
console.log("Create the room")
rooms[config.roomid] ={}
}
for (let id in rooms[config.roomid]) {
console.log(id)
rooms[config.roomid][id].emit('addPeer', { peer_id: socket.id, should_create_offer: false });
socket.emit('addPeer', { peer_id: id, should_create_offer: true });
}
rooms[config.roomid][socket.id] = socket;
console.log(Object.keys(rooms[config.roomid]))
})
socket.on('relayICECandidate', config => {
let peer_id = config.peer_id;
let ice_candidate = config.ice_candidate;
console.log('[' + socket.id + '] relay ICE-candidate to [' + peer_id + '] ', ice_candidate);
if (peer_id in sockets) {
sockets[peer_id].emit('iceCandidate', { peer_id: socket.id, ice_candidate: ice_candidate });
}
});
socket.on('relaySessionDescription', config => {
let peer_id = config.peer_id;
let session_description = config.session_description;
let type = config.type
console.log('[' + socket.id + '] relay SessionDescription to [' + peer_id + '] ',session_description)
if (peer_id in sockets) {
sockets[peer_id].emit('sessionDescription', {
peer_id: socket.id,
session_description: session_description,
type: type
});
}
})
})
server.listen(4000, () => {
console.log("Server up an running")
})
Front-end:
import React, { useRef, useEffect, useState } from "react";
import { useParams } from 'react-router-dom'
import io from "socket.io-client";
const Video = (props) => {
const ref = useRef();
useEffect(() => {
console.log(props.peer)
// ref.current.srcObject = props.vid
}, []);
return (
<video playsInline autoPlay ref={ref} />
);
}
const Room1 = () => {
const [peers, setPeers] = useState({})
const socket = io.connect("http://localhost:4000")
const localMediaStream = useRef(null)
const userstream = useRef();
const peerMediaElements = useRef({})
const params = useParams()
const [refresh, setRefresh] = useState(false)
useEffect(() => {
navigator.mediaDevices.getUserMedia({ audio: true, video: true }).then(stream => {
localMediaStream.current.srcObject = stream
userstream.current = stream
joinRoom()
})
socket.on("addPeer", (config) => {
const peerid = config.peer_id
if (peerid in peers) {
return
}
if (peerid in peers) return
const peer = addPeer(config)
const peerobjcreator = {
[peerid]: peer
}
console.log("Before adding peer", peers)
peers[peerid] = peer
setPeers(peers)
setRefresh(!refresh)
console.log("After adding peer", peers)
// if (config.should_create_offer) {
// createOffer(peerid, peer)
// }
})
socket.on("sessionDescription", (config) => {
createAnswer(config)
})
}, [])
const joinRoom = () => {
socket.emit("join", { roomid: params.roomid, userdate: {} })
}
const addPeer = (config) => {
const peerid = config.peer_id
const peer = new RTCPeerConnection({
iceServers: [
{
urls: "stun:stun.stunprotocol.org"
},
{
urls: 'turn:numb.viagenie.ca',
credential: 'muazkh',
username: '[email protected]'
},
]
})
peer.onicecandidate = (event) => {
if (event.candidate) {
socket.emit('relayICECandidate', {
peer_id: peerid,
ice_candidate: {
sdpMLineIndex: event.candidate.sdpMLineIndex,
candidate: event.candidate.candidate
}
});
}
}
userstream.current.getTracks().forEach(track => {
console.log("tRACK", track)
peer.addTrack(track, userstream.current)
})
if (config.should_create_offer) {
peer.onnegotiationneeded = createOffer(peerid, peer)
}
peer.ontrack = (event) => {
console.log("HeLO", event.streams[0])
peerMediaElements.current[peerid] = event.streams[0]
}
return peer
}
const createOffer = (peerid, peer) => {
console.log("Creating offer")
peer.createOffer().then(offer => {
return peer.setLocalDescription(offer);
}).then(() => {
const payload = {
peer_id: peerid,
session_description: peer.localDescription,
type: "offer"
};
socket.emit("relaySessionDescription", payload);
}).catch(e => console.log(e));
}
const createAnswer = (config) => {
console.log(config)
const peerid = config.peer_id
console.log(peers)
const peer = peers[peerid]
const remotedescription = config.session_description
const desc = new RTCSessionDescription(remotedescription)
const stuff = peer.setRemoteDescription(desc, () => {
if (remotedescription.type === "offer") {
console.log("Creating answer")
peer.createAnswer((localdescription) => {
console.log("Answer created")
peer.setLocalDescription(localdescription,
() => {
const payload = {
peer_id: peerid,
session_description: localdescription,
type: "answer"
}
socket.emit("relaySessionDescription", payload);
},
(err) => {
console.log("Answer setlocation failed", err)
})
},
(err) => {
console.log("Error creating answer", err)
})
}
},
(err) => {
console.log("Set remote description error", err)
})
}
return (
<div>
<video autoPlay ref={localMediaStream} />
{console.log(peerMediaElements.current)}
{
Object.keys(peerMediaElements.current).map(peerid => console.log(peerid))
}
</div>
)
}
export default Room1
question from:
https://stackoverflow.com/questions/65662268/cant-understand-how-to-show-remote-peers-video-in-my-react-based-video-conferenc