Встраиваемый плеер
Готовая страница просмотра /<поток>/embed.html: параметры адреса, встраивание через iframe, вкладки протоколов, автозапуск и звук.
У каждого потока есть готовая страница просмотра:
https://media.example.com/<поток>/embed.html
Внешних зависимостей у неё нет: ни библиотек с чужих сайтов, ни шрифтов, ни счётчиков. Всё приходит с того же сервера. Страница отдаётся даже до того, как поток стал живым, — она сама дождётся появления кадров.
Плеер умеет живое видео (HLS, LL-HLS, MSE-WS, DASH, WebRTC), просмотр архива, сдвиг по времени, превью-кадр и публикацию из браузера.
Быстрая проверка#
curl -sS -o /dev/null -w "%{http_code} %{content_type}\n" \ "https://media.example.com/demo/embed.html"
200 text/html; charset=utf-8
Откройте этот адрес в браузере. По умолчанию плеер показывает превью-кадр и кнопку запуска, а выбранная вкладка — протокол по умолчанию, назначенный сервером (обычно HLS).
Параметры адреса#
| Параметр | Значения | Что делает |
|---|---|---|
proto |
hls · hls-ll · mse-ws · dash · webrtc · whip · dvr · timeshift · preview |
выбирает режим. Важнее и настройки по умолчанию, и списка caps |
autostart |
1 · true |
запускает сразу, без нажатия кнопки |
token |
токен доступа | подставляется во все медиа-адреса, которые строит плеер |
ssid |
билет сессии | готовый билет вместо получения нового |
compact |
1 · true |
режим плитки: видео на всю площадь, шапка и вкладки скрыты |
chrome |
0 · false |
скрывает шапку и вкладки, сохраняя обычную раскладку |
chromeless |
1 · true |
то же, что chrome=0 |
debug |
присутствует | включает панель статистики и журнал событий |
from и to |
время Unix в миллисекундах | открывает архив на этом интервале |
dvr |
1 · true |
открывает архив без заданного интервала |
src |
абсолютный адрес медиа | проигрывает именно его; вкладки протоколов при этом не работают |
path |
имя потока | запасной способ указать поток |
Значение ll-hls принимается как синоним hls-ll — старые ссылки продолжают работать.
https://media.example.com/cam1/embed.html?proto=hls-ll&autostart=1 https://media.example.com/cam1/embed.html?proto=mse-ws&compact=1&autostart=1 https://media.example.com/cam1/embed.html?proto=preview https://media.example.com/cam1/embed.html?debug
?proto= — это удобство, а не разграничение доступаЯвно указанный протокол применяется независимо от списка caps. Ограничивать доступ нужно
авторизацией — см. Авторизацию просмотра. Список caps управляет только
тем, какие вкладки видны.
Вкладки протоколов и директива caps#
Набор вкладок сервер выводит сам, по фактам конфигурации: HLS есть всегда; LL-HLS — если включён
low_latency; MSE-WS и DASH — всегда; WebRTC — если задан webrtc <порт>; DVR и Timeshift — если
поток пишет архив; превью — всегда. Вкладка, для которой у сервера нет байтового пути, показывается
неактивной.
Набор можно сузить директивой caps в блоке потока — в одном из двух режимов:
stream cam1 { input rtsp://admin:пароль@10.0.0.10:554/Streaming/Channels/101; caps hls mse-ws; # РАЗРЕШИТЬ: только эти вкладки } stream cam2 { input rtsp://admin:пароль@10.0.0.11:554/Streaming/Channels/101; caps -dash -webrtc; # ЗАПРЕТИТЬ: все, кроме этих }
| Параметр | Тип и допустимые значения | По умолчанию | Применение |
|---|---|---|---|
caps |
список из hls, hls-ll, mse-ws, dash, webrtc, whip, dvr, timeshift, preview — либо все голые (разрешить), либо все с - (запретить) |
авто | горячее |
Смешивать режимы нельзя:
stream "cam1": caps cannot MIX deny (`-x`) and allow (bare) tokens — use one mode
Разрешить протокол, который сервер не отдаёт, тоже нельзя — это ошибка конфигурации, а не пустая вкладка:
stream "cam1": cap "webrtc" not served (not in the derivable set ["hls", "hls-ll", "mse-ws", "dash", "preview"])
При режиме запрета (caps -dash;) новая возможность потока — например, включённый позже архив —
автоматически добавит свою вкладку. Режим разрешения фиксирует набор жёстко, и про него легко
забыть.
Вкладка публикации в списке зрителю не показывается никогда — открывайте её явно через
?proto=whip. См. Приём публикации: RTMP и WHIP.
Текущий набор вкладок и протокол по умолчанию видны в API:
curl -sS "https://media.example.com/api/v1/streams/demo" \ -H "Authorization: Bearer $TOKEN" \ | python3 -c 'import sys, json s = json.load(sys.stdin) print("caps:", s["caps"]) print("default_proto:", s["default_proto"])'
caps: ['hls', 'hls-ll', 'mse-ws', 'dash', 'webrtc', 'dvr', 'timeshift', 'preview'] default_proto: hls
Встраивание в свою страницу#
Плеер встраивается элементом iframe. Для плитки в мозаике используйте ?compact=1: он убирает
шапку и вкладки и растягивает видео на всю площадь кадра.
<iframe src="https://media.example.com/cam1/embed.html?proto=mse-ws&compact=1&autostart=1" style="width:640px;height:360px;border:0" allow="autoplay; fullscreen" allowfullscreen></iframe>
Резиновая вставка с сохранением пропорций 16:9:
<div style="position:relative;width:100%;padding-top:56.25%"> <iframe src="https://media.example.com/cam1/embed.html?proto=hls-ll&autostart=1&chrome=0" style="position:absolute;inset:0;width:100%;height:100%;border:0" allow="autoplay; fullscreen" allowfullscreen></iframe> </div>
| Что нужно | Параметр |
|---|---|
| плитка в мозаике, видео на всю площадь | compact=1 |
| обычная раскладка, но без шапки и вкладок | chrome=0 |
| запуск без нажатия кнопки | autostart=1 |
| разрешить полноэкранный режим из кадра | атрибут allow="autoplay; fullscreen" и allowfullscreen |
Если у потока задан allowed_referers, страница со стороннего домена получит отказ. Список
проверяется по границе точки: example.com разрешает и cdn.example.com, но никогда не
evilexample.com. Слово none в списке дополнительно разрешает запросы без заголовка источника —
прямые ссылки и приложения. Учтите, что включение этого списка отключает кэширование сегментов
потока (см. Протоколы раздачи).
Автозапуск и звук#
Плеер всегда стартует без звука. Это не настройка сервера, а требование браузеров: автозапуск со звуком блокируется, пока пользователь не взаимодействовал со страницей. Стартуя приглушённым, плеер гарантированно запускается, а звук включается кнопкой динамика или ползунком громкости.
Параметра «включить звук сразу» нет и быть не может — браузер всё равно заблокирует такое воспроизведение. Если пользователь уже нажимал что-то на вашей странице, звук можно включить кнопкой в плеере.
Без ?autostart=1 плеер показывает превью-кадр и кнопку запуска — это дешевле: живой поток не
запрашивается, пока зритель не решил смотреть. Для мозаики из многих плиток такой режим экономит и
трафик, и заряд батареи на планшете.
На потоке с on_demand открытие страницы плеера ещё не является спросом — спросом становится
первый запрос медиа. Пока плеер стоит на паузе с превью-кадром, поток не поднимается. С
?autostart=1 он поднимется сразу.
Просмотр архива#
Если поток пишет архив, у плеера появляются вкладки «DVR» и «Timeshift». Открыть нужный интервал можно сразу из адреса — время задаётся в миллисекундах Unix:
https://media.example.com/cam1/embed.html?from=1787143720400&to=1787144020400
Плеер сам переключится в режим архива и начнёт воспроизведение. В этом режиме доступны шкала времени с масштабированием, календарь, выбор скорости и переключение отображаемого часового пояса между временем сервера и временем компьютера.
# интервал «последние 10 минут, кроме последних 5» python3 -c " import time now = int(time.time() * 1000) print(f'https://media.example.com/cam1/embed.html?from={now - 600000}&to={now - 300000}')"
https://media.example.com/cam1/embed.html?from=1787143720400&to=1787144020400
Параметр ?dvr=1 открывает архив без заданного интервала — плеер встанет на доступный край записи.
Подробности о самом архиве — Просмотр и экспорт.
Браузеры не декодируют G.711, поэтому при просмотре архива такая звуковая дорожка отбрасывается —
видео при этом исправно. Выгруженный фрагмент .mp4 сохраняет звук полностью. См.
Протоколы раздачи.
Панель отладки#
Параметр ?debug включает панель статистики: задержка, размер буфера, битрейт, число потерянных и
декодированных кадров, счётчики частей и запросов, восстановления и ошибки, а также журнал событий
проигрывателя. Для WebRTC дополнительно показывается статистика соединения.
https://media.example.com/cam1/embed.html?proto=mse-ws&autostart=1&debug
Это первое, что стоит открыть при жалобе на «рассыпается» или «отстаёт»: в журнале видно, что именно происходит — переподключение, пересинхронизация буфера или ошибка загрузки сегмента.
Передача токена#
Если раздача закрыта авторизацией, передайте токен параметром — плеер подставит его во все медиа-адреса, которые строит:
https://media.example.com/cam1/embed.html?proto=hls&token=$TOKEN
Для встраивания на публичной странице выпускайте короткоживущие токены, ограниченные одним потоком, а не общий токен на всё. См. Авторизацию просмотра.
Куда двигаться дальше#
- Протоколы раздачи — какой протокол выбрать и что он несёт.
- Авторизация просмотра — как закрыть поток и выпустить токен.
- Просмотр и экспорт — работа с архивом.
- Приём публикации: RTMP и WHIP — публикация из браузера через
?proto=whip.