Pepguy's picture
Update app.js
c663034 verified
raw
history blame
5.34 kB
// server.js
const path = require('path');
const express = require('express');
const http = require('http');
const WebSocket = require('ws');
const mediasoup = require('mediasoup');
const app = express();
const PORT = 7860;
// Serve static files from ./public
app.use(express.static(path.join(__dirname, 'public')));
let worker, router;
const producerTransports = new Map(); // ws → { transport, producer }
const consumerTransports = new Map(); // ws → [ { transport, consumer } ]
;(async () => {
// 1) Create the mediasoup Worker + Router
worker = await mediasoup.createWorker();
router = await worker.createRouter({
mediaCodecs: [
{ kind: 'audio', mimeType: 'audio/opus', clockRate: 48000, channels: 2 },
{ kind: 'video', mimeType: 'video/VP8', clockRate: 90000 }
]
});
// 2) Expose RTP capabilities via HTTP for the clients
app.get('/rtpCapabilities', (req, res) => {
res.json({ rtpCapabilities: router.rtpCapabilities });
});
// 3) Create HTTP + WebSocket server
const server = http.createServer(app);
const wss = new WebSocket.Server({ server });
wss.on('connection', ws => {
ws.on('message', async msg => {
const { action, data } = JSON.parse(msg);
switch (action) {
case 'createProducerTransport': {
const transport = await router.createWebRtcTransport({
listenIps: ['0.0.0.0'],
// listenIps: ['127.0.0.1'],
enableUdp: true,
enableTcp: true
});
producerTransports.set(ws, { transport, producer: null });
ws.send(JSON.stringify({
action: 'producerTransportCreated',
data: {
id: transport.id,
iceParameters: transport.iceParameters,
iceCandidates: transport.iceCandidates,
dtlsParameters: transport.dtlsParameters
}
}));
break;
}
case 'connectProducerTransport': {
const { dtlsParameters } = data;
const { transport } = producerTransports.get(ws);
await transport.connect({ dtlsParameters });
ws.send(JSON.stringify({ action: 'producerTransportConnected' }));
break;
}
case 'produce': {
const { kind, rtpParameters } = data;
const { transport } = producerTransports.get(ws);
const producer = await transport.produce({ kind, rtpParameters });
producerTransports.get(ws).producer = producer;
ws.send(JSON.stringify({
action: 'produced',
data: { producerId: producer.id }
}));
break;
}
case 'createConsumerTransport': {
const transport = await router.createWebRtcTransport({
listenIps: ['0.0.0.0'],
// listenIps: ['127.0.0.1'],
enableUdp: true,
enableTcp: true
});
const arr = consumerTransports.get(ws) || [];
arr.push({ transport, consumer: null });
consumerTransports.set(ws, arr);
ws.send(JSON.stringify({
action: 'consumerTransportCreated',
data: {
id: transport.id,
iceParameters: transport.iceParameters,
iceCandidates: transport.iceCandidates,
dtlsParameters: transport.dtlsParameters
}
}));
break;
}
case 'connectConsumerTransport': {
const { dtlsParameters } = data;
const arr = consumerTransports.get(ws);
await arr[arr.length - 1].transport.connect({ dtlsParameters });
ws.send(JSON.stringify({ action: 'consumerTransportConnected' }));
break;
}
case 'consume': {
const producerEntry = [...producerTransports.values()].find(e => e.producer);
if (!producerEntry) {
ws.send(JSON.stringify({ action: 'consumeError', data: 'No producer available yet' }));
return;
}
const producer = producerEntry.producer;
const arr = consumerTransports.get(ws);
const { transport } = arr[arr.length - 1];
const consumer = await transport.consume({
producerId: producer.id,
rtpCapabilities: router.rtpCapabilities,
paused: false
});
arr[arr.length - 1].consumer = consumer;
ws.send(JSON.stringify({
action: 'consumed',
data: {
producerId: producer.id,
id: consumer.id,
kind: consumer.kind,
rtpParameters: consumer.rtpParameters
}
}));
break;
}
}
});
ws.on('close', () => {
// Clean up transports & producers/consumers for this ws
const pEntry = producerTransports.get(ws);
if (pEntry) {
pEntry.producer?.close();
pEntry.transport.close();
producerTransports.delete(ws);
}
const cEntries = consumerTransports.get(ws) || [];
cEntries.forEach(({ consumer, transport }) => {
consumer?.close();
transport.close();
});
consumerTransports.delete(ws);
});
});
// 4) Start the server
server.listen(PORT, () => console.log(`SFU demo listening on http://localhost:${PORT}`));
})();