I was playing around with Volumio in the past few weeks and thought I’ve have a crack at getting it to support playback via Google Chromecast. I’m aware that the project focus is to drive audio devices directly. So I’m not trying to suggest this as a feature etc. It was purely a go at seeing how far I could get.
The nearest thing available for Chromecast integration with Volumio at present is mkchromecast which is a project that uses a soft DSP device to act as a sound card on the given Windows, OSX or Linux host. If it could be made work, the rest would fall out of the wash in terms of integrating with your preferred applications such as Volumio.
But rather than go that route, I felt it would be much more efficient to concentrate on getting the integration to serve URLs for the selected music files and let the Chromecast stream the files directly and do its own decoding. Streaming an MP3 or FLAC over the LAN is a much better idea than a raw PCM stream. It’s also less taxing on a small form factor computer like an RPi to handle.
The end result was to prototype a python script that uses pychromecast to control a specified Chromecast on your LAN. The same script then accesses the Volumio API to monitor the current playlist and then direct the Chromecast to stream the file that is currently playing. It uses python module chrerrypy to provide the web server to serve the files to the Chromecast. There is no direct coding changes to Volumio other than the integration with the REST API and a single call to the volumio command line binary for seek commands (that are not supported by the REST API)
I have this working on a Pi1B right now and while there are some niggles and feature gaps, it’s working enough to share out the efforts to others that might be interested.
Check the README in github. It has all the steps required to get you up and running:
Once installed, you can then run the script on the command line or follow steps to have it automatically started and kept running for you.
In terms of normal Volumio config, just have it configured to use the default audio interface be that HDMI, Jack or anything else and also leave it configured to use a hardware or software mixer. We want a volume control to be active as it is relayed to the Chromecast.
How it works
When you run the script it will first do a discovery of your specified Chromecast (if you specified it by name) to obtain its IP and port.
Then the script will start showing the current Volumio JSON API state every second (calling the gestate function in the RESTful API).
If it detects that something is playing, it will generate a URL for the current track file and invoke a cast of that URL to the specified Chromecast.
It also ties into events detected from the Volumio gestate… volume changes, play, pause, next, previous etc. All of these get relayed to the Chromecast. So as you change track, pause, stop… Chromecast will follow suit.
However, there is no seek functionality at this stage. So you can’t skip ahead/back within a given track.
If the script loses connectivity to the Chromecast it will detect this, re-establish a cast and start streaming again. Even if someone independently casts to the device from another app, this script will steal back control on the next track change.
To stop the streaming, you clear the queue on Volumio or let the current playlist play out and that will put it into a stopped state on the Volumio end which directs the script to stop casting and release all control over the Chromecast.
I’ve got this to work fine on the normal Google Chromecast, Chromecast Audio and on Google Home devices. It will also work with Grouped devices for multi-room synchronised playback. I did try to get basic artwork working for the video variant but was struggling with converting the Volumio artwork references it into URLs.
Just FYI the skip restriction relates to how I had to sync Volumio playback with that of the Chromecast. When you instruct Volumio to play a file, it really is playing file vie the default audio device. The progress of that playback starts as soon as you hit play. But the Chromecast playback is on it’s own timing and subject to how long it takes the Chromecast to start streaming the file.
If both left to their own devices, the Volumio playback is likely to end first, causing the script to instruct Chromecast to play the next track before it finished playing the current one. So the approach I took was to force 30-second syncs, where the elapsed time as reported from the Chromecast is used to perform a local seek on Volumio and get it back in sync and likely behind by 1-2 seconds. The cool thing is that once the Chromecast finishes playback, that is quickly detected and the script invokes the next track via the API.
Visually what you see on the Volumio I/F is track time progress as the playback continues and a little niggle every 30 seconds as the sync takes place. So you can’t really listen to the native playback as it will experience drops every 30 seconds with the sync. But in fairness the objective is to listen via the Chromecast.
Also, if during playback, you go and seek further on via Volumio GUI, within 30 seconds it will reset itself back to where the Chromecast progress is. For that reason, we don’t (yet) have a reliable way of having a Volumio seek translate into a seek on the Chromecast. But it is something I’d like to tackle at some point.
So enjoy and comments welcome.