So on my home server I have a cron job that runs hourly and uses wget to download m3u files from various hosts. I then run m3ufilter against all of those m3u files to filter them and assemble them in one nice organized m3u file on a Samba share. All of the TV’s which run Kodi in one way or another look toward this m3u file.

Here is an example config but I’ll be explaining it below so just scroll down past it:

core:
  output: m3u
  group_order:
    - "Entertainment + Premiums - Rad"
    - "Entertainment + Premiums - Helix"
    - "Entertainment + Premiums - Dark"
    - "NFL Sunday Ticket - Rad"
    - "NFL Sunday Ticket - Helix"
    - "NFL Sunday Ticket - Dark"
    - "Sports - Helix"
    - "Sports - Dark"
    - "Locals - Rad"
    - "Locals - Helix"
    - "Locals - Dark"
    - "Radio/Music"
providers:
  - uri: file:///path/to/m3ufile
    filters:
      - match(Group, "USA ENTERTAINMENT") && !match(Group, "VIP")
      - match(Group, "USA MOVIE NETWORKS") && !match(Group, "VIP")
      - match(Group, "NFL PACKAGE")
      - match(Group, "USA \\& CANADA SPORTS")
      - match(Group, "ABC LOCAL NETWORKS")
      - match(Group, "CBS LOCAL NETWORKS")
      - match(Group, "NBC LOCAL NETWORKS")
      - match(Group, "FOX LOCAL NETWORKS")
    setters:
      - name: replace(Name, "USA ", "")
      - group: replace(Group, "USA ENTERTAINMENT", "Entertainment + Premiums - Helix")
      - group: replace(Group, "USA MOVIE NETWORKS", "Entertainment + Premiums - Helix")
      - group: replace(Group, "NFL PACKAGE", "NFL Sunday Ticket - Helix")
      - group: replace(Group, "USA \\& CANADA SPORTS", "Sports - Helix")
      - group: replace(Group, "ABC LOCAL NETWORKS", "Locals - Helix")
      - group: replace(Group, "CBS LOCAL NETWORKS", "Locals - Helix")
      - group: replace(Group, "NBC LOCAL NETWORKS", "Locals - Helix")
      - group: replace(Group, "FOX LOCAL NETWORKS", "Locals - Helix")

Okay so let’s go over this bullshit.

You can run this as a server or to just output a file… I run it to output as a file, so if you run it as a server you will have some other options you need to setup. I’m not going to go over every little line just some things I think aren’t obvious. Let’s go over filters, setters, and then come back to group_order.

Alright, so filters:

      - match(Group, "USA ENTERTAINMENT") && !match(Group, "VIP")
      - match(Group, "USA MOVIE NETWORKS") && !match(Group, "VIP")
      - match(Group, "NFL PACKAGE")
      - match(Group, "USA \\& CANADA SPORTS")
      - match(Group, "ABC LOCAL NETWORKS")
      - match(Group, "CBS LOCAL NETWORKS")
      - match(Group, "NBC LOCAL NETWORKS")
      - match(Group, "FOX LOCAL NETWORKS")

This is where you are matching your channels. You can see here that I am doing it by group name but you can also match to channel names. You can also see that I have some operators where I’m telling it not to match VIP in the first two lines. And also take notice that I needed to escape the & with two backslashes in the fourth line. Something I figured out with trial and error.

Okay, so you might be wondering how to get the group names, yeah? Well it’s easy. Run these commands against the m3u file from your host:

grep -Eo 'group-title="(?:\\.|[^"\\])*"' your_m3ufile | grep -Eo '"(?:\\.|[^"\\])*"' | sort | uniq > output.txt

Now you have a text file with all the group names you can use to match against in your m3u file. Alright let’s move on, now we have filtered out all the bullshit we don’t want in our m3u file by selecting for what we do want in it. Let’s organize it a bit and rename some categories. We do that in the setters section:

      - name: replace(Name, "USA ", "")
      - group: replace(Group, "USA ENTERTAINMENT", "Entertainment + Premiums - Helix")
      - group: replace(Group, "USA MOVIE NETWORKS", "Entertainment + Premiums - Helix")
      - group: replace(Group, "NFL PACKAGE", "NFL Sunday Ticket - Helix")
      - group: replace(Group, "USA \\& CANADA SPORTS", "Sports - Helix")
      - group: replace(Group, "ABC LOCAL NETWORKS", "Locals - Helix")
      - group: replace(Group, "CBS LOCAL NETWORKS", "Locals - Helix")
      - group: replace(Group, "NBC LOCAL NETWORKS", "Locals - Helix")
      - group: replace(Group, "FOX LOCAL NETWORKS", "Locals - Helix")

You can see from the above example that I am renaming both USA ENTERTAINMENT and USA MOVIE NETWORKS to Entertainment + Premiums - Helix. That is putting both those groups in the same category. You can see that I renamed some other categories as well as threw all the local channels into the same category. Great, now we are all organized and feeling really good about ourselves. What’s next? group_order:

    - "Entertainment + Premiums - Rad"
    - "Entertainment + Premiums - Helix"
    - "Entertainment + Premiums - Dark"
    - "NFL Sunday Ticket - Rad"
    - "NFL Sunday Ticket - Helix"
    - "NFL Sunday Ticket - Dark"
    - "Sports - Helix"
    - "Sports - Dark"
    - "Locals - Rad"
    - "Locals - Helix"
    - "Locals - Dark"
    - "Radio/Music"

Pretty simple stuff, we are just taking all the channel categories we have and are putting them in the order that we want them to appear. That’s it, we’re done, have a good day.