Skip to main content

Chromecast audio: mirroring, streaming, authenticating

I was curious about what the Chromecast audio is and how it works - both in terms of hardware and software. After a lot of needless thrashing about, I realized that the wikipedia page has the specifications for the system on a chip, though the ifixit teardown is more detailed and also points out that the Chromecast and Chromecast audio basically have the same system-on-a-chip. Interestingly, the Synology NAS also has a Marvell Armada system. Exploitee.rs says that the system runs a modified Android system.

I was most curious about was how the software works: specifically, when I play music through the chromecast audio what is the flow of data? My web-search-fu failed me, and could not get any descriptions of this that went beyond user-level, google marketing speak. What I gather is that there are two modes of data transfer: mirroring and streaming.

Mirroring takes the audio data stream playing from a computer (laptop, smart phone, iPad) and redirects it to the Chromecast. Software on the computer (say the chrome browser) is talking to (authenticating with) the server (say youtube), and is streaming the data from the server, doing all the heavy lifting. When you mirror, the audio component of the output, instead of feeding to the components of the operating system that drive the computer speakers, instead is sent back out over the LAN to the Chromecast, which then takes this stream, from your computer, and coverts it into analog signals for the connected speakers.

During streaming on the other hand, the Chromecast does all the heavy lifting - the Chromecast talks to the server, authenticates, and then grabs the data and renders it, doing the same work the laptop was doing during casting. The computer (smart phone, iPad) now acts only as a controller - there is typically an App that is used to select what music to play, but this App is just passing along metadata to the Chromecast, which then relays these instructions to the server and grabs the return data. The App is just a nice UI for the Chromecast, which is the backend.

This data flow is betrayed because I've found casting to often be glitchy, say when my computer stutters, which messes with the audio data flowing from the computer to the Chromecast. Streaming, on the other hand seems to be independent of the host - you can use an App on your phone to start a music stream and then turn off the phone, and the music will keep playing because the Chromecast is doing the actual work.

UPDATES:
Found this answer on google's FAQ for Chromecast, that makes this information explicit. They use the terms cast for what I called streaming and tab cast for what I called  mirroring.

A Synology blog post says:
Chromecast is basically a Chrome browser, you can’t see it, you can’t feel it, but it’s there: when you select a song to stream, DS audio/video simply passes the HTTP(S) url to the browser, meaning the stream goes from the DiskStation to the Chromecast, the device is never a bottleneck. And if you kill the app or log out, streaming will carry on uninterrupted!

Streaming should raise some privacy and security concerns in your mind. Say you let the Chromecast connect to your home NAS by supplying the login and password. You've basically given a black box - that has connection to the internet - access to your NAS. We trust this just like we trust that our laptops don't have spyware as part of the OS, or that the NAS itself is not phoning home with our private data, but you never really know, do you? 

Comments

Popular posts from this blog

A note on Python's __exit__() and errors

Python's context managers are a very neat way of handling code that needs a teardown once you are done. Python objects have do have a destructor method ( __del__ ) called right before the last instance of the object is about to be destroyed. You can do a teardown there. However there is a lot of fine print to the __del__ method. A cleaner way of doing tear-downs is through Python's context manager , manifested as the with keyword. class CrushMe: def __init__(self): self.f = open('test.txt', 'w') def foo(self, a, b): self.f.write(str(a - b)) def __enter__(self): return self def __exit__(self, exc_type, exc_val, exc_tb): self.f.close() return True with CrushMe() as c: c.foo(2, 3) One thing that is important, and that got me just now, is error handling. I made the mistake of ignoring all those 'junk' arguments ( exc_type, exc_val, exc_tb ). I just skimmed the docs and what popped out is that you need to return True or...

Store numpy arrays in sqlite

Use numpy.getbuffer (or sqlite3.Binary ) in combination with numpy.frombuffer to lug numpy data in and out of the sqlite3 database: import sqlite3, numpy r1d = numpy.random.randn(10) con = sqlite3.connect(':memory:') con.execute("CREATE TABLE eye(id INTEGER PRIMARY KEY, desc TEXT, data BLOB)") con.execute("INSERT INTO eye(desc,data) VALUES(?,?)", ("1d", sqlite3.Binary(r1d))) con.execute("INSERT INTO eye(desc,data) VALUES(?,?)", ("1d", numpy.getbuffer(r1d))) res = con.execute("SELECT * FROM eye").fetchall() con.close() #res -> #[(1, u'1d', <read-write buffer ptr 0x10371b220, size 80 at 0x10371b1e0>), # (2, u'1d', <read-write buffer ptr 0x10371b190, size 80 at 0x10371b150>)] print r1d - numpy.frombuffer(res[0][2]) #->[ 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.] print r1d - numpy.frombuffer(res[1][2]) #->[ 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.] Note that for work where data ty...