Wednesday, 18 April 2018

Slingbox Alternative: Build your own!

I've been trying to find ways to watch Japanese TV in Australia for a while now. It appears I can't pay for this no matter how much I want to - it just doesn't seem offered anywhere (I specifically want NHK Eテレ). Sadly the only two off-the-shelf options that seemed to present themselves were a Slingbox (and the annoyance of remote controlling a friend/families TV set from overseas) or something with a dubious streaming source like the UBOX that I assume may just stop working at some stage in the future.

I'd repeatedly written off both ideas. That was, until I came across @shotasano's blog post! It seems it is possible to decode Japanese digital TV with a valid B-CAS card, reader and the right software. So that's exactly what I did!

  • Like @shotasano, I also used a Raspberry Pi 3 B running Raspbian.
  • Mirakurun handles the DVB device IO (spawning recdvb mostly) and manages tuners, channels and the slowly polls raw EPG data with idle tuners.
  • Chinachu provides a Web UI with EPG and PVR features as well as a background "operator" process that manages free space, cleans up old recordings, schedules new ones according to rules and updates the EPG.
  • I'm using Kodi as a frontend. There is a dedicated PVR module for it, but I didn't fancy building APK's from scratch so I opted for the lazy approach with fewer features and installed a deprecated Simple IPTV PVR library for Chinachu instead and forgoing the PVR functionality.
The only slight challenge was obtaining a B-CAS card. In the end I ripped a red B-CAS card out of an old unused 地上デジタルチューナー box. 

All this together ends up fitting in a box only slightly larger than the Raspberry Pi itself and lives at a friends house in Japan, letting me stream to Sydney. Success!

I made one small code change so that I could visit http://192.168.1.xxx:20772/api/iptv/channels.m3u8 and http://192.168.1.xxx:20772/api/iptv/epg.xml with chrome and not get a bunch of 文字化け.

--- a/app-wui.js
+++ b/app-wui.js
@@ -508,6 +508,8 @@ function httpServerMain(req, res, query) {
                if (ext === 'asf') { type = 'video/x-ms-asf'; }
                if (ext === 'json') { type = 'application/json; charset=utf-8'; }
                if (ext === 'xspf') { type = 'application/xspf+xml'; }
+               if (ext === 'm3u8') { type = 'text/plain; charset=utf-8'; }
+               if (ext === 'xml') { type = 'text/plain+xml; charset=utf-8'; }

I also under-clocked everything and turned off wifi, bluetooth and audio to try to avoid under-voltage issues with my cheap power supply by adding this to /boot/config.txt:
# Default is 1200 for Pi3.
arm_freq=800

# Lower GPU frequency. We'll turn of HDMI later, but this might help.
gpu_freq=250

# Lower RAM frequency (from 450Mhz) too. We don't stress it too much.
sdram_freq=350

# Save power
dtparam=audio=off
dtoverlay=pi3-disable-bt
dtoverlay=pi3-disable-wifi

In /etc/rc.conf, I turned off HDMI which supposedly saves a tiny bit more (around 10mW):

# Disable HDMI
/usr/bin/tvservice -o

That it! Looking forward to kicking the tires of this thing over the coming months!