Pepguy commited on
Commit
6d4d78a
·
verified ·
1 Parent(s): 289918b

Update app.js

Browse files
Files changed (1) hide show
  1. app.js +69 -20
app.js CHANGED
@@ -1,25 +1,38 @@
1
  // server.js
 
 
2
  const http = require('http');
3
  const WebSocket = require('ws');
4
  const mediasoup = require('mediasoup');
5
 
 
6
  const PORT = 7860;
 
 
 
 
7
  let worker, router;
8
  const producerTransports = new Map(); // ws → { transport, producer }
9
  const consumerTransports = new Map(); // ws → [ { transport, consumer } ]
10
 
11
- (async () => {
12
- // 1) Start HTTP + WebSocket server
13
- const server = http.createServer();
14
- const wss = new WebSocket.Server({ server });
15
- server.listen(PORT, () => console.log(`Server running on ${PORT}`));
16
-
17
- // 2) Create a single Mediasoup Worker + Router
18
  worker = await mediasoup.createWorker();
19
- router = await worker.createRouter({ mediaCodecs: [
20
- { kind: 'audio', mimeType: 'audio/opus', clockRate: 48000, channels: 2 },
21
- { kind: 'video', mimeType: 'video/VP8', clockRate: 90000 },
22
- ]});
 
 
 
 
 
 
 
 
 
 
 
23
 
24
  wss.on('connection', ws => {
25
  ws.on('message', async msg => {
@@ -27,12 +40,20 @@ const consumerTransports = new Map(); // ws → [ { transport, consumer } ]
27
 
28
  switch (action) {
29
  case 'createProducerTransport': {
30
- // Create transport for broadcaster
31
- const transport = await router.createWebRtcTransport({ listenIps: ['127.0.0.1'], enableUdp: true, enableTcp: true });
 
 
 
32
  producerTransports.set(ws, { transport, producer: null });
33
  ws.send(JSON.stringify({
34
  action: 'producerTransportCreated',
35
- data: { id: transport.id, iceParameters: transport.iceParameters, iceCandidates: transport.iceCandidates, dtlsParameters: transport.dtlsParameters }
 
 
 
 
 
36
  }));
37
  break;
38
  }
@@ -50,26 +71,36 @@ const consumerTransports = new Map(); // ws → [ { transport, consumer } ]
50
  const { transport } = producerTransports.get(ws);
51
  const producer = await transport.produce({ kind, rtpParameters });
52
  producerTransports.get(ws).producer = producer;
53
- ws.send(JSON.stringify({ action: 'produced', data: { producerId: producer.id } }));
 
 
 
54
  break;
55
  }
56
 
57
  case 'createConsumerTransport': {
58
- // Create transport for a viewer
59
- const transport = await router.createWebRtcTransport({ listenIps: ['127.0.0.1'], enableUdp: true, enableTcp: true });
 
 
 
60
  const arr = consumerTransports.get(ws) || [];
61
  arr.push({ transport, consumer: null });
62
  consumerTransports.set(ws, arr);
63
  ws.send(JSON.stringify({
64
  action: 'consumerTransportCreated',
65
- data: { id: transport.id, iceParameters: transport.iceParameters, iceCandidates: transport.iceCandidates, dtlsParameters: transport.dtlsParameters }
 
 
 
 
 
66
  }));
67
  break;
68
  }
69
 
70
  case 'connectConsumerTransport': {
71
  const { dtlsParameters } = data;
72
- // assume latest transport
73
  const arr = consumerTransports.get(ws);
74
  await arr[arr.length - 1].transport.connect({ dtlsParameters });
75
  ws.send(JSON.stringify({ action: 'consumerTransportConnected' }));
@@ -77,7 +108,6 @@ const consumerTransports = new Map(); // ws → [ { transport, consumer } ]
77
  }
78
 
79
  case 'consume': {
80
- // find the broadcaster’s producer
81
  const producerEntry = [...producerTransports.values()].find(e => e.producer);
82
  if (!producerEntry) {
83
  ws.send(JSON.stringify({ action: 'consumeError', data: 'No producer available yet' }));
@@ -107,5 +137,24 @@ const consumerTransports = new Map(); // ws → [ { transport, consumer } ]
107
  }
108
  }
109
  });
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
110
  });
 
 
 
111
  })();
 
1
  // server.js
2
+ const path = require('path');
3
+ const express = require('express');
4
  const http = require('http');
5
  const WebSocket = require('ws');
6
  const mediasoup = require('mediasoup');
7
 
8
+ const app = express();
9
  const PORT = 7860;
10
+
11
+ // Serve static files from ./public
12
+ app.use(express.static(path.join(__dirname, 'public')));
13
+
14
  let worker, router;
15
  const producerTransports = new Map(); // ws → { transport, producer }
16
  const consumerTransports = new Map(); // ws → [ { transport, consumer } ]
17
 
18
+ ;(async () => {
19
+ // 1) Create the mediasoup Worker + Router
 
 
 
 
 
20
  worker = await mediasoup.createWorker();
21
+ router = await worker.createRouter({
22
+ mediaCodecs: [
23
+ { kind: 'audio', mimeType: 'audio/opus', clockRate: 48000, channels: 2 },
24
+ { kind: 'video', mimeType: 'video/VP8', clockRate: 90000 }
25
+ ]
26
+ });
27
+
28
+ // 2) Expose RTP capabilities via HTTP for the clients
29
+ app.get('/rtpCapabilities', (req, res) => {
30
+ res.json({ rtpCapabilities: router.rtpCapabilities });
31
+ });
32
+
33
+ // 3) Create HTTP + WebSocket server
34
+ const server = http.createServer(app);
35
+ const wss = new WebSocket.Server({ server });
36
 
37
  wss.on('connection', ws => {
38
  ws.on('message', async msg => {
 
40
 
41
  switch (action) {
42
  case 'createProducerTransport': {
43
+ const transport = await router.createWebRtcTransport({
44
+ listenIps: ['127.0.0.1'],
45
+ enableUdp: true,
46
+ enableTcp: true
47
+ });
48
  producerTransports.set(ws, { transport, producer: null });
49
  ws.send(JSON.stringify({
50
  action: 'producerTransportCreated',
51
+ data: {
52
+ id: transport.id,
53
+ iceParameters: transport.iceParameters,
54
+ iceCandidates: transport.iceCandidates,
55
+ dtlsParameters: transport.dtlsParameters
56
+ }
57
  }));
58
  break;
59
  }
 
71
  const { transport } = producerTransports.get(ws);
72
  const producer = await transport.produce({ kind, rtpParameters });
73
  producerTransports.get(ws).producer = producer;
74
+ ws.send(JSON.stringify({
75
+ action: 'produced',
76
+ data: { producerId: producer.id }
77
+ }));
78
  break;
79
  }
80
 
81
  case 'createConsumerTransport': {
82
+ const transport = await router.createWebRtcTransport({
83
+ listenIps: ['127.0.0.1'],
84
+ enableUdp: true,
85
+ enableTcp: true
86
+ });
87
  const arr = consumerTransports.get(ws) || [];
88
  arr.push({ transport, consumer: null });
89
  consumerTransports.set(ws, arr);
90
  ws.send(JSON.stringify({
91
  action: 'consumerTransportCreated',
92
+ data: {
93
+ id: transport.id,
94
+ iceParameters: transport.iceParameters,
95
+ iceCandidates: transport.iceCandidates,
96
+ dtlsParameters: transport.dtlsParameters
97
+ }
98
  }));
99
  break;
100
  }
101
 
102
  case 'connectConsumerTransport': {
103
  const { dtlsParameters } = data;
 
104
  const arr = consumerTransports.get(ws);
105
  await arr[arr.length - 1].transport.connect({ dtlsParameters });
106
  ws.send(JSON.stringify({ action: 'consumerTransportConnected' }));
 
108
  }
109
 
110
  case 'consume': {
 
111
  const producerEntry = [...producerTransports.values()].find(e => e.producer);
112
  if (!producerEntry) {
113
  ws.send(JSON.stringify({ action: 'consumeError', data: 'No producer available yet' }));
 
137
  }
138
  }
139
  });
140
+
141
+ ws.on('close', () => {
142
+ // Clean up transports & producers/consumers for this ws
143
+ const pEntry = producerTransports.get(ws);
144
+ if (pEntry) {
145
+ pEntry.producer?.close();
146
+ pEntry.transport.close();
147
+ producerTransports.delete(ws);
148
+ }
149
+ const cEntries = consumerTransports.get(ws) || [];
150
+ cEntries.forEach(({ consumer, transport }) => {
151
+ consumer?.close();
152
+ transport.close();
153
+ });
154
+ consumerTransports.delete(ws);
155
+ });
156
  });
157
+
158
+ // 4) Start the server
159
+ server.listen(PORT, () => console.log(`SFU demo listening on http://localhost:${PORT}`));
160
  })();