Discover Local Chromecast Devices Using DNS-SD
I always wondered how Chromecast devices are magically detected by different apps. And Spotify allows me to play music from my Sony SRS-X77 speaker. How does Spotify even know that speaker exists?
Well, it turns out this is powered by DNS Service Discovery. In fact you can use command line tools to emulate the discovery process. macOS has dns-sd
tool builtin (for other OS you can use Avahi).
You start the service discovery process with this command:
% dns-sd -B _services._dns-sd._udp local.
Browsing for _services._dns-sd._udp.local.
DATE: ---Sat 04 Jul 2020---
22:39:00.155 ...STARTING...
Timestamp A/R Flags if Domain Service Type Instance Name
22:39:00.156 Add 3 4 . _tcp.local. _http
22:39:00.156 Add 3 4 . _tcp.local. _spotify-connect
22:39:00.156 Add 2 4 . _tcp.local. _companion-link
22:39:00.397 Add 3 4 . _tcp.local. _googlezone
22:39:00.397 Add 2 4 . _tcp.local. _googlecast
22:39:00.397 Add 2 1 . _tcp.local. _companion-link
22:39:00.499 Add 3 4 . _tcp.local. _nvstream_dbd
22:39:00.802 Add 3 4 . _tcp.local. _printer
22:39:00.802 Add 2 4 . _tcp.local. _ipp
22:39:00.932 Add 3 4 . _tcp.local. _smb
22:39:00.932 Add 3 4 . _tcp.local. _device-info
22:39:00.932 Add 2 4 . _tcp.local. _afpovertcp
22:39:01.238 Add 2 4 . _tcp.local. _alexa
You can see some familiar names in it, e.g. Chromecast (googlecast), Spotify and Alexa.
Now let's see which devices are running Chromecast:
% dns-sd -B _googlecast._tcp local.
Browsing for _googlecast._tcp.local.
DATE: ---Sat 04 Jul 2020---
22:42:52.056 ...STARTING...
Timestamp A/R Flags if Domain Service Type Instance Name
22:42:52.057 Add 3 4 local. _googlecast._tcp. Chromecast-b838<...>
22:42:52.057 Add 3 4 local. _googlecast._tcp. Chromecast-df0d<...>
22:42:52.057 Add 2 4 local. _googlecast._tcp. Chromecast-Ultra-1234<...>
Looks like on my local network there are 3 Chromecast devices. Let's get more information of the Chromecast Ultra:
% dns-sd -L Chromecast-Ultra-1234<...> _googlecast._tcp local.
Lookup Chromecast-Ultra-1234<...>._googlecast._tcp.local.
DATE: ---Sat 04 Jul 2020---
22:44:11.610 ...STARTING...
22:44:11.611 Chromecast-Ultra-1234<...>._googlecast._tcp.local. can be reached at 1234d567-89ab-cdef-1234-56789abcdef0.local.:8009 (interface 4)
id=1234<...> cd=43DD<...> rm= ve=05 md=Chromecast\ Ultra ic=/setup/icon.png fn=Dining\ Table ca=200709 st=0 bs=FA8FCA5D4DCF nf=1 rs=
You can see a bunch of metadata, including the user assigned device name (Dining Table). Also notice the address in the "can the reached at" section. Use it we can get the IP of the device:
% dns-sd -G v4v6 1234d567-89ab-cdef-1234-56789abcdef0.local.
DATE: ---Sat 04 Jul 2020---
22:48:15.421 ...STARTING...
Timestamp A/R Flags if Hostname Address TTL
22:48:15.421 Add 40000002 4 1234d567-89ab-cdef-1234-56789abcdef0.local. 192.168.1.71 120
Bingo. Its IP is 192.168.1.71
. And now you know how the googlecast library locates the Chromecast devices.