Skip to content

Выгрузка архива

Отрезок записанного архива скачивается одним файлом MP4, который открывается обычными проигрывателями, например VLC. Файл собирается из архива в момент запроса: заранее ничего готовить не нужно, и места на диске выгрузка не занимает.

Выгрузка работает у стрима с включённой записью. Выгружается только MP4: файла MPEG-TS станция не собирает, и запрос .ts отклоняется с 422.

Адрес выгрузки

http://<адрес-станции>/streaming/v/<стрим>/archive-<от>-<длительность>.mp4
  • от — начало отрезка, UTC в секундах;
  • длительность — длина отрезка в секундах.

Например, archive-1789546139-600.mp4 — десять минут архива начиная с указанного момента.

Станция отвечает на GET файлом, а на HEAD — только его заголовками. Пробовать адрес заголовками стоит до скачивания: Content-Length приходит без тела, и размер файла известен заранее. У GET и HEAD исходы совпадают: отказ, который даст скачивание, виден уже на пробе.

Выбор дорожек

Без параметров в файл попадают все видео- и аудиодорожки отрезка. Нужные дорожки выбираются параметром filter.tracks:

http://<адрес-станции>/streaming/v/<стрим>/archive-<от>-<длительность>.mp4?filter.tracks=v1a1

Дорожки обозначаются так же, как в плейлистах: v1, v2 — видео, a1 — аудио. Если в файл не попала ни одна видеодорожка, он отдаётся с типом audio/mp4.

Субтитры и служебные дорожки в выгрузку не идут: они ломают совместимость классического контейнера, ради которой он и выбран. Запрос такой дорожки отклоняется.

Что попадает в файл

  • Начало — файл начинается с ключевого кадра не позже запрошенного момента, поэтому бывает на несколько секунд длиннее запрошенного. Если начало попало в разрыв записи, файл начинается с первого ключевого кадра после разрыва;
  • разрывы записи — склеиваются: в файле только записанное время, и он может оказаться короче запрошенного отрезка;
  • смена параметров дорожки — если в отрезке менялись параметры, например разрешение, файл заканчивается на месте смены. Обрыв общий для всех дорожек: иначе картинка кончилась бы на середине звука.

Имя файла станция предлагает в заголовке Content-Disposition:

<стрим>_<ГГГГ-ММ-ДД>_<ЧЧ-ММ-СС>Z_<секунд>s.mp4

Время в имени — UTC, длительность — фактически записанная, а не ширина выделения: имя не должно врать о содержимом.

Пределы

Два предела живут в настройках машины, раздел DVR, и переживают перезапуск: они меняются применением конфигурации, а не рестартом.

  • export_max_duration_secs — предельная длительность одной выгрузки, секунд. По умолчанию 10800 — три часа, столько же по умолчанию позволяет выделить лента;
  • export_max_concurrent — сколько выгрузок станция выполняет одновременно. По умолчанию 4.

Запрос длиннее потолка отклоняется с 422 до чтения архива. Запрос сверх числа одновременных получает 503 с заголовком Retry-After: повтор через указанное число секунд ничего не потеряет, работа не начиналась.

Нулевое значение не допускается. Потолок длительности режет одну выгрузку, но не их число: десятки одновременных ставят диск в полку, а станция в это время ещё и пишет.

Ответы сервера

Код Когда
200 файл отдаётся
403 стрим зашифрован: классическая выгрузка шифрования не несёт
404 в отрезке нет записи
422 запрос нельзя выполнить, причина названа в теле ответа
503 уже выполняется предельное число выгрузок; повторить через Retry-After секунд

Причины кода 422:

  • длительность больше потолка export_max_duration_secs;
  • названа отсутствующая дорожка — дорожки нет у стрима либо в отрезке у неё нет записи;
  • запрошены субтитры или служебная дорожка;
  • контейнер не MP4 — расширение в адресе иное;
  • параметр packing не compat — выгружается только классический MP4;
  • filter.tracks не является обозначением дорожек;
  • длительность задана как now — выгрузка «до текущего момента» не поддерживается: между пробой и скачиванием край архива уезжает, и объявленная длина разошлась бы с телом.

Если отдача обрывается уже после заголовков — например, отказал диск, — ответ завершается незавершённой передачей: curl сообщает об оборванном соединении, браузер помечает загрузку как неудавшуюся. Файл, который пришёл целиком, содержит весь отрезок.

Счётчики

Выгрузка считается вместе с остальными метриками процесса (см. Мониторинг):

  • archive_export_requests_total — число отданных выгрузок;
  • archive_export_recorded_secs_total — выгружено секунд записи;
  • archive_export_bytes_total — выгружено байт;
  • archive_export_failures_total — отказы с меткой reason.

Отказы по вине клиента и по вине станции разведены намеренно: негодный запрос — не признак поломки, и по нему не стоит будить дежурного.

Что дальше