Spaces:
Sleeping
Sleeping
File size: 5,341 Bytes
42e18e6 6d4d78a 42e18e6 6d4d78a 42e18e6 6d4d78a 42e18e6 6d4d78a 42e18e6 6d4d78a 314b7d8 42e18e6 64a031b 42e18e6 6d4d78a c663034 6d4d78a 42e18e6 6d4d78a 42e18e6 64a031b 42e18e6 64a031b 42e18e6 6d4d78a 42e18e6 6d4d78a c663034 6d4d78a 42e18e6 6d4d78a 42e18e6 6d4d78a 42e18e6 6d4d78a 42e18e6 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 |
// 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}`));
})(); |