Архив и Catch-up: спецификация M3U и Xtream
Эталонная спецификация для IPTV-провайдеров — как объявить catch-up/архив в плейлистах M3U и Xtream Codes, чтобы он корректно воспроизводился в UniPlayer.
IPTV catch-up (также называемый архивом, таймшифтом или DVR) позволяет плееру восстановить URL уже прошедшей трансляции из URL живого канала и времени начала по UTC. В плейлисте M3U он объявляется атрибутами catchup, catchup-source и catchup-days в каждой строке #EXTINF; UniPlayer поддерживает режимы default, append, shift и Flussonic, а также автоопределение tv_archive для Xtream Codes. UniPlayer — это плеер, как VLC: провайдер предоставляет плейлист и окно архива, а UniPlayer лишь строит URL воспроизведения из времени начала программы в EPG.
Что это за документ
Это справочник для провайдеров по объявлению catch-up TV (он же архив, таймшифт, DVR, рестарт/архив) в плейлистах, которые ваши подписчики загружают в UniPlayer.
UniPlayer — это плеер, а не контент-сервис: та же модель нейтрального инструмента, что и у VLC. Ваш сервер хранит потоки и записанный архив; UniPlayer читает ваш плейлист, сопоставляет его с EPG и — когда пользователь отматывает назад в программе передач — восстанавливает URL воспроизведения архива по правилам ниже. Если ваш плейлист объявляет catch-up так, как описано в этой спецификации, каждый клиент UniPlayer (iOS, iPadOS, Apple TV) воспроизводит ваш архив без какой-либо интеграции под конкретного провайдера с нашей стороны.
Коротко. Укажите правильный режим
catchupи (где нужно) шаблонcatchup-sourceв каждой строке#EXTINF, объявите глубину хранения черезcatchup-daysи убедитесь, что ваш origin принимает время начала в формате UTC Unix. Это весь контракт.
1. Модель catch-up
Воспроизведение catch-up — всегда одна и та же операция из трёх частей:
| Часть | Кто предоставляет | Примечания |
|---|---|---|
| URL живого потока | Ваш плейлист (#EXTINF → строка URL) | Обычный адрес живого канала. |
| Время начала | UniPlayer, из EPG | Время начала выбранной программы как временная метка UTC Unix (в секундах). |
| Длительность / окно | Ваш плейлист (catchup-days) + EPG | Насколько далеко назад доходит архив; длительность программы. |
UniPlayer вычисляет смещение начала как programme_start − now (отрицательное число секунд,
«в прошлое»), конвертирует его в абсолютную временную метку UTC Unix и подставляет в ваш URL
живого потока согласно режиму catch-up канала. Отдельного «плейлиста архива» нет —
URL архива генерируется из URL живого потока.
Терминология (в дикой природе всё взаимозаменяемо): catch-up = архив = таймшифт = DVR = catchup TV = перемотка. UniPlayer трактует это как одну функцию.
2. Атрибуты M3U, которые читает UniPlayer
Объявляйте catch-up атрибутами в строке #EXTINF. UniPlayer разбирает любую пару
key="value"; ключи, относящиеся к catch-up:
| Атрибут | Обязателен | Значение |
|---|---|---|
catchup | Да¹ | Режим catch-up (см. §3). Также принимается как catchup-type. |
catchup-source | Зависит от режима | Шаблон URL или строка запроса с плейсхолдерами (см. §4). Обязателен для default/append, когда URL нельзя вывести автоматически. |
catchup-days | Рекомендуется | Целое число — сколько прошедших дней архива вы храните. Определяет, насколько далеко назад программа передач позволяет отматывать. |
timeshift | Опционально | Устаревший сигнал SIPTV. Его наличие заставляет UniPlayer трактовать канал как режим shift; его значение также читается как запасной источник числа дней. |
tvg-rec | Опционально | Устаревшие «дни записи» — читается как запасное значение catchup-days (>0 ⇒ архив доступен). |
catchup-time | Опционально | Окно, выраженное в секундах (внутренне конвертируется в дни). Запасной источник дней с наименьшим приоритетом. |
¹ Если вы опустите catchup, но форма URL потока ясно указывает на origin с поддержкой архива
(например, содержит /archive-, /rewind- или timeshift), UniPlayer определит режим. Явное указание
всегда лучше — не полагайтесь на автоопределение.
Порядок разрешения дней. UniPlayer читает окно из первого присутствующего значения:
catchup-days → timeshift → tvg-rec → catchup-time÷86400. Если ни одного нет, но
канал определён как способный к catch-up иным образом, UniPlayer предполагает окно в 30 дней.
Всегда задавайте catchup-days, чтобы пользователи видели реальную глубину.
3. Режимы catch-up (значение catchup)
UniPlayer нормализует значение catchup / catchup-type к одному из режимов ниже. Псевдонимы в
правом столбце принимаются и сворачиваются к каноническому режиму.
| Канонический режим | Принимаемые псевдонимы | Использовать, когда… |
|---|---|---|
default | default | Вы даёте полный шаблон URL архива в catchup-source. |
append | append | Вы даёте фрагмент строки запроса в catchup-source для добавления к URL живого потока. |
shift | shift, timeshift | Ваш origin принимает параметры запроса SIPTV utc/lutc. |
flussonic | flussonic, fs, flussonic-hls, flussonic-ts | Ваш origin — Flussonic (или совместимый с Flussonic). UniPlayer строит URL сам — catchup-source не нужен. |
xstream-1 | xstream, xtream, xc | Архив Xtream Codes (обычно определяется автоматически — см. §6). |
vod | vod | Записи catch-up в стиле video-on-demand. |
3.1 default — полный шаблон URL
catchup-source — это полный URL архива с плейсхолдерами, которые UniPlayer подставляет:
#EXTINF:-1 catchup="default" catchup-days="7" catchup-source="https://origin.example/ch12/video-${start}-${duration}.m3u8",Channel 12
https://origin.example/ch12/index.m3u8
3.2 append — фрагмент запроса
catchup-source — это лишь та часть, которую нужно добавить к URL живого потока. Начните её с ? (или с &, если
ваш URL живого потока уже содержит строку запроса):
#EXTINF:-1 catchup="append" catchup-days="7" catchup-source="?utc=${start}&lutc=now",News 24
https://origin.example/news/index.m3u8?token=abc
3.3 shift — SIPTV utc/lutc
catchup-source не нужен. UniPlayer добавляет utc=<start>&lutc=<now> к URL живого потока
(используя &, когда URL уже содержит ?):
#EXTINF:-1 catchup="shift" catchup-days="5",Sports 1
https://origin.example/sports1/index.m3u8
→ запрос к архиву становится …/sports1/index.m3u8?utc=1717400000&lutc=1717420000.
Если последний сегмент пути в URL живого потока — mpegts, UniPlayer вместо этого переписывает его в
timeshift_abs-<start>.ts (см. §5).
3.4 flussonic — автопостроение из URL живого потока
catchup-source не нужен — задайте режим, и UniPlayer перепишет URL живого потока, используя собственное
соглашение таймшифта Flussonic (точное преобразование см. в §5):
#EXTINF:-1 catchup="flussonic" catchup-days="14",Movie Channel
https://origin.example/movie/index.m3u8
3.5 xstream-1 / xc — Xtream Codes
Обычно вы не прописываете это вручную — когда UniPlayer загружает плейлист Xtream Codes, он задаёт
это автоматически из tv_archive/tv_archive_duration (§6). Псевдонимы существуют, чтобы M3U-экспорты
из панелей Xtream тоже распознавались.
4. Плейсхолдеры шаблона URL
Когда вы предоставляете catchup-source (режимы default / append), UniPlayer подставляет эти
токены. Всё время — в секундах UTC Unix epoch.
| Токен | Чем заменяется | Примечания |
|---|---|---|
${start} | Начало программы, абсолютные секунды UTC Unix | Основной токен. Используйте его для времени начала архива. |
${duration} | Длительность программы в секундах | Распознаётся внутри литерала в стиле Flussonic video-${start}-${duration} (см. ниже). |
utc=<n> / lutc=<n> | Подставляется режимом shift | utc = начало, lutc = текущий момент. Не токены шаблона — выдаются автоматически в режиме shift. |
Литеральный шорткат Flussonic. Если ваш catchup-source (или URL живого потока) содержит литеральный
сегмент video-${start}-${duration}, UniPlayer заменяет весь этот сегмент относительной формой Flussonic
mono-timeshift_rel<seconds> (отрицательные секунды в прошлое). Это позволяет одному
шаблону обслуживать и HLS-, и Flussonic-origin.
Замечание о совместимости (Kodi / соглашение
{utc}). Более широкая IPTV-экосистема (Kodi’s PVR IPTV Simple Client) также определяет{utc},{lutc},{utcend},{duration},{offset}, токены strftime{Y}{m}{d}{H}{M}{S}и{catchup-id}. Надёжно поддерживаемый набор UniPlayer — это токены${start}/${duration}плюс авторежимыshift(utc/lutc) иflussonic. Для максимальной совместимости между плеерами и гарантированного воспроизведения в UniPlayer предпочитайтеcatchup="flussonic"для Flussonic-origin иcatchup="shift"для utc/lutc-origin — им не нужен шаблон, и в них нельзя ошибиться при наборе.
5. Flussonic-origin (точное преобразование)
Для catchup="flussonic" (а также fs / flussonic-hls / flussonic-ts) UniPlayer переписывает
живой URL в URL таймшифта Flussonic. Два случая:
| URL живого потока заканчивается на | URL архива, который строит UniPlayer | Форма |
|---|---|---|
…/mpegts | …/timeshift_abs-<startUnixUTC>.ts | Абсолютный таймшифт HTTP-MPEG-TS |
…/index.m3u8, …/mono.m3u8, …/video.m3u8 (HLS) | сегмент index / mono / video → timeshift_rel<seconds> | Относительный HLS-таймшифт (отрицательные секунды) |
Примеры:
Live: https://origin.example/ch/mpegts
Archive: https://origin.example/ch/timeshift_abs-1717400000.ts
Live: https://origin.example/ch/index.m3u8
Archive: https://origin.example/ch/timeshift_rel-3600.m3u8 (1 hour back)
Поэтому ваш Flussonic DVR должен принимать как абсолютную (timeshift_abs-<utc>.ts), так и
относительную (timeshift_rel<-seconds>.m3u8) формы. Это нативные DVR-эндпоинты Flussonic;
никакой особой настройки с вашей стороны, кроме включения DVR для потока, не требуется.
6. Архив Xtream Codes
Когда пользователь добавляет аккаунт Xtream Codes, UniPlayer читает живые потоки через API панели
(player_api.php?action=get_live_streams). Catch-up для каждого потока определяют два поля:
| Поле | Значение |
|---|---|
tv_archive | 1 ⇒ catch-up включён для этого канала; 0 ⇒ нет. |
tv_archive_duration | Целое число дней хранимого архива (например, 7). |
UniPlayer автоматически отображает это в модель catch-up: tv_archive=1 помечает канал как архивный
(внутренний режим xstream-1), а tv_archive_duration становится окном catchup-days. Плейлист
в целом помечается archive_type, чтобы UI объявлял о наличии catch-up.
URL таймшифта Xtream. Нативный формат эндпоинта архива Xtream:
http://host:port/timeshift/USERNAME/PASSWORD/DURATION/START/STREAM_ID.EXT
# e.g.
http://host:port/timeshift/user/pass/60/2026-06-03:14-30/1234.ts
DURATION— минуты запрашиваемого сегмента.START—YYYY-MM-DD:HH-MMв серверной таймзоне архива.EXT—tsилиm3u8.
Рекомендация провайдеру. Catch-up в Xtream сигнализируется через
tv_archive/tv_archive_duration, и именно это UniPlayer читает для окна. Для самого надёжного воспроизведения архива сегодня панели, способные также выдавать M3U-экспорты, должны включать явные атрибутыcatchup="shift"(utc/lutc) илиcatchup="flussonic"на архивных каналах, поскольку эти режимы однозначны и не зависят от origin. Если ваша панель предоставляет только API Xtream, убедитесь, чтоtv_archive_durationточен, чтобы глубина программы передач была верной.
7. Время, временные метки и таймзоны
Эти правила не подлежат обсуждению, чтобы архив совпадал с программой передач:
- Время начала — секунды UTC Unix epoch. UniPlayer подставляет в
${start}/utc/timeshift_abs-…целочисленную временную метку UTC. Ваш origin должен интерпретировать её как UTC. - EPG должен быть корректен по UTC. UniPlayer выводит начало архива из времени начала программы в EPG. Если времена ваших XMLTV-программ расходятся с фактической трансляцией, архив будет начинаться не в тот момент. Публикуйте времена EPG с корректными смещениями таймзоны (UniPlayer нормализует всё к UTC при загрузке).
- Относительные смещения отрицательны. Значения Flussonic
timeshift_rel— это отрицательные секунды (например,-3600= час назад). UniPlayer вычисляет их отnow. - Без клиентской поправочной коррекции. UniPlayer не применяет сдвиг
catchup-correction. Если вашему архиву нужна фиксированная часовая коррекция, заложите её в origin или EPG — не полагайтесь на атрибут поканальной коррекции. - Минимальное смещение. Запросы менее чем ~1 секунды в прошлое откатываются к живому URL.
8. Разобранные примеры
Полный смешанный плейлист, по которому провайдер может смоделировать свой:
#EXTM3U url-tvg="https://origin.example/epg.xml.gz"
# Flussonic origin — simplest, no template needed
#EXTINF:-1 tvg-id="ch.movie" tvg-logo="https://origin.example/logo/movie.png" catchup="flussonic" catchup-days="14",Movie Channel
https://origin.example/movie/index.m3u8
# SIPTV utc/lutc origin
#EXTINF:-1 tvg-id="ch.sports1" catchup="shift" catchup-days="7",Sports 1
https://origin.example/sports1/index.m3u8?token=abc
# Full template (default mode)
#EXTINF:-1 tvg-id="ch.news" catchup="default" catchup-days="5" catchup-source="https://origin.example/news/video-${start}-${duration}.m3u8",News 24
https://origin.example/news/index.m3u8
# Append a query fragment
#EXTINF:-1 tvg-id="ch.kids" catchup="append" catchup-days="3" catchup-source="?utc=${start}",Kids TV
https://origin.example/kids/index.m3u8
# HTTP-MPEG-TS Flussonic (absolute timeshift)
#EXTINF:-1 tvg-id="ch.doc" catchup="flussonic" catchup-days="30",Docs HD
https://origin.example/doc/mpegts
9. Чек-лист провайдера
Прежде чем выпустить плейлист, проверьте:
- У каждого архивного канала есть значение
catchup(илиcatchup-type) из §3. -
catchup-daysзадан и соответствует вашему реальному сроку хранения. - Каналы
default/appendвключаютcatchup-sourceс${start}(и${duration}, если нужно). - Flussonic-каналы предоставляют и
timeshift_abs-<utc>.ts, иtimeshift_rel<-sec>.m3u8. - Ваш origin принимает время начала в формате UTC Unix.
-
tvg-idприсутствует и сопоставляется с каналом EPG (catch-up выбирается из программы передач — нет EPG, нет UI архива). - Времена программ EPG корректны по таймзоне.
- Панели Xtream возвращают точные
tv_archive/tv_archive_duration.
10. Частые ошибки
| Симптом | Вероятная причина |
|---|---|
| Кнопка архива не появляется | Нет tvg-id / нет совпадения в EPG, либо нет catchup/catchup-days, а форму URL нельзя определить. |
| Программа передач отматывается лишь на несколько дней назад | Отсутствует catchup-days → предположение в 30 дней, либо задано меньше реального срока хранения. |
| Архив воспроизводит не тот момент | Времена программ EPG в неверной таймзоне, либо origin трактует ${start} как локальное время, а не UTC. |
| Шаблон не подставляется | Использован токен только для Kodi ({utc}, {Y}{m}{d}…) вместо ${start} / shift / flussonic — переключитесь на поддерживаемый режим (§4). |
| Архив Flussonic отдаёт 404 | DVR не включён для потока, либо origin не принимает timeshift_rel / timeshift_abs. |
| Неверная глубина архива Xtream | tv_archive_duration неточен в панели. |
Связанное
- Формат плейлиста M3U / M3U8 — базовые атрибуты, кодировка и структура.
- XMLTV / EPG — как времена программ питают начало архива.
- UniPlayer — нейтральный плеер; эта спецификация описывает, как должен быть структурирован ваш плейлист, а не какой контент он несёт.