Channel Collections to m3u

Using TiviMate with Channels DVR for a few years now. I have always wanted to use Channel Collections as the source m3u since the channels are in the order I want and and in the groups I want.

This weekend I wrote a program and was able to accomplish this -- generate a m3u file with the channels in order of the Collection and assigned to groups using the name of the Channel Collection. Love this.

When I hit the Channel Collections endpoint, I get the list of channels for each Collection, but there is no indication as to the source for the channel (TVE or Pluto for example). Channels that are provided by both TVE and Pluto (think Dabl, Comet, etc.) were causing me a problem with my code. I use the Devices endpoint to get the data necessary to build the #EXTINF entry and the http URL.

My work around was to disable Dabl and Comet in the Pluto channel listing and test for "Hidden" in the Devices data to ignore the configuration for that channel.

Is there another endpoint that connects the Channel Collection channel list with the Devices used for the channel in the collection?

Can you provide an example entry? Last time I asked no one knew how to represent multiple groups for a single channel.

No, the information available is what's shown. Are you saying you have duplicate channel-ids across sources?

Yes:

TVE:
"ID": "dabl",
"GuideNumber": "6781",

Pluto
"ID": "dabl",
"GuideNumber": "9530",

I disabled the Pluto Dabl which gave me a way to ignore it as I'm using the TVE version.

Interesting is that with both Dabl stations enabled, Channels Collections will only allow me to pick the TVE version (Pluto version doesn't show up). If I disable the TVE version, I can use the Pluto version.

Okay going to push a new Pluto docker with id fix

channel-id must be unique or things won't work

I'm using the pluto url, not docker if that matters.

1 Like

4 duplicate ids I know of
buzzr
dabl
heartland
newsy

1 Like

cnn isn't a dup, but buzzr is.

TVE                         PLUTO
"ID": "cnn",                "ID": "pluto-cnn",
"GuideNumber": "6030",      "GuideNumber": "9068",
"GuideName": "CNN",         "GuideName": "CNN",
                            
"ID": "buzzr",              "ID": "buzzr",
"GuideNumber": "6750",      "GuideNumber": "9050",
"GuideName": "BUZZR",       "GuideName": "BUZZR",

Yes cnn is already on the conflicted list. I will add buzzr

@mike_here Are you willing to share what you wrote to accomplish this? I've added an M3U generator to OliveTin-for-Channels, and I'd like to be able to include Channels Collections as a "filter". Also, what endpoints are you talking about relative to Collections?

I abandoned the collections to m3u approach a few months after I posted. Over time, it was too much effort to keep everything in sync. I don't have that code because it morphed into the system I setup afterward. I decided I wanted each user to have their own server and I wanted all channels grouped in a specific order. Where I have Pluto (and the endless channels), I wanted the user machine to only have the channels from each source that anyone in the house would watch. (turns out that's about 160 channels across all sources). Each user can administer and remove or favorites their own channels in the web admin. Each user creates their own collections if they want.

I have a "primary" channels server setup and all it does is act a the TVE tuner for my setup. It's barely configured except for the TVE source. All of the channels servers are in docker containers. Pluto, FrndlyTV and Fubo are as well.

The common element across all user channels dvrs are the m3u files that define all of the sources. They only contain possible channels and the channels are numbered with a particular schema.

The software is now a set of python functions that take a lot of the work out of the process. It's a commitment. Quick and dirty version can be done in an hour if you understand python and some basics. sqlite3 database is used and it is how I manage data post collecting the data to build out m3u files. A high quality set of m3u builds is more in the 6 hours. The number of "duplicates"/duplicates is often not obvious due to naming inconsistencies between sources. Once the data is normalize, it's all very easy. A little different the the original but you're welcome to it.

Thanks for getting back to me on this. Based on your explanation of what you have going now, I don't think it's a fit with what I'm doing in the OliveTin-for-Channels project. Mostly what I had in mind, is to add a Channels Collection option to the M3U generator I created as an OliveTin Action. I was hoping there'd either be an undocumented endpoint in the API, or a reasonably simple script to filter for a given collection.

The endpoint for collections:

http://x.x.x.x:8089/dvr/collections/channels

Thanks! Any tips or tricks on turning that into an M3U?

lol. there is the problem. in order to create the m3u you still need the source data to build out the m3u. after completing this it became apparent that this approach wasn't going to work long term. I'm sure there are ways to make this work by code, but the quality of the m3u would be questionable.

http://x.x.x.x:8090/devices/ANY/channels.m3u?format=ts

the endpoint to generate the m3u could be joined with the endpoint for collections to stitch the two together, but I couldn't get past NOT normalizing the data to get the features and quality I wanted.

@mike_here So I'm doing a bit of experimenting to see if there's any reasonable approach to this. I used the following to extract the channel identifiers from the collections endpoint:

curl http://media-server6:8089/dvr/collections/channels | jq -r '.[] | select(.name == "Up-n-Away") | .items[]'

Which resulting in the following output:

virtual-2
virtual-3
virtual-5
2.1
8
11.1
9.10
12
5.1
abc
5.25.3
5.6
9.1
fox
10
4.1
cbs
4.2
frndly-55
cc
vh1
cmt
tvland
paramount
cnn
cnni
tbs
tbsp
tnt
tntp
tru
trup
tcm
aetv
history
lifetime
msnbc
242
244
bravop
fx
fxp
fxx
fxxp
fxm
sundance
amc
557
bbca
ifc
hallmark
hallmarkmm
frndly-3
discovery
hgtv
tlc
travel
diy
ahc
disney
disneyp
freeform
freeformp
espn1
espn2
espnu
espnews
sec
acc
olympics
212
213
215
216
217
samsung-USBC600001QL
218
fs1
fs2
cbssports
btn
501
502
504
505
503
506
507
509
samsung-USBB3200012D6
samsung-USBB3500002FL
samsung-USAJ3400020KC
samsung-USBC13000065U
samsung-USAJ26000054W
samsung-USBB19000017U
samsung-USBB3200015M8
samsung-USAK3508709A
pluto-5efbd39f8c4ce900075d7698
pluto-634dacf51d90320007fcd5fa
pluto-620bfa7df72827000703ddb1
pluto-5b68a18823ecb93393cba2f1
pluto-5efbd29e4aa26700076c0d06
pluto-62f54c11b3af68000702c304
pluto-62f54c6439183b000769fb8f
reboot
exit
5MAXHD
ACMAXHD
MAXHD
MAXHDP
SZEAHD
STZENHD
MGMHD
MGMDRHD
MGMHTH
MGMMRHD
MOMAXHD
MOVIEHD
OUTMAXHD
STRZCIH
STZCHD
STZEHD
STZHD
STZHDP
STRZIBH
STZKHD
THMAXHD
SHOWHD
SHOWHDP

Easy enough, but these values are not present in the M3U endpoint data, so I can't use that as a data source. Do you know if there's another endpoint I can use that contains these values, and hopefully the data I need to build a custom M3U containing just this collection?

I appreciate your help btw, I know you've gone in another direction -- but clearly you've been down this road before. :slight_smile:

You can query all your sources with /devices. It will show each device and all its channels. From there you can fetch what you need from the channel ID's that are returned in the collection. Then just write out the m3u yourself.

Here's the format for the stream for the channel:

http://$IP:$PORT/devices/$DEVICEID/channels/$CHANNEL_NUMBER/stream.mpg?format=ts

Thanks to useful input from @mike_here and @maddox, I've added the ability to generate an M3U based on a Channel Collection to OliveTin-for-Channels:

There's a new field in the M3U generator for the Collection name, which should be left set to "none" if you're not creating a collection-specific M3U:

You can either copy and paste the resulting M3U from Logs-stdout, or the .m3u can be found in the ./data directory found under whatever you have mapped to /config in your Docker Compose:

Lastly, if you'd like to simply "host" the file so it can be added by URL to another DVR, you can use static-file-server:

version: '3.9'
services:
  static-file-server:
    image: halverneus/static-file-server:${TAG}
    container_name: static-file-server
    dns_search: ${DOMAIN}
    ports:
      - 8080:8080
    environment:
      - FOLDER=${FOLDER}
    volumes:
      - ${HOST_DIR}/static-file-server:${FOLDER}
    restart: unless-stopped

Using environment variables similar to these:

TAG=latest
DOMAIN=tailxxxxx.ts.net
FOLDER=/web
HOST_DIR=/data
1 Like