dante-aes67-relay.js 1.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152
  1. const dgram = require('dgram');
  2. const client = dgram.createSocket({ type: 'udp4', reuseAddr: true });
  3. const sdp = require('./sdp');
  4. //config
  5. const addr = '10.10.1.100';
  6. const danteMulticast = '239.255.220.221';
  7. const aes67Multicast = '239.69.1.122';
  8. const samplerate = 48000;
  9. const channels = 2;
  10. const encoding = 'L24';
  11. const name = 'Dante Multicast Relay';
  12. const sessID = Math.round(Date.now() / 1000);
  13. const sessVersion = sessID;
  14. const ptpMaster = '08-00-00-ff-fe-00-00-1f:0';
  15. //rtp specific vars
  16. var seqNum = 0;
  17. client.on('listening', function() {
  18. client.addMembership(danteMulticast, addr);
  19. client.setMulticastInterface(addr);
  20. });
  21. client.on('message', function(buffer, remote) {
  22. //read values from buffer
  23. var channelCount = buffer.readUInt8(0);
  24. var timestampSeconds = buffer.readUInt32BE(1);
  25. //bytes 6 and 7 seem to be always 0x00, maybe reserved bytes
  26. var timestampMedia = buffer.readUInt16BE(7);
  27. var pcmData = buffer.slice(9);
  28. //calculate media timestamp for rtp
  29. var timestampRTP = ((timestampSeconds * samplerate) + timestampMedia) & 0xffffffff;
  30. //create RTP header
  31. var rtpHeader = Buffer.alloc(12);
  32. rtpHeader.writeUInt16BE(0x8061, 0);
  33. rtpHeader.writeUInt16BE(seqNum, 2);
  34. rtpHeader.writeInt32BE(timestampRTP, 4);
  35. rtpHeader.writeUInt32BE(0xaf12af34, 8);
  36. //create and send RTP packet
  37. var rtpBuffer = Buffer.concat([rtpHeader, pcmData]);
  38. client.send(rtpBuffer, 5004, aes67Multicast);
  39. //increase seqnum
  40. seqNum = (seqNum + 1) % 65536;
  41. });
  42. client.bind(4321);
  43. sdp.start(addr, aes67Multicast, samplerate, channels, encoding, name, sessID, sessVersion, ptpMaster);