Wednesday, April 16, 2014

On Writing an Over the Air TV Schedules App

Apple has been kind enough to accept my iOS App for reading TV schedules from an HDHomerun network TV tuner: Schedules GH. The first question that comes to mind, is why would I do such a thing? People have always connected Internet connections and the Internet is filled with TV schedule data. For instance, my MythTV server gets its listings from Schedules Direct, and I also go to Titan TV when that isn't available. So, I will admit this is a niche product, useful to OTA enthusiasts and the handful of people who take their HDHomeruns RVing.

Sometimes, you write an app just to show what you can do. It is not a beginners task, to walk line by line through the ATSC spec, to figure out the packet structure, implement a Huffman decompressor, decode various odd flavors of text, and know what every bit of a data blob means.  And then to turn around, and make an attractive, iOS7 themed app which scrolls at 57 fps, can call (at least five) multiple tuners concurrently, has a pleasant on-boarding experience all with a consistent color palette.  Earlier in the year, I'd been doing the rounds looking for a job, and what I heard from companies was a need for full-stack app developers, especially with the new hot topic being energy-efficient Bluetooth LE. So I concentrated on finishing a product which would showcase my overall skills. On interviews, I'd bring out an HDHomerun and a Leaf-style antenna and show them what I was up to.

Schedules GH
The idea to write a scheduling app came out of the shelved idea of writing a TV audio app. I had read about Silicon Dust releasing a transcoding version of the HDHomerun, the HDTC-2US, and I thought it'd be interesting to write a player app, concentrating on audio listening. However, what I had assumed was that the tuner would not only transcode video but would also transcode Dolby Digital, and it doesn't, at least not yet. Well, Dolby takes both an arm (upfront license fee) and a leg (per unit royalty) to legally decode their audio data. So I'll wait on Silicon Dust updating the firmware.

 But I'd already explored various ways to get schedule data into my app. I couldn't get it from Schedules Direct as I wasn't planning on open sourcing the app, and while I did talk to a pleasant man at Tribune Company owned Zap2It Labs, I wasn't going to have the volume to make it worth their while. So, I reasoned, why not just get the information from the device itself.

Thus I started a journey down into A/65:2013. the technical standard in the United States for broadcast digital TV. LibHDHomerun is a bit helpful, in that you can tell it to filter and deliver kinds of packets, but the sample code is about extracting video streams, not reading data packets, so all the locating the various tables in the spec: the master table, the terrestrial channels table, the system time table, the event record, the extended text table was up to me. It took the longest time to work right; I was particularly vexed by missing that over a certain packet size (188 bytes) tables would have to be stitched back together before calculating a validating CRC.  I leaned heavily on unit tests, and I can at least say that my code works for the stations in the greater Boston area.


I hadn't heard the term on-boarding before WWDC 2012, but it makes sense, the user's experience the first time they load the app is critical towards them knowing what the app does and how to use it. With a hardware tied app, its absolutely necessary (and yes, the next version of Signal GH will have an on-boarding sequence).

So, the onboarding is just a 3 step process of choosing an initial tuner, scanning for channels and sub channels, and finally choosing which tuners to call to get schedule information. If I had done this on my Signal GH app, I'd have a lot fewer confused users. 

UI Niceties

In the old days of iOS development, we'd get details about a table item by sliding over to a detail view. It seems like the fashion these days is to do more inline. So tapping on a schedule listing, just animates an expansion of the table, revealing the whole description text, and some action buttons.
You'll notice I'm using a green stripe to indicate a show that is on right now. No need to hit the user over the head.

I experimented with using pull to refresh instead of the refresh button, but pull to refresh requires me to be at the top of the table, which I might likely not be. So I went with the refresh button. 

All the graphics, given that I wrote it, are of course in vectored SVG format including the network logos. So I don't worry much about scaling. I drew all the artwork that wasn't a network logo with my SVG Paths app and I think everything turned out nicely. 

In general, the UI does not try to extend the boundaries of app design. Just execute a recognizable, flat design and keep out of the way. I review a lot of apps tied to devices on Amazon through the Amazon Vine program and I wish others would follow this guidance.

Submitting to Apple

As this is an app tied to a specific device, and I'm not actually sure how Apple reviews Signal GH (do they have an in-house HDHomerun?), I asked Apple reviewing for guidance and they told me to ship them hardware, so I shipped them my cheapest HDHomerun with an attached antenna. Which they promptly lost for a week, apparently, but eventually the app was reviewed, and became available yesterday night. 

Hopes and Dreams

Well, I don't expect a lot of income out of this app. It will likely be extremely useful to a handful of people in specific circumstances. And other, more hobby minded, people will likely find it interesting what TV stations put into their data stream. It was a nice demo when I was job hunting, although in the end, the job I did get didn't even involve a face to face interview. And the code will be used in other apps in the future. So a decent use of my time.