LINXD-2209-black-screen-when-2-video-calls-are-answered-simultaneously #3
138
app.js
138
app.js
@ -18,11 +18,7 @@ import Server from 'socket.io'
|
||||
import mediasoup, { getSupportedRtpCapabilities } from 'mediasoup'
|
||||
|
||||
let worker
|
||||
let router = {}
|
||||
let producerTransport
|
||||
let consumerTransport
|
||||
let producer
|
||||
let consumer
|
||||
let videoCalls = {}
|
||||
|
||||
app.get('/', (_req, res) => {
|
||||
res.send('Hello from mediasoup app!')
|
||||
@ -96,42 +92,16 @@ const mediaCodecs = [
|
||||
},
|
||||
]
|
||||
|
||||
let queue = []
|
||||
|
||||
// queue.push({
|
||||
// callId: 1,
|
||||
// callback: () => console.log('callback')
|
||||
// })
|
||||
// queue.push({
|
||||
// callId: 2,
|
||||
// callback: () => console.log('callback')
|
||||
// })
|
||||
// queue.push({
|
||||
// callId: 3,
|
||||
// callback: () => console.log('callback')
|
||||
// })
|
||||
|
||||
const getRtpCapabilities = (callId, callback) => {
|
||||
const rtpCapabilities = router[callId].rtpCapabilities
|
||||
callback({ rtpCapabilities })
|
||||
}
|
||||
|
||||
setInterval(async () => {
|
||||
if (queue.length > 0) {
|
||||
const { callId, callback } = queue.shift();
|
||||
if (router[callId] === undefined) {
|
||||
router[callId] = await worker.createRouter({ mediaCodecs })
|
||||
console.log(`[createRoom] Router ID: ${router[callId].id}`)
|
||||
}
|
||||
getRtpCapabilities(callId, callback)
|
||||
}
|
||||
}, 4000);
|
||||
const getRtpCapabilities = (callId, callback) => {
|
||||
console.log('[getRtpCapabilities] callId', callId);
|
||||
const rtpCapabilities = videoCalls[callId].router.rtpCapabilities;
|
||||
callback({ rtpCapabilities });
|
||||
}
|
||||
|
||||
peers.on('connection', async socket => {
|
||||
console.log('[connection] socketId:', socket.id)
|
||||
socket.emit('connection-success', {
|
||||
socketId: socket.id,
|
||||
existsProducer: producer ? true : false,
|
||||
socketId: socket.id
|
||||
})
|
||||
|
||||
socket.on('disconnect', () => {
|
||||
@ -140,23 +110,12 @@ peers.on('connection', async socket => {
|
||||
})
|
||||
|
||||
|
||||
socket.on('createRoom', async ({ callId }, callback) => {
|
||||
console.log('[createRoom] callId', callId);
|
||||
// console.log('Router length:', Object.keys(router).length);
|
||||
// if (router[callId] === undefined) {
|
||||
// // worker.createRouter(options)
|
||||
// // options = { mediaCodecs, appData }
|
||||
// // mediaCodecs -> defined above
|
||||
// // appData -> custom application data - we are not supplying any
|
||||
// // none of the two are required
|
||||
// router[callId] = await worker.createRouter({ mediaCodecs })
|
||||
// console.log(`[createRoom] Router ID: ${router[callId].id}`)
|
||||
// }
|
||||
|
||||
// getRtpCapabilities(callId, callback)
|
||||
queue.push({
|
||||
callId,
|
||||
callback
|
||||
})
|
||||
if (videoCalls[callId].router === undefined) {
|
||||
console.log('[createRoom] callId', callId);
|
||||
videoCalls[callId].router = await worker.createRouter({ mediaCodecs })
|
||||
console.log(`[createRoom] Router ID: ${videoCalls[callId].router.id}`)
|
||||
}
|
||||
getRtpCapabilities(callId, callback)
|
||||
})
|
||||
|
||||
// Client emits a request to create server side Transport
|
||||
@ -166,88 +125,88 @@ peers.on('connection', async socket => {
|
||||
// The client indicates if it is a producer or a consumer
|
||||
// if sender is true, indicates a producer else a consumer
|
||||
if (sender)
|
||||
producerTransport = await createWebRtcTransportLayer(callId, callback)
|
||||
videoCalls[callId].producerTransport = await createWebRtcTransportLayer(callId, callback)
|
||||
else
|
||||
consumerTransport = await createWebRtcTransportLayer(callId, callback)
|
||||
videoCalls[callId].consumerTransport = await createWebRtcTransportLayer(callId, callback)
|
||||
})
|
||||
|
||||
// see client's socket.emit('transport-connect', ...)
|
||||
socket.on('transport-connect', async ({ dtlsParameters }) => {
|
||||
socket.on('transport-connect', async ({ dtlsParameters, callId }) => {
|
||||
console.log('[transport-connect] DTLS PARAMS... ', { dtlsParameters })
|
||||
await producerTransport.connect({ dtlsParameters })
|
||||
await videoCalls[callId].producerTransport.connect({ dtlsParameters })
|
||||
})
|
||||
|
||||
// see client's socket.emit('transport-produce', ...)
|
||||
socket.on('transport-produce', async ({ kind, rtpParameters, appData }) => {
|
||||
socket.on('transport-produce', async ({ kind, rtpParameters, appData, callId }) => {
|
||||
cristi marked this conversation as resolved
Outdated
cristi
commented
For refactor: why do we need to differentiate between producerTransport and consumerTransport? Why don't we have a For refactor: why do we need to differentiate between producerTransport and consumerTransport? Why don't we have a `transport` variable (it is only one transport for each client regardless if they are producer or consumer)?
cristi
commented
We need producer and consumer transports for each call. We need producer and consumer transports for each call.
|
||||
// call produce based on the prameters from the client
|
||||
producer = await producerTransport.produce({
|
||||
videoCalls[callId].producer = await videoCalls[callId].producerTransport.produce({
|
||||
kind,
|
||||
rtpParameters,
|
||||
})
|
||||
console.log(`[transport-produce] Producer ID: ${producer.id} | kind: ${producer.kind}`)
|
||||
console.log(`[transport-produce] Producer ID: ${videoCalls[callId].producer.id} | kind: ${videoCalls[callId].producer.kind}`)
|
||||
|
||||
producer.on('transportclose', () => {
|
||||
videoCalls[callId].producer.on('transportclose', () => {
|
||||
console.log('transport for this producer closed', callId)
|
||||
|
||||
// https://mediasoup.org/documentation/v3/mediasoup/api/#producer-close
|
||||
producer.close()
|
||||
videoCalls[callId].producer.close()
|
||||
|
||||
// https://mediasoup.org/documentation/v3/mediasoup/api/#router-close
|
||||
router[callId].close()
|
||||
delete router[callId]
|
||||
videoCalls[callId].router.close()
|
||||
delete videoCalls[callId]
|
||||
})
|
||||
})
|
||||
|
||||
// see client's socket.emit('transport-recv-connect', ...)
|
||||
socket.on('transport-recv-connect', async ({ dtlsParameters }) => {
|
||||
socket.on('transport-recv-connect', async ({ dtlsParameters, callId }) => {
|
||||
console.log(`[transport-recv-connect] DTLS PARAMS: ${dtlsParameters}`)
|
||||
await consumerTransport.connect({ dtlsParameters })
|
||||
await videoCalls[callId].consumerTransport.connect({ dtlsParameters })
|
||||
})
|
||||
|
||||
socket.on('consume', async ({ rtpCapabilities, callId }, callback) => {
|
||||
console.log('[consume] callId', callId, router);
|
||||
console.log('[consume] callId', callId);
|
||||
try {
|
||||
// console.log('consume', rtpCapabilities, callId);
|
||||
// check if the router can consume the specified producer
|
||||
if (router[callId].canConsume({
|
||||
producerId: producer.id,
|
||||
if (videoCalls[callId].router.canConsume({
|
||||
producerId: videoCalls[callId].producer.id,
|
||||
rtpCapabilities
|
||||
})) {
|
||||
console.log('[consume] Can consume', callId);
|
||||
// transport can now consume and return a consumer
|
||||
consumer = await consumerTransport.consume({
|
||||
producerId: producer.id,
|
||||
videoCalls[callId].consumer = await videoCalls[callId].consumerTransport.consume({
|
||||
producerId: videoCalls[callId].producer.id,
|
||||
rtpCapabilities,
|
||||
paused: true,
|
||||
})
|
||||
|
||||
consumer.on('transportclose', () => {
|
||||
videoCalls[callId].consumer.on('transportclose', () => {
|
||||
console.log('transport close from consumer', callId)
|
||||
|
||||
// https://mediasoup.org/documentation/v3/mediasoup/api/#router-close
|
||||
router[callId].close()
|
||||
delete router[callId]
|
||||
producer.close()
|
||||
consumer.close()
|
||||
stvideoCallsate[callId].router.close()
|
||||
delete videoCalls[callId].router
|
||||
videoCalls[callId].producer.close()
|
||||
videoCalls[callId].consumer.close()
|
||||
})
|
||||
|
||||
consumer.on('producerclose', () => {
|
||||
videoCalls[callId].consumer.on('producerclose', () => {
|
||||
console.log('producer of consumer closed', callId)
|
||||
|
||||
// https://mediasoup.org/documentation/v3/mediasoup/api/#router-close
|
||||
router[callId].close()
|
||||
delete router[callId]
|
||||
producer.close()
|
||||
consumer.close()
|
||||
videoCalls[callId].router.close()
|
||||
delete videoCalls[callId].router
|
||||
videoCalls[callId].producer.close()
|
||||
videoCalls[callId].consumer.close()
|
||||
})
|
||||
|
||||
// from the consumer extract the following params
|
||||
// to send back to the Client
|
||||
const params = {
|
||||
id: consumer.id,
|
||||
producerId: producer.id,
|
||||
kind: consumer.kind,
|
||||
rtpParameters: consumer.rtpParameters,
|
||||
id: videoCalls[callId].consumer.id,
|
||||
producerId: videoCalls[callId].producer.id,
|
||||
kind: videoCalls[callId].consumer.kind,
|
||||
rtpParameters: videoCalls[callId].consumer.rtpParameters,
|
||||
}
|
||||
|
||||
// send the parameters to the client
|
||||
@ -265,9 +224,9 @@ peers.on('connection', async socket => {
|
||||
}
|
||||
})
|
||||
|
||||
socket.on('consumer-resume', async () => {
|
||||
socket.on('consumer-resume', async ({ callId }) => {
|
||||
console.log(`[consumer-resume]`)
|
||||
await consumer.resume()
|
||||
await videoCalls[callId].consumer.resume()
|
||||
})
|
||||
})
|
||||
|
||||
@ -288,10 +247,9 @@ const createWebRtcTransportLayer = async (callId, callback) => {
|
||||
}
|
||||
|
||||
// console.log('webRtcTransport_options', webRtcTransport_options);
|
||||
// console.log('router', router, '| router[callId]', router[callId]);
|
||||
|
||||
// https://mediasoup.org/documentation/v3/mediasoup/api/#router-createWebRtcTransport
|
||||
let transport = await router[callId].createWebRtcTransport(webRtcTransport_options)
|
||||
let transport = await videoCalls[callId].router.createWebRtcTransport(webRtcTransport_options)
|
||||
console.log(`callId: ${callId} | transport id: ${transport.id}`)
|
||||
|
||||
transport.on('dtlsstatechange', dtlsState => {
|
||||
|
Loading…
Reference in New Issue
Block a user
not important: we don't need socket.id on clients