23
23
24
24
25
25
import alawmulaw from 'alawmulaw' ; // For now, move to codec.mjs later.
26
+ import dgram from 'dgram' ;
27
+ import { Codec } from './codec.mjs' ;
26
28
27
29
const Payload = {
28
30
Mulaw8K : 0 ,
@@ -275,14 +277,73 @@ class RTPHeader {
275
277
}
276
278
277
279
/**
278
- * Temporary class - replace with RTPPacket instances when you work out how.
280
+ * Should provide a source and sink for RTP Packets. For now, hardcode to the correct values for Combadge audio.
281
+ *
282
+ * Down the line, we should generalise this to allow the library to be reused elsewhere -
283
+ * (since I wouldn't be writing it if there was another approachable JS RTP library)
279
284
*/
280
- class RTPStream {
281
- constructor ( ) {
285
+ class RTPServer {
286
+ constructor ( listenAddress , portNumber , consumer = undefined ) {
282
287
this . sampleCount = new Number ( 160 ) ; // At 8 bits/sample, this can be used for both incrementing the timestamp AND counting bytes.
283
288
this . header = new RTPHeader ( this . sampleCount ) ;
289
+ this . _consumer = undefined ;
290
+
291
+ if ( portNumber % 2 != 0 ) {
292
+ throw `RTP Ports must be even. Odd-numbered ports are reserved for RTCP. Invalid port ${ portNumber } passed.` ;
293
+ }
294
+
295
+ if ( consumer ) {
296
+ this . _consumer = consumer ;
297
+ }
298
+
299
+ this . udpServer = dgram . createSocket ( 'udp4' ) ;
300
+ this . udpServer . bind ( portNumber , listenAddress )
301
+ this . udpServer . on ( 'listening' , ( ) => {
302
+ const address = this . udpServer . address ( ) ;
303
+ console . log ( `RTP Server spawned at ${ address . address } :${ address . port } ` ) ;
304
+ } )
305
+ this . udpServer . on ( 'message' , ( message , clientInfo ) => {
306
+ var packet = RTPPacket . from ( message ) ;
307
+ this . receivePacket ( packet ) ;
308
+ } )
309
+
310
+ /*
311
+ this.transcoding = true;
312
+ var floatSamples=Float32Array.from(Float32Array.from(this.recSamples).map(x=>x/0x8000));
313
+ var newSamples = waveResampler.resample(floatSamples, 8000, 16000); // RETURNS A FLOAT64 NOT AN INT16 READ THE DOCS
314
+ var samples1616=Int16Array.from(newSamples.map(x => (x>0 ? x*0x7FFF : x*0x8000)));
315
+ var wav16buffer = new Buffer.from(samples1616.buffer);
316
+ console.log("Result:", model.stt(wav16buffer));
317
+ this.transcoding = false;
318
+ */
319
+ }
320
+
321
+ /**
322
+ * Function to pass in a function to receive audio from the server.
323
+ */
324
+ set consumer ( consumer ) {
325
+ this . _consumer = consumer ;
326
+ }
327
+
328
+ get consumer ( ) {
329
+ return this . _consumer ;
330
+ }
331
+
332
+ /** Do something with the packet, then forward it to the Consumer if set, or cache it if not. */
333
+ receivePacket ( packet ) {
334
+ var samples = Codec . resampleOld ( packet . payload ) ;
335
+ this . consumer . receiveSamples ( samples ) ;
284
336
}
285
337
338
+ /**
339
+ * Send audio to a remote device. We'll be explicit about target, rather than just using send() from the responder
340
+ * because otherwise I can already see an exploit where a snooper sends 0-length packets to ensure they're always the most recent address.
341
+ * socket.send(msg[, offset, length][, port][, address][, callback])
342
+ */
343
+ sendPacket ( packet , address , port ) {
344
+ packetData = packet . toBuffer ( )
345
+ this . udpServer . send ( packetData , 0 , packetData . length , port , address )
346
+ }
286
347
287
348
/**
288
349
* Return a completed media packet without transcoding.
@@ -308,25 +369,4 @@ class RTPStream {
308
369
}
309
370
}
310
371
311
- class MediaQueue {
312
- constructor ( ) {
313
- this . inQueue = new Array ( ) ;
314
- this . outQueue = new Array ( ) ;
315
- }
316
-
317
- /**
318
- * Add a packet to the queue for RTP decoding
319
- */
320
- addReceivedPacket ( packet , callback ) {
321
- return null ;
322
- }
323
-
324
- /**
325
- * Add a media stream for RTP encoding
326
- */
327
- addTransmitMedia ( samples , callback ) {
328
- return null ;
329
- }
330
- }
331
-
332
- export { Payload , RTPHeader , RTPStream , RTPPacket , MediaQueue } ;
372
+ export { Payload , RTPHeader , RTPPacket , RTPServer } ;
0 commit comments