SkillAgentSearch skills...

M3uparser

Parse your m3u VOD list and make a .strm library for media server

Install / Use

/learn @Xaque8787/M3uparser
About this skill

Quality Score

0/100

Supported Platforms

Universal

README

m3uparser

m3u|>arser

m3u|>arser will parse your m3u urls and make a .strm library.

Docker Compose Example

services:
  m3uparser:
    container_name: m3uparser
    image: xaque87/m3uparser:latest
    environment:
      - PUID=1000 # Defaults 1000 if blank.
      - PGID=1000 # Defaults 1000 if blank.
      - M3U_URL= # "https://m3u_URL1.com, https://m3u_URL2.com, etc..."
      - HOURS=12 # update interval, setting this optional, default 12hrs.
      - SCRUB_HEADER= # Optional, add more/different scrub values, does not override the defaults
      - EXCLUDE_TERMS= # Optional, this acts as a filter to ignore stream that contain defined value in group-title
      - REMOVE_TERMS= # Optional, add more/different remove term values, does not override the defaults
      - REPLACE_TERMS= # Optional, add more/different replace values, does not override the defaults
      - CLEANERS= # Optional, add more/different cleaner values, does not override the defaults
      - CLEAN_SYNC= # If set to true will remove titles from VOD folders that are not present in m3u files, Defaults to false if blank.
      - LIVE_TV= # Default is true, true will make a combined livetv.m3u from all live tv streams found in m3u files. Will be placed in /VODS/Live_TV 
      - UNSORTED= # Default is false, true will put at /VODS/Unsorted_VOD
      - JELLYFIN_URL= # Requires a Jellyfin server to be running. http://<jfin_url:8096> DO NOT use quotes around server url.
      - API_KEY= # Generate API key on server and enter it here. Requires a Jellyfin server to be running.
      - TF_HOST= # IP address used for Threadfin, example 127.0.0.1
      - TF_PORT= # Port used for Threadfin, example 34400
      - TF_USER= # Username being used for Threadfin
      - TF_PASS= # Password for Threadfin
      - REFRESH_LIB= # Requires a Jellyfin server to be running. Will refresh libraries after each parsing.

    volumes:
      - /path/to/your/media/library:/usr/src/app/VODS
      - /path/to/your/media/library:/usr/src/app/logs/

| ENV VARIABLE | VALUES | DESCRIPTION | EXAMPLE | DEFAULT VALUES | | ------------- |:---------------------------------------------------:|:-------------------------------------------------------------------------------------------------------------:|:--------------------------------------------:|:-----------------------------------:| | M3U_URL | any url(s), in quotes, and seperated with a comma , | Include all URLs you want to be parsed | "https://m3u_URL1.com, https://m3u_URL2.com" | n/a | | BYPASS_HEADER | true/false | Bypass checking url header for content-type and content-disposition. | False | False | | HOURS | numeric value | Number representing the interval you want to update from m3u urls | 12 | 8 | | SCRUB_HEADER | any text, in quotes, and seperated with a comma , | Removes value and preceding text from begining of group-title line | "HD :" | "HD :, SD :" | | EXCLUDE_TERMS | any text, in quotes, and seperated with a comma , | Excludes content that contains defined term if found in the group-title | "AR -, FR -" | "" | | REMOVE_TERMS | any text, in quotes, and seperated with a comma , | Removes value(s) set from file and directory names | "x264, 720p" | "720p, WEB, h264, H264, HDTV, x264" | | REPLACE_TERMS | "term-to-replace=replace-value" | Replaces one value with another. Separate terms with an = and term on left is replaced with term to the right | "replace-this=with-this" | "1/2=\u00BD, /=-" | | CLEANERS | series,movie,tv,unsorted | Type of stream to apply REMOVE_TERMS value to | tv, movies | tv | | REFRESH_LIB | true/false | Refresh Jellyfin libraries after parsing | false | false | | CLEAN_SYNC | true/false | Will remove titles from VOD folders that are not present in m3u. | false | false | | LIVE_TV | true/false | Parse live tv streams in m3u urls and creates a single livetv.m3u | true/false | true | | UNSORTED | true/false | Creates a VOD folder for undefined streams, either misspelled or poorly labeled streams | true/false | false |

Instalation Process

mkdir m3uparser
cd m3uparser
curl -o docker-compose.yaml https://raw.githubusercontent.com/Xaque8787/m3uparser/main/m3uparser/docker-compose.yaml
curl -o m3uparser.env https://raw.githubusercontent.com/Xaque8787/m3uparser/main/m3uparser/m3uparser.env

Then edit the m3uparser.env file with your credentials and desired values.

Then run:

docker compose up -d

Basic Information

Expanding default values

Add more values to the environment variables in the compose file to extend the defaults.

How it works

The parser uses the group-title value in the #EXTINF line of m3u files to structure the file and folder hierarchy. There are five stream types:

  • series: Shows with season/episode values.
  • tv: Shows with 'aired on date', such as talk shows with guest stars.
  • movies: Movies with release years.
  • live-tv: Live TV streams.
  • unsorted: Streams that do not fit into the above categories.

Key=Value pairs are made from each item in the EXTINF line. The values are then used to determine stream type, extract relavent information, and finally clean out unwanted values to then make the end resulting .strm libraries.

Examples and Explanations

SCRUB_HEADER

The group-title value often contains more information than just the TV show or Movie name. The SCRUB_HEADER values work by matching the first instance of the given values in the group-title string, and removing the values and anything that precedes it. The goal is to use a common string found amongst the group-title values.

Example: SCRUB_HEADER="HD :, SD :". This removes these values,HD : and SD :, if they exist, and any preceding text from the group-title line. So a line like this, group-title="Movie VOD",HD : The Fall Guy 2024 will become group-title= The Fall Guy 2024. Ensure spaces are included where needed. Add multiple values to SCRUB_HEADER=, separated by commas, in a single set of quotes. Note that any quotes that exist in the group-title are stripped before the SCRUB_HEADER is applied, so they do not need to be included in the SCRUB_HEADER value.

ESCAPING SPECIAL CHARACTERS

You can escape characters like , by using a \ So if your group-title looks like this group-title="Movie VOD",The Fall Guy 2024, your SCRUB_HEADER value should look like this SCRUB_HEADER="\," So this finds the first instance of a , and then removes it and anything that precedes it.

Default is set to: SCRUB_HEADER="HD :, SD :"

REMOVE_TERMS & CLEANERS

REMOVE_TERMS removes specified terms, and any attached text, from titles. For instance, REMOVE_TERMS="x264", would remove the entire string x264-somegarbge. This setting is case-sensitive and should have multiple values separated by commas, in a single set of quotes. i.e REMOVE_TERMS="x264, h264, X264"

A common format seen is to put qualities and language tag in sets of brackets like this [EN] or [h265]. To remove all of these use a REMOVE_TERM="["

Default is set to: "720p, WEB, h264, H264, HDTV, x264"

The CLEANERS variable defines which stream types REMOVE_TERMS applies to. For example, CLEANERS=series,tv applies REMOVE_TERMS to series and TV shows.

Default is set to: tv

REPLACE_TERMS

Add more replacements to REPLACE_TERMS in the format "replace=value". For example: REPLACE_TERMS="replace-this=with-this, dontwant=wantinstead". This replaces specified terms in all streams, except live TV.

Default is set to: "1/2=\u00BD, /=-"

BYPASS_HEADER

Setting this to true will have the script download the m3u urls regardless if it is available from provider or not. It will still check for 200 response from url, but will not check for content-type or content-disposition from the header response. These two checks are useful for ensuring the m3u file downloaded is actually available from the provider. In some cases if your provider is "down", you still may get a 200ok response from their server, but the m3u file that will be downloaded will be empty, resulting in a failed parsing. There are cases where the provider does not have a content-disposition entr

View on GitHub
GitHub Stars45
CategoryDevelopment
Updated14d ago
Forks4

Languages

Python

Security Score

75/100

Audited on Mar 18, 2026

No findings