Как создать M3U плейлист для IPTV: теги, EPG и структура
Как вручную собрать M3U плейлист для IPTV: структура #EXTM3U и #EXTINF, атрибуты tvg-id, tvg-logo, group-title, привязка EPG, архив и кодировка UTF-8.
💡︎ Главные мысли статьи:
- M3U плейлист — обычный текстовый файл: первая строка #EXTM3U, затем для каждого канала строка #EXTINF с атрибутами и строка со ссылкой на поток.
- Сохраняйте файл в UTF-8 без BOM, иначе кириллица в названиях каналов может превратиться в «кракозябры».
- tvg-id связывает канал с телепрограммой XMLTV, group-title раскладывает каналы по папкам в плеере.
- 296 кинозалов BCU и 4K новинки
- Матч Премьер 50fps и архив 6 дней
- СБП (+20% бонус), карты РФ, МИР и ЕС
M3U плейлист можно собрать в любом текстовом редакторе. Первая строка — #EXTM3U, дальше для каждого канала пишутся две строки: #EXTINF с названием и атрибутами, затем ссылка на поток. Файл сохраняется в UTF-8 без BOM с расширением .m3u8. Ниже разобраны все нужные атрибуты, подключение телепрограммы и архива и типичные ошибки.
Свой список удобен, когда провайдерский плейлист слишком большой: в нём остаются только нужные каналы, с вашими категориями и логотипами.
Минимальный рабочий плейлист
#EXTM3U x-tvg-url="https://epg.example.com/guide.xml.gz"
#EXTINF:-1 tvg-id="match-tv" tvg-name="Матч ТВ HD" tvg-logo="https://example.com/logos/match.png" group-title="Спорт",Матч ТВ HD
http://cdn.provider.example/live/match_tv/index.m3u8
#EXTINF:-1 tvg-id="1tv" tvg-logo="https://example.com/logos/1tv.png" group-title="Общие",Первый канал
http://cdn.provider.example/live/1tv/index.m3u8
Адреса в примерах условные: ссылки на потоки и телепрограмму берите у своего провайдера.
Заголовок #EXTM3U
#EXTM3U— обязательная первая строка. Без неё многие плееры не распознают файл как плейлист.x-tvg-url(некоторые плееры понимают такжеurl-tvg) — ссылка на файл телепрограммы в формате XMLTV, обычный или сжатый.xml.gz. Плеер скачает расписание и сопоставит его с каналами.
Строка канала #EXTINF
#EXTINF:-1— длительность записи. Для прямого эфира пишут-1.tvg-id— идентификатор канала в файле XMLTV. Он должен совпадать с атрибутомidэлементаchannelв телепрограмме. Если не совпадает, канал останется без расписания.tvg-name— имя для поиска в EPG. Плееры используют его, когдаtvg-idне задан.tvg-logo— прямая ссылка на картинку логотипа (PNG с прозрачным фоном выглядит лучше всего).group-title— категория, по которой плеер раскладывает каналы: «Кино», «Спорт», «Детские».- Текст после последней запятой — название канала, которое увидит зритель.
- Следующая строка — ссылка на поток: HLS (
.m3u8), MPEG-TS (.ts) или мультикастudp://(у домашнего провайдера с udpxy или прямым мультикастом).
Атрибуты вроде tvg-id и group-title не входят в формальный стандарт: это общепринятое расширение формата, которое понимают TiviMate, OTT Navigator, Televizo, Kodi и большинство других плееров. Поэтому в разных плеерах редкие атрибуты могут работать по-разному.
Архив передач (catch-up)
Если провайдер поддерживает архив, его включают атрибутами в строке #EXTINF:
#EXTINF:-1 tvg-id="1tv" catchup="append" catchup-days="7" catchup-source="?utc={utc}&lutc={lutc}" group-title="Общие",Первый канал
http://stream.provider.example/live/1tv/index.m3u8
catchup— способ формирования ссылки на архив.appendдописываетcatchup-sourceв конец адреса потока,defaultиспользуетcatchup-sourceкак полный адрес. Есть и другие типы (shift,flussonic,xc), их поддержка зависит от плеера.catchup-days— сколько дней архива хранит провайдер.catchup-source— шаблон запроса. Плеер подставляет вместо{utc}и{lutc}время начала передачи и текущее время в Unix-формате.
Шаблон задаёт сервер провайдера. Если он не поддерживает такой запрос, атрибуты ничего не дадут. Подробнее про форматы архива написано в статье про настройку архива и перемотки в IPTV.
User-Agent и Referer
Некоторые серверы отдают поток только определённому клиенту. Заголовки можно задать строками #EXTVLCOPT перед ссылкой:
#EXTINF:-1 group-title="Кино",Канал
#EXTVLCOPT:http-user-agent=Mozilla/5.0 (SMART-TV; Linux; Tizen 6.0)
#EXTVLCOPT:http-referrer=https://provider.example/
http://stream.provider.example/cinema/stream.m3u8
Эти строки пришли из VLC. TiviMate и OTT Navigator их тоже читают, а некоторые плееры для Smart TV игнорируют.
Сдвиг телепрограммы (tvg-shift)
Время в XMLTV указывается вместе с часовым поясом, например 20261026210000 +0300, поэтому обычно плеер сам показывает расписание по местному времени. tvg-shift нужен, когда канал идёт со сдвигом (региональный «+2» или «+4»), а телепрограмма у вас только от основной версии:
#EXTINF:-1 tvg-id="russia1" tvg-shift="+2" group-title="Региональные",Россия 1 (+2)
http://stream.provider.example/live/russia1_plus2.m3u8
Значение задаётся в часах. Поддерживают его не все плееры: если расписание не сдвинулось, ищите похожую настройку сдвига EPG в самом плеере.
Проверка потоков перед добавлением
Узнать кодек, разрешение и частоту кадров потока можно утилитой ffprobe из пакета FFmpeg:
ffprobe -v error -select_streams v:0 -show_entries stream=codec_name,width,height,avg_frame_rate -of default=noprint_wrappers=1 "http://stream.provider.example/live/stream.m3u8"
codec_name—h264илиhevc. HEVC понадобится аппаратный декодер на приставке или телевизоре.widthиheight— разрешение кадра.avg_frame_rate— частота кадров, например50/1или25/1.
Быстро проверить, отвечает ли сервер:
curl -ILs --connect-timeout 5 "http://stream.provider.example/live/stream.m3u8" | grep -E "HTTP/|Content-Type"
Ответ 200 и тип application/vnd.apple.mpegurl (или application/x-mpegURL) означают, что сервер прямо сейчас отдаёт плейлист. О стабильности потока это ничего не говорит. Некоторые серверы отвечают на запрос заголовков (HEAD) ошибкой, хотя сам поток работает. Тогда проверьте ссылку в VLC.
Кодировка и переносы строк
- UTF-8 без BOM. В ANSI (Windows-1251) кириллица на телевизоре превратится в «кракозябры». Метка BOM (байты
EF BB BF) в начале файла может помешать плееру распознать#EXTM3U. В спецификации HLS (RFC 8216) прямо сказано, что плейлисты должны быть в UTF-8 и без BOM. - Переносы строк. Большинство плееров читает и Windows (CRLF), и Unix (LF). Если какой-то плеер склеивает строки, сохраните файл с LF.
- Редактор. Notepad++ и VS Code показывают кодировку и тип переносов в строке состояния. Старый «Блокнот» Windows сохранял файлы в ANSI по умолчанию, поэтому проверяйте кодировку перед сохранением.
Проверить плейлист перед загрузкой в плеер можно в онлайн-чекере M3U, а сопоставить каналы с телепрограммой — в редакторе EPG и M3U.
Где хранить плейлист
Если загрузить файл в плеер с флешки, после каждой правки придётся загружать его заново на всех устройствах. Удобнее разместить файл в сети и добавить в плеер ссылку:
- Pastebin, GitHub Gist и похожие сервисы дают прямую ссылку на текст (кнопка Raw). Некоторые из этих сервисов могут быть недоступны у части российских провайдеров.
- Репозиторий на GitHub подходит, если вы часто правите список: видна история изменений, а ссылка на файл не меняется. Пошагово процесс описан в статье про автообновляемый плейлист на GitHub.
Не выкладывайте в открытый доступ плейлист с персональной ссылкой или токеном платного провайдера: по ней смогут смотреть посторонние, а провайдер может заблокировать доступ.
Чек-лист
- Первая строка —
#EXTM3U. - Кодировка UTF-8 без BOM.
- В каждой строке
#EXTINFназвание канала стоит после последней запятой. tvg-idсовпадает сidканала в XMLTV.- После каждой строки
#EXTINFидёт ссылка на поток.
❓︎ Часто задаваемые вопросы (FAQ)
В чем разница между файлами .m3u и .m3u8?
Структура одинаковая. Расширение .m3u8 означает, что файл в кодировке UTF-8, а для .m3u плееру иногда приходится угадывать кодировку. Если в названиях есть кириллица, сохраняйте файл в UTF-8 и используйте расширение .m3u8.
Почему названия каналов отображаются вопросительными знаками или кракозябрами?
Файл сохранён в кодировке Windows-1251 (ANSI) или с меткой BOM. Откройте его в Notepad++ или VS Code, выберите кодировку UTF-8 (без BOM) и сохраните заново.
Как заставить работать архив телепередач (Catch-up)?
Архив должен поддерживать сам провайдер. Если он поддерживается, в строку #EXTINF добавляют атрибуты catchup, catchup-days и catchup-source. Точный формат catchup-source даёт провайдер, придумать его самостоятельно нельзя.