I built my own Tablo Apple TV app. Worthwhile project?

Like some others, I wanted to use the Tablo with my AppleTV natively. I spent a couple hours throwing together a simple proof of concept to watch live TV through the device, the use case I was most interested in.

Is this project something others are interested in using? Is it something others would be willing to contribute to?

Here’s a quick animated GIF screengrab of it in action: http://f.gabe.bz/3V3w0L2Y1F1r

Let me know your thoughts!

-Gabe

4 Likes

Thank you Gabe. I’m sure others that use an apple TV will be interested. I just wanted to say thanks from all the Tablo users.

Interested in sharing the code?

Sure. Like I said, it was just a quick proof of concept, so it’s nothing fancy, and certainly not production grade. But if people wanted to work together on it, we could probably build something cool.

Gabe,
I haven’t had a chance to load it up and look at it, but the gif looks nice.

Since LiveTV produces a live HLS stream (open-ended), are you able to do trickplay/scrubbing (fwd/rev skip, etc) with the video? I am interested to see how Tablo is going to deal with it on LiveTV.

See more discussion about it here (link to post where I start asking about it):
[Apple TV Beta Testers?] (Apple TV Beta Testers?)

I don’t have a very deep base of knowledge when it comes to video, but I thought to enable trick play a separate m3u8 playlist needed to be supplied with only the keyframes so it could be loaded and rendered outside of the actual video stream. As far as I’ve seen Tablo doesn’t have that secondary playlist, but it might be something new they’re adding just to support tvOS features.

As far as basic navigation within a stream, I haven’t played with it… I’ll report back if I learn anything!

-Gabe

Very interesting code, I know what I’ll be playing with when I get home today :slightly_smiling:

I see what appear to be some hard coded IP addresses and some plex references, but I imagine I’ll be able to puzzle that out.

Thanks a lot for being willing to post this. If I have any tweaks, I’ll try and contribute.

Yes! Point https://github.com/gabek/tablo/blob/master/tablo/Constants.swift#L12 to your Tablo device. I can’t think of anything else that you should have to change.

Also, all of this assumes you have a subscription to the Tablo program guide. I can’t imagine the code would react well if you didn’t have it, since it was built as a single-purpose test.

Gabe - thanks for posting this…my hat is off to you - well done! I’m fairly new to Xcode (more of a java background), but have toyed with Xcode off an on for the last few years. I changed the constants per your instructions to my local Tablo and spun your source code up in the simulator - its running like a champ. So was/is the thought to expand the live ChannelCell to a RecordedCell as well in order to review/play past recordings? I might toy with that idea a bit more - not sure how live vs recordings differ when calling those requests? If i find anything useful I’ll definitely contribute! Thanks again and nice work!

Realistically Tablo will have their official version out before I’m able to build anything terribly useful, so this experiment is more of an exploration if a different/more targeted interface is useful. Like for me, having the Program Guide interface isn’t terribly useful because I’m not one to check and “see what’s on”. I only open Tablo because I know something is live that I care about. So an app where I can open it and just select FOX, for instance, is fast and caters my use case.

As for expanding to recordings, I selected live tv because it was the most straightforward. Recording/PVR functionality requires more UI to be useful. Each show would have multiple episodes for instance, and the APIs are completely different. But it is the next logical step in functionality if we wanted to continue to explore.

So I got curious about the determination of the IP address…

Low level stuff not really well supported in Swift.

Challenge 1, get the appropriate broadcast mask for your situation (tables on your local network)…

So if you add a bridging header for “#include <ifaddrs.h>” you can use that to get the appropriate network interfaces with the ifaddrs Module.

Challenge 2, broadcast a UDP message on the correct port and receive the response(s) on the correct port to do discovery of the Tablo devices on your local network.

http://www.superhac.com/tablo/ is an essential resource for this until and unless Nuvyyo documents and exposes the interfaces.

The CocoaAsyncSocket framework makes this fairly simple once you work out the details of which delegate method you need to use to pick up the data.

    let ifInfo = getNetworkInterfaceInfo()
    if (ifInfo.keys.contains("en0")) {
        do{
            if (inSock == nil){
                inSock = AsyncUdpSocket(delegate: self)
                try inSock!.bindToPort(8882)
            }
        } catch {
            print("error")
        }
        inSock!.receiveWithTimeout(10.0,tag: 0)
        do{
            if (outSock == nil){
                outSock = AsyncUdpSocket(delegate: self)
                try outSock!.enableBroadcast(true)
            }
        } catch {
            print("error")
        }
        let data = "BnGr".dataUsingEncoding(NSUTF8StringEncoding)
        outSock?.sendData(data, toHost: ifInfo["en0"]!["broadcast"], port: 8881, withTimeout: 10.0, tag: 0)
    }


// AsyncUdpSocketDelegate method
func onUdpSocket(sock: AsyncUdpSocket!,
didReceiveData data: NSData!,
withTag tag: Int,
fromHost host: String!,
port: UInt16) -> Bool
{
delegate.tabloHostDetected(host, data)
return true
}

No way I want to add two significant modules to someone else’s project for my own curiosity about how to get the Tablo device address (avoiding hard coding) but it was a very interesting exercise.

Re-reading the dev requirements for tvOS apps, I suspect that Nuvyyo’s biggest challenge was startup time as the requirement to store all but trivial transient data in the cloud means that they either need to do a complete sync each time the app starts or download the digested version of that data from the cloud…

Thanks again for the look at your code, it’s got some very clear usages showing the power of Swift. If you want any of the stuff I’ve done, I’d be glad to send it along.

This is interesting. If it pulls fast like the Plex app then it will be sweet!