This tutorial series assumes you are familiar with golang, as we will be using it throught this article series.
A chromecast is a part of every Android TV. It has a default reciever app on your android TV on which you can cast any kind of supported media for as long as you can speak Google Cast protocol. To cast your media you don’t need any special app installed on tv. The default reciever app is good enough to give you basic controls such as pause/play, rewind forward or backwards, as well as volume controls. In order to cast media, you don’t send the files over, instead you send the url of a file and request it to be played. Default reciever is smart enough to fetch it themselves. Media can can be a LAN url for as long as it is reachable from your android tv.
A chromecast default reciever app doesn’t allow you to keep track of your media library, it has a hard time buffering large files, it doesn’t allow you to switch between subtitles channels nor audio chanels, and generally speaking can’t do more than play simple media in Chromecast appropriate format.
You will probabbly need to have android TV or a TV with a chromecast device on your LAN. Your LAN will need to support mdns (most of home setups support this protocol), as that is how we can discover chromecast enabled devices on our local network. If you are unfamiliar with mdsn it might be a good idea to read about it on wikipedia.
Besides hardware and network requirements, you will need some video to play on your device. Due to copyright reasons this one is the most popular as it has open source license. However keep in mind this is a 10s mp4 in 320p resolution, which means it will load correctly on any android tv. However if you were to try to load a longer mp4 video, of lets say an hour, of approx 1GB, your android TV would probabbly crash.
You will probabbly want to convert large videos to mpeg-ts format. A mpeg-ts video format is a format which is great for chunking because it is just appending x video files one after another. Chunking allows your tv to load the needed chunks to and from memory without needing to hold huge memory buffers. In other words it allows a dynamic streaming of media.
However most of the files you find online, as well as what your mobile device produces is mp4. Which means we need to convert it to mpeg-ts. Luckly for us there is a free and open source tool for converting/rencoding media to different formats, as well as many more things called ffmpeg
We will also need a way to piece those chunks together, a chromecast supported way of doing it is using m3u8 playlist. The playlist has many tags supported. You can look up the full m3u specs on wikipedia. However the most important thing to remember is that it is timpestamped sequential collection of mpeg-ts files. It looks in a way similar like this:
#EXTM3U
#EXT-X-VERSION:6
#EXT-X-TARGETDURATION:18
#EXT-X-MEDIA-SEQUENCE:0
#EXT-X-PLAYLIST-TYPE:EVENT
#EXT-X-INDEPENDENT-SEGMENTS
#EXT-X-DISCONTINUITY
#EXTINF:10.635622,
livestream-00.ts
#EXTINF:10.301967,
livestream-01.ts
#EXTINF:10.135122,
livestream-02.ts
#EXTINF:9.801456,
livestream-03.ts
#EXTINF:10.468789,
livestream-04.ts
#EXTINF:12.846167,
livestream-05.ts
#EXTINF:6.423089,
livestream-06.ts
#EXTINF:11.886878,
livestream-07.ts
#EXTINF:9.175833,
livestream-08.ts
#EXTINF:9.718033,
With all that in mind lets try to create a m3u8 playlist and mpeg-ts chunks from this open source 10-min mp4 using ffmpeg. Here is the bash command with comments. Don’t be intimidated by its size, there are honestly just a couple of parameters that are tweakable, the rest are hardcoded settings for wide chromecast support. You will be tweaking input and output, while copy pasting the others, and that’s it.
./ffmpeg \
-y \
`# our input` \
-i input.mp4 \
`# try to optimize for speed` \
-preset fast \
`# encoding of audio` \
-c:a aac \
`# quality of audio` \
-b:a 192k \
`# number of audio channels` \
-ac 2 \
`# encoder settings` \
-c:v libx264 \
`# resolution settings` \
-b:v 1024k \
`# quality settings` \
-profile:v high \
`# higher number represents better quality while taking longer to rencode` \
-crf 22 \
`# pixel type, (this is not resolution)` \
-pix_fmt yuv420p \
`# use all cpus` \
-threads 0 \
`# specify m3u8` \
-f hls \
`# intal m3u size` \
-hls_list_size 0 \
`# target chunks of approx 10 seconds, real will vary` \
-hls_time 10 \
`# allow for streaming` \
-hls_playlist_type event \
`# tell player that we will add to this list as it plays` \
-hls_flags independent_segments+append_list \
`# our output playlist` \
-master_pl_name myplaylist.m3u8 \
`# our output chunks location` \
./chunks/*
We’ve learned what chromecast can do, what it can’t do, we’ve learned a bit about video formats and network requirements we will need. And in the end we’ve created a video we will need in order to cast it to our chromecast enabled device. Next we will be diving into chromecast protocol, and figuring out how that piece works.