So, in the first part of this series the overall picture was laid out. It’s time to get our hands dirty and dig into the more practical side of things. But first, let’s go through the overall lifecycle of a Sender/Receiver application and the messaging system that makes things rock.
Since I have done all my Sender development on Android, I will be basing things on my experiences from that platform. But the overall stuff should be basically the same regardless of Sender platform.
The Media Router API and device discovery
So, how does your Android device know there’s a Chromecast on the same WiFi? There’s an add-on Android support library available called android-support-v7-mediarouter.jar which ”allows applications to control the routing of media channels and streams from the current device to external speakers and destination devices”. This library provides a generic approach to discover ”media routes” on the local network. One can also use the DeviceManager from the Cast API:s. But as far as I can tell, using the MediaRouter API seems to be the recommended way.
The Google Cast lifecycle
The overall lifecycle can serve as a good context to explain how things fit together. For the real details, you can consult the API docs, here’s a more coarse-grained version.
1. Your Sender application initializes the appropriate Google Cast context objects and tells your app to scan for cast devices using the MediaRouter API.
2. You select your target media route and a session is established between the Sender and Receiver applications.
3. A ”channel” object is now available on both sides, this is essentially a Web Socket. In the context of the Google Cast API, you will now attach a MessageStream to the channel. This MessageStream can be a default one provided by the Cast API:s that provide basic media controlling functionality (start, stop, rewind, volume up/down) or a subclass of your own, providing app-specific methods and callbacks.
4. We now consider the application as running. Sender and Receiver can exchange messages over the MessageStream and act/react to each other as the developer seems fit. For example, once the playback of a media stream ends, you might want the receiver to inform the sender that this has happened so the Sender might go back into some media browsing activity to choose what to play next.
5. Once the cast should end, either side can invoke the appropriate lifecycle methods (e.g. endSession()) and the other side’s onSessionEnd callback can run. For Android Senders, you can hook into the normal activity lifecycle callbacks (onPause, onStop etc.) and fine-tune your app’s behaviour if the Activity is not active anymore. For a Media Playback solution, you’d definitely will want to keep the cast going, while you for a multiplayer game may want to pause the game for all participants until the onResume callback fires when the activity is brought to the front again. It’s up to the developer!
I think the customizable MessageStream protocol is one of the most intriguing parts of the Chromecast Sender/Receiver model. Since you can connect several Sender apps to the same Receiver it opens up some very interesting possibilities for collaborative work, multiplayer games and other imaginable and probably unimaginable stuff. Personally, I’m hoping for wide adaptment of Chromecast for various services. Not just online media-on-demand services such as the already existing Netflix, YouTube, Hulu etc, but for all kinds of services where it would be very neat to cast interesting stuff onto the Big Screen directly from your app. For example, I hope the guys and girls at Prezi will support showing their web-based presentations on a Chromecast device with an app as remote control in the future. I’m almost getting some Google Wave flashbacks here when it comes to collaborative work.
Setting up your Android sender development environment
This was tougher than I could have imagined, mostly due to myself not following these excellent instructions to the letter and also trying to get things up in IntelliJ IDEA 12 instead of Eclipse / Android Developer. Basically, getting the Android support libraries for support-v4, mediarouter and appcompat set up correctly in relation to your project is far from straightforward. But I got it to work once I did it exactly as that guide linked above described it. It’s very probable one can get it to work in IntelliJ IDEA too, feel free to blog about it if you succeed!
Anyway, I just created a brand new Android project from scratch with some default Activity. You’ll need some special elements in your AndroidManifest.xml though:
<uses-sdk android:minSdkVersion="9" android:targetSdkVersion="18"/> <uses-permission android:name="android.permission.INTERNET"/> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/> <uses-feature android:name="android.hardware.wifi" android:required="true"/>
The actual source code for an Android sender application will be dealt with in Part 4 of this blog series.
Setting up for Receiver app development
Well, as you certainly can tell, the setup for how you develop and deploy your receiver app is up to you and what platform you’re planning on deploying it on.
Setting up your Chromecast device for debugging and development
This is actually quite simple if you use the guide at the bottom of this page and this guide. Well, if you just can avoid some irritating pitfalls.
- Your Chromecast device must be whitelisted for debugging to work.
- In the standard Android Chromecast app, you must check the box under the Privacy section for ”Send this Chromecast’s serial number when checking for updates”. Note that international customers until just recently had to install the chromecast.apk from some other place than Google Play. An earlier version (1.1.1) had a bug that didn’t persist the state change of that checkbox, causing many gray hairs on developers just not understanding why the debugging and development on their whitelisted device wouldn’t work. Make sure you have 1.1.2 or later if you’re configuring this stuff from the Android app. The iOS and Windows/Mac OS installers works fine.
- Your Chromecast device must be set into ”Developer mode”. You do this by opening the standard Chromecast Android App or equivalent. Click the ”Apps” label seven (7) times. The message, ”developer mode enabled” appears.
- Well, after you’ve done the above. Pull the power plug and reconnect it so the Chromecast reboots which should force a check for updates.
Now, you should be able to open Chrome and enter http://[ip.to.chrome.cast]:9222 in the browser address field and you should be good to go.
It might be worth mentioning that I couldn’t get the Sender and Receiver to connect properly until I had gotten all of the above whitelisting and dev mode steps done properly.
How to get hold of the IP-address of your Chromecast?
The easy way it to use the standard Android Chromecast app or equivalent. Click on the device you want to get the IP for. The spinning loading thing is shown for a little while until a ”Chromecast Settings” page is shown. At the bottom (below that send serial number thing), the IP address is shown. Me, doing things the hard way, opened my WiFi Router’s DHCP table and looked at the list of connected devices. The one with a * were my Chromecast. Yes, an asterisk.