First steps

A project log for CastVolumeKnob

Hardware volume control for Chromecast Audio devices

Ákos MelczerÁkos Melczer 01/21/2019 at 22:340 Comments

The first I had to figure out  a way I can communicate with Chromecasts. The official API to communicate only supports Android, iOS and Chrome browser. For my purpose either of those options are usable, I needed to communication from a microcontroller.

Third party options:

None of these options were appropriate for my use case but I have found a lot's of useful information in the documentations.


Chromecasts use a communication protocol called Protocol-buffers or protobuf, developed by Google.

To use protocol-buffers you need to 'define' your protocol in a .proto file which you can compile out to a library. The supported languages are:

I started development on a PC and I choose Python because it was the easiest and quickest to develop in for me. At first I tried to construct my own protocol-buffer messages but I couldn't get it to work.Then I tried the .proto file and the compiled library from the pychromecast library, but i still didn't got any response.

Then I tried to capture the messages sent from the pychromecast library with wireshark, but the socket is encrypted.

Then I inserted a few print statements in to the library before sending the messages.

And i got messages like this:

b'\x00\x00\x00Y\x08\x00\x12\x08sender-0\x1a\nreceiver-0"(\x002\x13{"type": "CONNECT"}'

With the protocol-buffer libray I could parse these strings and into more readable JSON format.

When i tried to send these back, I got an answer from the Chromecast - Finally!

I continued with this method and found the message responsible for changing the volume, I could even change the value and it still worked.

Done. Right?

Not so fast!

For some reason it only worked when I converted the messages to strings with the precompiled protocol-buffer library.

Due to size and complexity I can't use the protobuf library on a microcontroller, I need a simpler solution.

My first thought was creating messages to set the volume from 0 to 100 and from that create a lookup table. As I was creating that table I noticed a pattern, besides the value of the volume i wanted to change there is a request number. Every message from the initial connection is numbered, starting from 1 and increments by 1. I needed to change that as well. Although almost everything else stayed the same between the messages there was still one important difference. Every part of the message had a number before it indicating its size. Since I wanted to send volume and request values from single digits to triple digits (0 to 100) I needed 5 different sized message. From those 5 created messages I can pick according to the current volume level and request number. And it worked. :)

Now I got it working without any third party library, I was getting closer.