VoD — видео по запросу
Раздача готовых MP4-файлов из каталога как конечных HLS-плейлистов и прямых загрузок с перемоткой, без предварительной обработки.
VoD (video on demand, видео по запросу) — раздача заранее подготовленных файлов из каталога на
диске. Вы кладёте .mp4 в каталог, объявляете этот каталог библиотекой — и файлы сразу играются в
браузере как обычное потоковое видео, с перемоткой по всей длительности.
Никакой подготовки не требуется: ни перекодирования, ни переупаковки, ни этапа импорта. Плейлист и куски синтезируются на лету при первом обращении, исходные файлы не меняются.
Чем VoD отличается от архива#
| Архив (DVR) | VoD | |
|---|---|---|
| Откуда берётся материал | сервер записывает живой поток сам | файлы кладёте вы |
| Единица | непрерывная лента времени | отдельный файл |
| Как адресуется | поток + интервал времени | путь к файлу |
| Как настраивается | строка dvr внутри stream |
блок vod <имя> <каталог> |
| Что происходит со старым | вытесняется по ретенции | ничего, файлы лежат, пока вы их не удалите |
| Длительность | ограничена глубиной архива | ограничена размером файла (см. предел ниже) |
Механизмы независимы: VoD можно использовать без единого пишущего потока, а архив — не объявляя ни одной библиотеки. Общее у них одно: собственные записи архива тоже являются корректными файлами и играются через VoD, если положить их в библиотеку.
Объявление библиотеки#
vod movies /srv/media/movies { segment_duration 6; }
| Параметр | Тип и допустимые значения | По умолчанию | Применение |
|---|---|---|---|
<имя> |
[A-Za-z0-9._-]+, не . и не .., уникально |
— (обязателен) | горячее |
<корень> |
абсолютный путь к каталогу | — (обязателен) | горячее |
segment_duration |
целое, секунды | 6 |
горячее |
Имя библиотеки становится частью URL, поэтому менять его позже — значит менять все выданные ссылки.
Тело { } необязательно: vod movies /srv/media/movies; — рабочая запись.
line 24: `vod` takes <name> <root> { … } or a bare `vod { … }` tuning block
Библиотек может быть сколько угодно — по блоку на каждую:
vod movies /srv/media/movies; vod lessons /srv/media/lessons { segment_duration 4; }
Изменения применяются по systemctl reload hastreamer и не затрагивают ни живые потоки, ни архив.
segment_duration влияет только на скорость стартаКороткие куски начинают играть быстрее, но дают больше запросов на ту же минуту видео. Значение по умолчанию (6 с) подходит почти всегда; менять его имеет смысл, только если вы измерили задержку старта и она вас не устраивает. В конфигурации диапазон не проверяется; при создании библиотеки через API значение приводится к 1–60 секундам.
Глобальная настройка кеша#
Отдельный блок vod { } без имени и пути настраивает не библиотеку, а кеш разбора файлов:
vod { index_cache 64; index_ttl 300; }
| Параметр | Тип и допустимые значения | По умолчанию | Применение |
|---|---|---|---|
index_cache |
целое 1…4096 |
64 |
горячее |
index_ttl |
целое 1…86400, секунды |
300 |
горячее |
vod { index_cache } must be 1..=4096 (0 is not a valid 'unlimited'); got 0
vod { index_ttl } must be 1..=86400 seconds; got 0
line 31: unknown vod tuning directive "cache_size" (want index_cache/index_ttl)
index_cache — ограничение на ядро, и оно же ограничивает число открытых файловых дескрипторов:
проверенный дескриптор хранится вместе с разобранным индексом, отдельной настройки для файлов нет.
Кеш подметается при каждом обращении к /vod, поэтому простаивающая или удалённая библиотека
освобождает дескрипторы сама. Изменение конфигурации сбрасывает индекс и дескриптор вместе, так
что после замены файла новый разбор никогда не смешается со старыми смещениями.
В кеше лежит только индекс, никогда не медиаданные — за горячие участки файлов отвечает страничный кеш операционной системы.
Какие файлы раздаются#
- Контейнеры: обычный (прогрессивный) MP4 и фрагментированный MP4. Расширения —
.mp4,.m4v,.mov, регистр не важен. faststartне требуется. Расположение служебных данных внутри файла роли не играет.- Видео: H.264, H.265, AV1, VP9. В файле должен быть хотя бы один видеотрек и хотя бы один ключевой кадр — иначе файл не раздаётся.
- Звук: AAC или Opus.
- B-кадры обрабатываются корректно, порядок вывода сохраняется.
Такой файл разбирается, но звуковая дорожка не нарезается. Сервер честно не объявляет звук в плейлисте, вместо того чтобы обещать дорожку, которую не отдаст. Кадр-превью доступен только у файлов H.264 и H.265; у AV1 и VP9 его нет, и плеер спокойно переживает отсутствие.
Перекодирования в продукте нет: что положили, то и раздаётся. Готовьте нужные форматы заранее.
Чтобы разобрать файл, сервер однократно читает его целиком в память (именно поэтому неважно,
где внутри файла лежат служебные данные). Действует ограничение 1 ГиБ на файл и такой же общий
бюджет на все одновременные разборы. Файл больше 1 ГиБ отвечает 404 на всех синтезированных
HLS-адресах.
Прямая загрузка файла (маршрут без /playlist.m3u8) этим не ограничена — она не разбирает файл
вовсе и отдаёт любой размер с поддержкой докачки. Если материал крупный, режьте его на части
заранее.
Адреса#
Обратите внимание на форму: имя файла — это часть пути, а служебные объекты висят под ним.
| Адрес | Что отдаёт |
|---|---|
/vod/<библиотека>/<путь>/<файл.mp4>/playlist.m3u8 |
конечный плейлист HLS-VOD |
/vod/<библиотека>/<путь>/<файл.mp4>/init.mp4 |
заголовок инициализации |
/vod/<библиотека>/<путь>/<файл.mp4>/seg-<N>.m4s |
кусок медиаданных, нумерация с 1 |
/vod/<библиотека>/<путь>/<файл.mp4>/thumb-<мс>.mp4 |
кадр-превью на указанной миллисекунде |
/vod/<библиотека>/<путь>/<основа>/master.m3u8 |
мастер-плейлист нескольких качеств |
/vod/<библиотека>/<путь>/<файл.mp4> |
прямая загрузка файла с поддержкой докачки |
Для файла /srv/media/movies/lesson-01.mp4 в библиотеке movies адрес воспроизведения такой:
http://media.example.com:8080/vod/movies/lesson-01.mp4/playlist.m3u8
Тот же файл целиком:
curl -sS -O "http://media.example.com:8080/vod/movies/lesson-01.mp4"
Пути внутри библиотеки могут быть вложенными, содержать пробелы и не-латиницу — в URL они
записываются в процентном кодировании. Файл 2026/лекция 1.mp4 адресуется так:
/vod/movies/2026/%D0%BB%D0%B5%D0%BA%D1%86%D0%B8%D1%8F%201.mp4/playlist.m3u8
init.mp4 рядом с одноимённым каталогом недостижимЕсли в библиотеке существует каталог с именем вида что-то.mp4, а внутри него лежит настоящий файл
init.mp4, обратиться к этому файлу нельзя: адрес уже занят синтезированным заголовком
инициализации. Не называйте каталоги как медиафайлы.
Перемотка#
Плейлист VoD конечный: он содержит все куски файла и завершается EXT-X-ENDLIST. Плеер сразу
знает полную длительность и переходит в любую точку без обращения к серверу за «разрешением» —
запрашивается только нужный кусок.
Прямая загрузка поддерживает диапазоны байт (Range) и ответы 206, поэтому файл можно и
докачивать, и мотать в плеере, который работает с файлом напрямую:
curl -sS -r 0-1023 -o /dev/null -D - \ "http://media.example.com:8080/vod/movies/lesson-01.mp4" | head -4
HTTP/1.1 206 Partial Content Content-Type: video/mp4 Content-Range: bytes 0-1023/734003200 Accept-Ranges: bytes
Прямой маршрут читает файл ограниченными порциями и не трогает кеш индексов — это дешёвый путь для загрузки, но у него нет ни выбора качества, ни превью.
Несколько качеств одного материала#
Мастер-плейлист собирается по соглашению об именах: файлы-соседи вида <основа>_<кбит/с>.mp4
объединяются в одну группу. Достаточно двух пригодных файлов.
/srv/media/movies/lesson-01_800.mp4 /srv/media/movies/lesson-01_2400.mp4 /srv/media/movies/lesson-01_5000.mp4
http://media.example.com:8080/vod/movies/lesson-01/master.m3u8
Плеер сам выберет подходящее качество и будет переключаться на ходу.
Сервер только группирует уже подготовленные файлы по именам. Набор качеств вы готовите сами, вне сервера. Для живого видео адаптивного качества нет вовсе — это потребовало бы перекодирования, которого в продукте нет.
Управление и наблюдение#
Библиотеки настраиваются не только в файле:
| Запрос | Действие |
|---|---|
GET /api/v1/vod |
список библиотек, их файлы и статистика воспроизведений |
POST /api/v1/vod/libraries/{имя} |
создать или изменить библиотеку: {"root":"…","segment_duration":6} |
DELETE /api/v1/vod/libraries/{имя} |
удалить библиотеку; файлы на диске не трогаются |
curl -sS "http://media.example.com:8080/api/v1/vod" \ -H "Authorization: Bearer $TOKEN"
{"libraries":[],"tuning":{"index_cache":64,"index_ttl":300}}
Инвентаризация в GET /api/v1/vod намеренно не обходит подкаталоги и берёт только верхний уровень,
не более 500 файлов: обход большой библиотеки на каждый запрос панели стоил бы дороже самой раздачи.
На воспроизведение это не влияет — по прямой ссылке играется любой файл на любой глубине
вложенности, просто в списке панели он не появится.
В панели управления библиотеки живут на странице VoD: создание и правка, раскрывающийся список файлов, кнопки открыть по HLS, скопировать ссылку и скачать.
Доступ#
Когда авторизация просмотра включена, VoD проверяется тем же правом, что и архив — dvr, но на
собственном ресурсе vod/<библиотека>/<файл>. Сессия просмотра VoD живёт дольше живой: длительность
задаётся session_keys { vod_session_ttl }, по умолчанию 24 часа (допустимо от 300 до 604800
секунд) — чтобы просмотр длинного материала не прерывался посреди фильма.
Безопасность путей обеспечивается не разбором строки, а проверкой уже открытого файла: сервер убеждается, что открытый дескриптор находится внутри корня библиотеки и указывает на обычный файл, и дальше читает только через этот дескриптор. Символическая ссылка наружу, подмена пути после открытия, именованный канал или файл устройства отклоняются.
Без неё VoD, как и любая другая раздача, не отдаёт ни одного кадра, хотя панель и API продолжают отвечать. См. Лицензирование.
curl -sS -o /dev/null -w '%{http_code} %{content_type}\n' \ "http://media.example.com:8080/vod/movies/lesson-01.mp4/playlist.m3u8"
200 application/vnd.apple.mpegurl
404 означает одно из трёх: библиотеки с таким именем нет, файла по такому пути нет, либо файл
больше 1 ГиБ и потому недоступен на синтезированных адресах. Проверьте первые две причины запросом
GET /api/v1/vod, третью — размером файла.
Куда двигаться дальше#
- Запись архива (DVR) — если материал должен писаться сервером, а не приноситься файлами.
- Просмотр и экспорт — просмотр архива и выгрузка фрагментов.
- Протоколы раздачи — чем VoD отдаётся зрителю.