-
Notifications
You must be signed in to change notification settings - Fork 2
M3U
- General
- M3U header
- M3U channels
- Media stream url
- Additional tags
- Channels numbering
- Grouping
- Matching M3U channel to EPG
- Logo
- Custom HTTP headers
- Catch-up
- DRM
- Other attributes
Default playlist encoding is UTF-8, but any other encoding can be specified during playlist configuration.
M3U playlist is text file which has header block and channels information. For example:
#EXTM3U url-tvg="http://example.com/xmltv.zip"
#EXTINF:-1 group-title="Music", MTV
http://example.com/channel/01
#EXTINF:-1 group-title="News", Euronews
http://example.com/channel/02
When TVirl installs playlist it process additional EPG resources to fill EPG information. All EPG resources are configured during initial playlist installation. Initial list of EPG resources is loaded from url-tvg attribute from M3U header.
TVirl supports next types of EPG resources:
- EPG in XmlTv format (archived or plain XML)
- EPG in JTV format (archived NDX + PDT files)
- channels logo (archive with image files: PNG/JPG)
EPG resource can be:
- local (on-device memory, sdcard, attached external disk and so on).
Local file is selected using TVirl's picker UI or can be referenced
using url with
file://
scheme. - remote, represented by it's url.
TVirl supports M3U/EPG urls:
-
HTTP(s) (For ex.:
https://example.com/xmltv.xml
,http://user:pswd@example.com/epg.tar.gz
) -
FTP (For ex.:
ftp://user:pswd@ftp.example.com/playlist.m3u
) -
local (For ex.:
file:///storage/emulated/0/Download/icons.zip
)
Main archive formats supported by TVirl:
- zip
- gzip (.gz, .tar.gz)
- bzip (.bz2)
It's possible to specify archive encoding to read file names properly from it.
Default archive encoding is cp866
.
Header block declares information about playlist itself and additional attributes
shared among all channels in it.
Header block starts with #EXTM3U
tag and ends before first channel
(which starts with #EXTINF:
).
All global attributes are declared using #EXTM3U
tag.
#EXTM3U url-tvg="http://example.com/jtv.zip" tvg-shift=-2 catchup="shift" catchup-days=7
Global attributes TVirl supports:
url-tvg
tvg-shift
-
catchup
,catchup-type
,catchup-source
,catchup-days
,timeshift
,tvg-rec
All global attributes (except url-tvg
) are added to all channels entries.
But if channel entry has same attribute already - TVirl will ignore inherited
global value.
url-tvg
defines coma-separated list of additional resources, which will be
loaded with a playlist to fill EPG information.
#EXTM3U url-tvg="http://example.com/xmltv.zip,http://example.com/icons.zip"
TVirl supports additional tags declared in M3U header.
#EXTM3U
#EXTVLCOPT:http-user-agent=Restream/5.20408.171030 (mag250, mag250) SmartSDK/1.5.63-rt-25 Qt/4.7.3 API/0.30.0
#EXTINF:-1,CBS
http://example.com/01
Global tags work the same way as global attributes. All values are added to all channels entries.
M3U playlist declares information about channels, their title, logo, catch-up information if supported, media stream url.
#EXTINF:0 tvg-id="493" tvg-logo="http://best-logo.net/images/euronews.png" group-title="NEWS",Euronews
udp://@235.1.1.2:5678
The general structure of channel entry is:
#EXTINF:<duration> <attrib_name1>=<attrib_value1> <attrib_value2>="<attrib_value2>",<channel_title>
<optional_tag>:<value>
<media_url>
- duration is float number. In most cases it does not make any sense for IPTV live streaming, but it can be used to bypass channel number.
- attributes are key-value pairs. Attributes names have to be unique, if multiple attributes with same name are declared - last one wins.
- channel title is title which will be used to represent channel in EPG. It's also used to search matching channel in EPG resources (XmlTv, JTV, logo)
- media url
TVirl supports transports:
- udp (natively or through UDP-to-HTTP proxy)
- rtp (only through UDP-to-HTTP proxy)
- http(s) with HLS/Dash/SmoothStreaming/HTTP Progressive (MPEG-TS, mkv, mp4, ...) (see ExoPlayer supported formats)
TVirl supports additional tags: #EXTGRP
, #EXTVLCOPT
, #KODIPROP
.
All tags declared before first channel are inherited by all channels
(see Global tags).
#EXTINF:0,Fox Life
#EXTGRP:MOVIES
http://example.com/fox_life.m3u8
#EXTINF
:
#KODIPROP:inputstream.adaptive.license_type=com.widevine.alpha
#KODIPROP:inputstream.adaptive.license_key=http://example.com/license
#EXTINF:-1,Star Plus
http://example.com/Star_Plus.mpd|user-agent="Foo"
This syntax breaks possibility to read tags in header properly. I'm highly erncorouge you to use standard syntax:
#EXTINF:-1,Star Plus
#KODIPROP:inputstream.adaptive.license_type=com.widevine.alpha
#KODIPROP:inputstream.adaptive.license_key=http://example.com/license
http://example.com/Star_Plus.mpd|user-agent="Foo"
TVirl can use custom channels numbering if there is one provided.
#EXTINF:-1 tvg-chno="18",TCM UK
http://example.com/01
#EXTINF:-1 tvg-chno="1.003",MTV
http://example.com/02
TVirl can use duration value as channel number. Next channels will have numbers 15 and 16.
#EXTINF:15,TCM UK
http://example.com/01
#EXTINF:16,MTV
http://example.com/02
TVirl reads information about channels grouping using different tags and attributes. But while TVirl understands all kinds of category/group names, system with its TV App and TV Input Framework accept canonical program GENRES. TVirl allows to map channels groups/categories to canonical genres during playlist installation.
#EXTINF:-1, Best Music
#EXTGRP:MUSIC
http://example.com/best3.m3u8
#EXTINF:-1, Euronews
#EXTGRP:NEWS
http://example.com/news.m3u8
group-title
attribute defines group for current and all further channels,
till another group-title
is declared. In the next example, both channels
(Movies 1, Movies 2) share same group: MOVIES.
#EXTINF:-1 group-title="MOVIES", Movies 1
http://example.com/best1.m3u8
#EXTINF:-1,Movies 2
http://example.com/best2.m3u8
#EXTINF:-1 group-title="MUSIC", MTV
http://example.com/music.m3u8
groups
attribute can declare multiple (using |
as separator) groups for
a single channel.
#EXTINF:-1 groups="MOVIES|COMEDY", Movies 3
http://example.com/01
When playlist is installed with EPG resources attached, TVirl performs channel look-up to find how different entities match to channels from a playlist. Here is the list of identities in the order from higher priority to lower:
- attribute
tvg-logo
(for logo only). - attribute
tvg-id
- attribute
tvg-name
- channel title
When EPG is archive with logo images, TVirl uses file names to compare with identities.
Comparing is case-insensitive, where symbol "_
" equals to "
" (space).
When processing XmlTv TVirl checks identities against channel id
and it's
display-name
's.
=== M3U Playlist:
#EXTINF:-1 tvg-id="LA1.es",la 1 HD
http://example.com/01
=== XmlTv (tvg-id matches id):
<channel id="LA1.es">
<display-name lang="es">LA 1 ES</display-name>
</channel>
=== XmlTv (title matches display name):
<channel id="132">
<display-name lang="en">LA 1 HD</display-name>
</channel>
=== zip archive with images:
/LA1.es.png
/la_1_hd.jpg
Channel logo can be provided using tvg-logo
or logo
attributes:
#EXTINF:-1 tvg-logo="http://static.example.com/logo/01.png",Paramount Channel
http://example.com/01
#EXTINF:-1 logo="http://static.example.com/logo/02.png",Paramount Comedy
http://example.com/02
Additionally to logo from M3U playlist itself TVirl loads logo from EPG resources:
- archive with images
-
<icon src="..." />
from XmlTv
<channel id="Telecinco.es">
<display-name lang="es">Telecinco ES</display-name>
<icon src="http://static.example.com/es/Telecinco.es.png"/>
</channel>
TVirl supports custom HTTP headers. If no custom HTTP headers are provided default
User-Agent
will be used, for example: TVirl/0.5.0.2 (Linux;Android 9) ExoPlayerLib/2.11.6
.
TVirl supports #EXTVLCOPT
tag with options:
http-user-agent
http-referrer
#EXTINF:-1,Channel 1
#EXTVLCOPT:http-user-agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:76.0) Gecko/20100101 Firefox/76.0
#EXTVLCOPT:http-referrer=https://example.com
http://example.com/01.m3u8
It's possible to add arbitary custom headers to media url:
- headers block starts with
|
- the rest of headers block is similar to query part of urls:
- TVirl url-decode whole block before parsing it
- each key-value pair is separated using
&
- each key-value has syntax:
<name>=<value>
-
"
are trimmed from values if exist
#EXTINF:-1,Ch1
http://example.com/01|User-Agent=VLC
#EXTINF:-1,Ch2
http://example.com/02|X-Forwarded-For=1.1.1.1&User-Agent=Foo%2F3.0+%28compatible%3B+FMSc%2F1.0%29&Referer=%20&Seekable=0
#EXTINF:-1,Ch3
http://example.com/03|Referer=https://youtube.com
TVirl supports different catch-up types. Next attributes are used:
-
catchup
,catchup-type
with possible values:default|append|shift|flussonic|fs
. -
catchup-source
is url or part of url to access catch-up withdefault
orappend
type. -
catchup-days
,timeshift
,tvg-rec
with number of days service provides catch-up.
For default
and append
catch-up services TVirl uses catchup-source
.
catchup-source
is added to stream url for append
type.
#EXTINF: 0 catchup="default" catchup-source="http://example.com/archive/?start=${start}",Ch1
http://example.com/stream1.m3u8
#EXTINF:0 catchup="append" catchup-source="?start=${start}" catchup-days="3",Ch2
http://example.com/stream2.m3u8
TVirl supports next placeholders inside catchup-source
:
-
${timestamp}
,{lutc}
: current Unix epoch time (seconds since epoch) -
${start}
,{utc}
: program start time as Unix epoch time -
${offset}
: program offset in seconds (now - start
) -
${duration}
,{duration}
: program duration in seconds (program_end - program_start
ornow - program_start
if program is not finished) -
${end}
,{utcend}
: program end time as Unix epoch time -
{Y}
,{m}
,{d}
,{H}
,{M}
,{S}
: year (YYYY
), month (01-12), day (01-31), hour (00-23), minute (00-59), second (00-59) of program start time
TVirl supports playback of DRM-protected (Widevine, PlayReady) streams. TVirl adopted syntax from KODI InputStream.Adaptive:
-
inputstream.adaptive.license_type
=com.widevine.alpha
|com.microsoft.playready
-
inputstream.adaptive.license_key
= url to retrieve license (custom headers are supported)
#EXTINF:-1,Ch1
#KODIPROP:inputstream.adaptive.license_type=com.widevine.alpha
#KODIPROP:inputstream.adaptive.license_key=http://example.com/01.mpd
http://example.com/01.mpd"
#EXTINF:-1,Ch2
#KODIPROP:inputstream.adaptive.license_type=com.widevine.alpha
#KODIPROP:inputstream.adaptive.license_key=http://example.com/license|User-Agent=Mozilla/5.0 (Windows NT 10.0; WOW64)
http://example.com/02.mpd"
#KODIPROP
is specified
before #EXTINF
tag. TVirl supports it, but it's considered invalid and breaks
parsing of global tags from a M3U header.
It's possible to specify time correction (hours) for programs from EPG resource.
tvg-shift
can be specified globally or per-channel.
This correction is applied on top of time-zone correction specified for EPG
resource during initial playlist installation.
#EXTM3U url-tvg="http://example.com/jtv.zip" tvg-shift=2
#EXTINF:-1, Ch1
http://example.com/01
#EXTINF:-1 tvg-shift=-1, Ch2
http://example.com/02
- EPG is in JTV format and your local zone is different than time zone used to generate JTV. JTV always uses local time zone and if it's different from user's one it should be manually corrected.
- Channel's live stream is re-stream from original one with some delay applied.