Skip to content

How to discover & update audio groups

Amila Welihinda edited this page Jun 29, 2017 · 2 revisions

I use the following code to discover and group Chromecast devices, including Audio groups. These tend to change its address/port when a new master is chosen.

The caller receives up to three arguments:

  1. the callback for new discovered devices. The callback will get the name, ip and port.
  2. how frequently to send re-discover commands in ms.
  3. the callback for updated devices (new IP and/or port). The callback will get the name, ip and port.
//multicast-dns scanner (find all devices)
var util = require('util');
var mdns = require('multicast-dns');
var find = require('array-find');
var xtend = require('xtend');
var txt = require('mdns-txt')();
function mdsn_scan(cb_new, scan_interval, cb_update){
    var m = mdns();
    
    var found_devices = {};

    var onResponse = function(response) {
        
        var txt_field = find(response.additionals, function(entry) {
            return entry.type === 'TXT';
        });

        var srv_field = find(response.additionals, function(entry) {
            return entry.type === 'SRV';
        });

        var a_field = find(response.additionals, function(entry) {
            return entry.type === 'A';
        });

        if (!txt_field || !srv_field || !a_field) {
            return;
        }
        
        //console.log('txt:\n', util.inspect(txt.decode(txt_field.data)));
        
        var ip   = a_field.data;
        var name = txt.decode(txt_field.data).fn;
        var port = srv_field.data.port;
        
        
        if (!ip || !name || !port) {
            return;
        }
        
        if (name in found_devices) {
            //We have seen this device already
            old_device = found_devices[name];
            if (old_device.ip != ip || old_device.port != port) {
                //device has changed
                old_device.ip   = ip;
                old_device.port = port;
                if (cb_update)
                    cb_update(name, ip, port);
            }
        } else {
            //First time we see this device
            found_devices[name]={
                    ip:   ip,
                    port: port
            };
            if (cb_new)
                cb_new(name, ip, port);            
        }        
    }
    m.on('response', onResponse);

    function sendQuery(){
        //console.log("Sending query");
        m.query({
            questions:[{
                name: '_googlecast._tcp.local',
                type: 'PTR'
            }]
        });
    }
    
    sendQuery();
    if (scan_interval)
        setInterval(sendQuery, scan_interval);
}
Clone this wiki locally