Watching TV on your Android via a Raspberry Pi

During the long Easter holiday I’ve kept myself busy with a little pet project for my Raspberry Pi. So far I’ve been using the RPI as a small intranet server, DNS server and Proxy server. But it had plenty of room, both in RAM and storage, to do other things. As I had recently acquired a (dirt-cheap!) Android-based tablet, I was wondering if it would be possible to stream live TV directly to it.

There are plenty of commercial solutions available, as well as some apps, that stream directly over the Internet. But, as I had mentioned, the tablet was dirt cheap and so it should be indicative of the amount of money I was willing to spend.

I already owned a USB TV stick, which I used on my laptop, and wanted to use this as the receiver. It’s a PCTV Nanostick T2, based on the Sony CXD2820R demodulator, which is (or was?) the only device to support the UK’s DVB-T2 format for HD reception.

The USB TV stick is directly supported by the 3.x kernel (as an em28xx device), and naturally, the RPI did too. So it was a matter of finding what software would stream from the TV source over the network, and what software that would be able to accept and display this stream — particularly on an Android device.

This is where XBMC comes into play. Since version 12 of XBMC (“Frodo”), it is now possible to watch live TV via a PVR back-end. What’s great too, is that XBMC runs on a plethora of operating systems and devices, including Android. The app is not yet available in the Google Play store, so you need to manually download and install it. Just note, that before you install it on your Android, you may need to enable the Unknown sources option found under the Android’s system settings (under the Security tab).

Note! While the Raspberry Pi will detect the USB TV stick that is directly connected to it, it cannot provide enough power to it. This means it will not be able to tune into any channels. So the USB TV stick must be attached to a self-powered USB hub (which in turn is connected to the RPI, of course).

Tvheadend

So with the “front-end” sorted, all I needed was the back-end for the Raspberry Pi. I settled on using Tvheadend, because it is very lightweight and runs on the ARM device just fine. However, I didn’t install it from binary as, well, there wasn’t one available — at least not in individual form. Compiling is a breeze though, and the developers already have everything available for a .DEB package. I skipped building a .DEB package, simply for sake of simplicity, but used their init script, config files, etc.

To compile Tvheadend, you start by getting the necessary packages. Some I will list here are optional, but I prefer to cram as much “optional” stuff into a build, so I won’t need to recompile everything it when I do need it at one point.

sudo apt-get install git build-essential \
libavcodec-dev libavformat-dev libssl-dev \
libavutil-dev libavahi-client-dev libcurl3 \
w-scan

After the packages have been installed, proceed to clone the source code of Tvheadend using git. This will create a directory called tvheadend based on the location where you are, generally /home/pi/ if you’ve logged in via SSH.

git clone git://github.com/tvheadend/tvheadend.git

Now proceed to the directory and run the initial configuration. Running the configuration will check if you have the required packages installed, and fetch DVB scan data from a remote server.

cd tvheadend
./configure

If everything went well, you should not have received any fatal errors. You may see a few “fail” messages, but these are benign.

As I live in the London area, the Freeview transmitter is Crystal Palace. However, the source from which the configuration obtains the DVB scan data appears to be slightly outdated and may cause some hiccups. In my case, I’ve simply provided my own scan data using the previously installed w_scan application. You may skip this, if it doesn’t apply to you.

w_scan -cGB -x > ./data/dvb-scan/dvb-t/uk-CrystalPalace

This will directly replace the file in tvheadend/data/dvb-scan/dvb-t/uk-CrystalPalace, so if you’re concerned, you may wish to make a copy first.

Then proceed to compile Tvheadend, which for obvious reasons will take a little longer on a Raspberry Pi than a conventional computer:

make clean && make

Installation

Once it has been completed, you’re ready to install it. As mentioned earlier, Tvheadend already contains everything needed to build a .DEB package from which you could install it. However, I chose not to, and simply used some of the existing files to install it manually:

sudo su
make install
ln -s /usr/local/bin/tvheadend /usr/bin/tvheadend
cp ./debian/tvheadend.init /etc/init.d/tvheadend
chmod +x /etc/init.d/tvheadend
update-rc.d tvheadend defaults
cp ./debian/tvheadend.default /etc/default/tvheadend
adduser --quiet --system --group --shell /bin/bash hts
mkdir -p "/home/hts/.hts/tvheadend"
cat > /home/hts/.hts/tvheadend/superuser <<EOF
{
"username": "superadmin",
"password": "MySuperSecretPassword"
}
EOF
chmod 600 /home/hts/.hts/tvheadend/superuser
chown -R hts:hts "/home/hts/.hts"
exit

The one thing that you should pay attention to, is the portion here it creates the /home/hts/.hts/tvheadend/superuser file. The username and password provided here are only for sample purposes, and you should change this to something you’ve thought up yourself.

If you have a firewall setup on your RPI (and you should!), remember to open up the TCP ports 9981 and 9982 for the appropriate network. UDP is not required.

Configuration

Now that you have installed it, fire up Tvheadend:

sudo service tvheadend start

And configure it further at http://(ip address or domain name of your PI):9981. You will be prompted for a username and password, which was provided earlier in the superuser file.

Some guidance for configuration can be found in XBMC’s Wiki — it does not mention that after you’ve selected DVB input, you should tick the box Enabled found in the Adapter Configuration box, and then save the settings before it will perform an initial scan. You can follow its progress by expanding the window at the bottom (click the chevrons pointing upwards in the bottom-right corner).

Additionally, you need to setup the Access Control list, also found in the Configuration area, to allow/restrict access from devices. This is explained in more detail in the Tvheadend Wiki.

After this, you can configure XBMC, by going into its system settings, and enabling the Tvheadend HTSP Client add-on. Once that has been enabled, click Configure for it, and provide the necessary details, which at minimum is the IP or domain name for the Raspberry Pi. Finally, still within XBMC’s system settings, enable Live TV. You are now able to watch live TV! Unless …

Bugs!

There’s a bug with the Raspberry Pi firmware related to its USB. Or, there’s a problem with the USB itself. Either way, it affects many video streaming devices, such as webcams and TV USB sticks (like the em28xx devices). The result is that you may find yourself rather annoyed by the fact that live TV is barely “live”, and mostly consists of black screens or what appears to be a very bad signal. Looking at the logs for Tvheadend, you may notice many lines similar to this:

Apr 1 21:45:02 raspberrypi tvheadend[13259]: TS: Sony CXD2820R/London: 490,000 kHz/BBC ONE: MPEG2AUDIO @ #102: Continuity counter error, 533 duplicate log lines suppressed
Apr 1 21:45:03 raspberrypi tvheadend[13259]: TS: Sony CXD2820R/London: 490,000 kHz/BBC ONE: MPEG2VIDEO @ #101: Continuity counter error, 5777 duplicate log lines suppressed
Apr 1 21:45:03 raspberrypi tvheadend[13259]: TS: Sony CXD2820R/London: 490,000 kHz/BBC ONE: MPEG2AUDIO @ #106: Continuity counter error, 121 duplicate log lines suppressed
Apr 1 21:45:03 raspberrypi tvheadend[13259]: TS: Sony CXD2820R/London: 490,000 kHz/BBC ONE: MPEG2AUDIO @ #102: Continuity counter error, 534 duplicate log lines suppressed

Thankfully, this problem has been addressed by the Raspbian teams, and requires that you update your kernel (firmware). You can double-check the current version, which will likely produce something similar to this:

# uname -a
Linux raspberrypi 3.6.11+ #371 PREEMPT Thu Feb 7 16:31:35 GMT 2013 armv6l GNU/Linux

The important bit is the #371 part here, which is the one that has the above described issue. Updating the kernel/firmware is slightly different than what you’d expect from most Debian distributions (which is simply apt-get a linux image), but Liam McLoughlin has created a simple script to help you with that. Here’s a quick how-to:

sudo wget http://goo.gl/1BOfJ -O /usr/bin/rpi-update && sudo chmod +x /usr/bin/rpi-update
sudo rpi-update

Just let it run its course, which involves updating itself and then obtaining the latest firmware. If this is the first time you’ve run it, it will download about 42 Megabytes worth of files. After it has successfully completed downloading and installing, you need to reboot the Raspberry Pi. Once back up, the kernel/firmware version should have been updated to at least the following:

# uname -a
Linux raspberrypi 3.6.11+ #401 PREEMPT Fri Mar 29 22:59:09 GMT 2013 armv6l GNU/Linux

Again, the important part here is the #401, changed from the previous #371.

NOTE: If you still have all the original Raspbian bells and whistles installed, such as X-server/Gnome, then before you reboot the RPI, double check your available disk space.


Crystal Palace scan file

By request, the following is the scan file for Crystal Palace with which I receive the HD channels:

# — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — 
# file automatically generated by w_scan
# (http://wirbel.htpc-forum.de/w_scan/index2.html)
#! <w_scan> 20120605 1 0 TERRESTRIAL GB </w_scan>
# — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — —
# location and provider: <add description here>
# date (yyyy-mm-dd) : 2013–06–15
# provided by (opt) : <your name or email here>
#
# T[2] [plp_id] [system_id] <freq> <bw> <fec_hi> <fec_lo> <mod> <tm> <guard> <hi> [# comment]
# — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — —
T 482000000 8MHz 3/4 NONE QAM64 8k 1/32 NONE # London
T 490000000 8MHz 2/3 NONE QAM64 8k 1/32 NONE # London
T 514000000 8MHz 2/3 NONE QAM64 8k 1/32 NONE # London
T 506000000 8MHz 3/4 NONE QAM64 8k 1/32 NONE # London
T 529833000 8MHz 3/4 NONE QAM64 8k 1/32 NONE # London
T2 0 16435 546000000 8MHz AUTO AUTO AUTO AUTO AUTO AUTO # London
T2 0 16435 746000000 8MHz AUTO AUTO AUTO AUTO AUTO AUTO # London