M3U from Tablo

You guys did it again. It seems to be working really well.

Now I'm curious how hard the reported expiration date on the playlist URL per channel is.

I think OP asked not about integrating Tablo support directly into channels but to add support for sequential M3u8 playlists.

@TGZRyo I assume you need some script to create M3U tablo playlist from the API Calls?
with VPN connection Is it possible to watch channels from your box using Tablo app on iPad?

EDIT: Ok, I saw post higer and I see it is working now for you, great!

1 Like

Yeah it's working quite well. I have an HDHomeRun so this is more of a hobby thing at the moment.

It appears the link generated via the Tablo API expires after 6 hours and 20 minutes. I might make a script that makes API calls to the Tablo to generate new playlists per channel.

Does Channels DVR have an API I can call to pass an updated text format 'Source' to an existing playlist source I created?

Yep! And we got it. This is certainly within the bounds of our responsibility. We want to make sure these things work on our end, so you guys can do the other stuff on yours!

Yes, but as we always state, the API is private and we reserve the right to change it. It's listed below.

An even better way to do this would be to create a new project that essentially proxies the M3U. So, the project handles the fetching of the M3U from the Tablo, then you point Channels at the project and it gets served a sanitized M3U.

HTTP Method: PUT
Path: /providers/m3u/sources/$YOUR_M3U_NAME

Payload:

{
    "name": "IPTV",
    "type": "HLS",
    "source": "Text",
    "url": "",
    "text": "#EXTM3U\n\n#EXTINF:-1 tvg-ID=\"XXX\" tvg-name=\"XXX\" channel-number=\"530\" tvg-logo=\"XXX.png\" group-title=\"XXX\",XXX\nhttps://XXX.m3u8\n\n",
    "refresh": "",
    "limit": "",
    "satip": "",
    "numbering": ""
}

You can do a GET on that same URL to fetch your M3U. Then just update the text field with your new content and update it with the PUT.

1 Like

Could you PATCH with just the {"text":"…"}?

I thought about doing something like this and just hosting my own M3U that Channels would use. I see that Channels can be set to 'Never Refresh' or 'Refresh Daily'. Would it be possible to have this refresh more frequently? Like every 4 hours, 12 hours, Daily.

We can add more refresh options for the M3U.

I'm curious if you've found any API on the Tablo to list and download recordings?

Yes. I don't have storage attached to it right now to test functionality of playing them. But I was able to return info from the database.

GET http://192.168.1.92:8885/recordings/airings

["/recordings/series/episodes/580287","/recordings/series/episodes/580286","/recordings/series/episodes/580285","/recordings/series/episodes/580284","/recordings/series/episodes/580282","/recordings/series/episodes/580279","/recordings/series/episodes/452104","/recordings/series/episodes/388109","/recordings/series/episodes/380702","/recordings/series/episodes/365831","/recordings/series/episodes/353605","/recordings/series/episodes/343417","/recordings/series/episodes/329127","/recordings/series/episodes/321684","/recordings/series/episodes/318535","/recordings/series/episodes/313737","/recordings/series/episodes/306893","/recordings/series/episodes/299750","/recordings/series/episodes/292900","/recordings/series/episodes/285083","/recordings/series/episodes/277910","/recordings/series/episodes/195106","/recordings/series/episodes/79346","/recordings/series/episodes/79343","/recordings/series/episodes/79340"]

GET http://192.168.1.92:8885/recordings/series/episodes/79340

{"object_id":79340,"path":"/recordings/series/episodes/79340","series_path":"/recordings/series/79341","season_path":"/recordings/series/seasons/79342","snapshot_image":{"image_id":79349,"has_title":false},"airing_details":{"datetime":"2018-11-24T01:00Z","duration":1920,"channel_path":"/recordings/channels/15097","channel":{"object_id":15097,"path":"/recordings/channels/15097","channel":{"call_sign":"CBSX","call_sign_src":"CBSXX","major":XX,"minor":1,"network":"CBS","resolution":"hd_1080"}},"show_title":"Frosty the Snowman"},"video_details":{"state":"finished","clean":true,"cloud":false,"uploading":false,"audio":"aac","size":1804001280,"duration":2000,"width":1920,"height":1080,"schedule_offsets":{"start":-15,"end":64,"deprecated":true},"recorded_offsets":{"start":-15,"end":64},"airing_offsets":{"start":0,"end":0,"source":"none"},"seek":15,"error":null,"warnings":[]},"user_info":{"position":15,"watched":false,"protected":false},"episode":{"title":null,"description":"Based on the popular song with the same title, this holiday classic tells the story of a snowman named Frosty, brought to life by a magic hat. As the temperature begins to rise, Frosty worries that he'll melt, so his human friends come up with a plan to put him on a train to the North Pole, where he'll never melt. But the owner of the magic hat, Professor Hinkle, realizes it's really magic, after all, and wants it back. As they journey toward the North Pole, the cold takes its toll on Frosty's human companion, Karen, and he seeks help from none other than Santa himself, who takes Karen home, Frosty to the North Pole and shames Professor Hinkle into letting Frosty keep the cap.","number":0,"season_number":0,"orig_air_date":"1969-12-07","tms_id":"SH000148960000"},"qualifiers":["cc"]}

1 Like

Unfortunately it looks like I can only have as many active playlist URLs as I have tuners. I was hoping I'd be able to generate a list of all available stations. Then create an M3U that I could use until the playlists expired.

Once I generate a third playlist and start watching, it will stop the first stream (which I expected). Then I have to generate a new playlist to watch a different channel.

For this to work properly I'd have to run a GET URL and POST it to Channels anytime I wanted to tune to a specific station. Either that or limit the project to two channels.

Here's additional API calls for recordings
M3U to watch a recording: POST http://192.168.1.92:8885/recordings/programs/airings/769550/watch
Delete a recording: DELETE http://192.168.1.92:8885/recordings/programs/airings/769550

Other random ones I documented
GET http://192.168.1.92:8885/server/info
GET http://192.168.1.92:8885/server/capabilities

Does it mean now it will work with AES encrypted m3u ? I asked about this in Hacks section but no response and I assumed playlist with sequence of chunks was not supported. So if I have the key can I play and decrypt such list or I need separate projects that decrypt stream and send it reencoded to channels directly?

I don't think it works thay way. I have 2 tuners in HDHomeRun and certainly CHannels contain internally playlist with all channels that are tuned from the air. Not sure why the Tablo would be any different, and you should use only one M3u for entire box, am I wrong?

also I see in your playlist each line in the stream is always the same /stream/segw.ts?YVP4BtOYiH4aI7s7icXEKQ Have you tried in VLC e.g. playing that?

1 Like

The playlist stream is different every time you run the GET call. The stream you are referring to above is the sequential streaming for that particular station and playlist session. If I request a stream from two other channels and want to go back to the original. I have to generate a new playlist URL and has a completely different GUID. I found this mentioned in a third party app someone made.

Tablo has a developers group you can join to get full API access. But I'm not developing an app and found most of the API calls by using wireshark.

If you get a playlist, it expires after 6 hours and 20 minutes unless you request other streams. Tablo is indeed different from HDHomeRun.

so you need to store somewhere those URL for that particilar channels to be able to get back to it during that 6hourse 20 minutes. Some alias for ffmpeg command perhaps that first read URL from array and passing it to the ffmpeg itself. In my head it's doable :slight_smile:

My guess is that sequential streaming is in your case one stream url that is written inside m3u8 as relative link, try to change it for full URL and check how long does it play.

The problem is not storing the URLs for a period of time. I can script everything to generate the links and put them in M3U format. If I generate 2 playlists, those work.

As soon as I request a 3rd, one of the other two stop working. Requiring me to generate a new one if I want to watch that channel again. It has a limit of 2 functional playlists at a time.

Which wouldn't be a problem with full integration into an app. The app would limit you to 2 streams and request a new playlist when tuning to a new station.

You could write a simple proxy, which accepts HTTP requests for channelX.m3u8, and then makes the request to Tablo to create the actual playlist and redirect.

1 Like

Now we're getting somewhere - you didn't mention previously Tablo has 2 streams limit :slight_smile:

@tmm1 It would be like creating own API, so maybe even better request instead for channelX.m3u8 to some rewritten url like /tablo/channel/X

could you post an example how to create an endpoint that can redirect something to channels server?

I put together a simple docker container you can use to expose your Tablo tuners into Channels DVR

6 Likes