...
В этом случае поток будет захвачен из указанного источника, и после публикации на сервере начнется его проигрывание по HLS. Обратите внимание, что URI должен быть закодирован, все символы, кроме алфавитно-цифровых, должны быть экранированы.
В сборке 5.2.1679 добавлена возможность играть поток по URI источника, как HLS ABR
Code Block | ||
---|---|---|
| ||
http://wcs:8082/vod-live%3A%2F%2Ffile.mp4-HLS-ABR-STREAM/vod-live%3A%2F%2Ffile.mp4-HLS-ABR-STREAM.m3u8 |
При обращении к Edge серверу в CDN, если поток с указанным именем или URI опубликован на Origin сервере, по HLS начнет проигрываться поток из CDN. Если такого потока в CDN нет, Edge попытается захватить поток по указанному URI локально.
...
Автоматическая нарезка HLS сегментов для опубликованного потока
При необходимости, может быть настроена аутентификация клиентов для воспроизведения потока по HLS. В файле любой из потоков, опубликованных на сервере по WebRTC, RTMP, MPEG-TS, или захваченный из RTSP или RTMP источника по REST API, может автоматически нарезаться на HLS сегменты. Эта возможность включается настройкой
Code Block | ||
---|---|---|
| ||
hls_auto_start=true |
В сборке 5.2.1895 добавлена возможность автоматической нарезки HLS ABR, при условии, что используется HLS ABR на одном узле. Эта возможность включается настройкой
Code Block | ||
---|---|---|
| ||
hls_abr_auto_start=true |
Аутентификация воспроизведения HLS с помощью REST hook
При необходимости, может быть настроена аутентификация клиентов для воспроизведения потока по HLS. В файле flashphoner.properties должна быть установлена настройка
...
В сборке 5.2.1008 добавлена возможность указать ключ приложения для аутентификации в HLS URL, например
Code Block | ||
---|---|---|
| ||
httpыhttps://wcs:8445/streamName/streamName.m3u8?appKey=customAppKey&aclAuth=1254789 |
...
REST-метод | Пример тела REST-запроса | Пример тела REST-ответа | Статусы ответа | Описание | ||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
/hls/startup |
| 200 - OK 404 - Stream not found 500 - Internal error | Запустить HLS нарезку указанного потока | |||||||||||||||
/hls/find_all |
|
| 200 – OK 404 – Not found | Найти все потоки, для которых есть HLS нарезки | ||||||||||||||
/hls/terminate |
| 200 – OK 404 – Not found | Завершить или перезапустить HLS нарезку указанного потока |
Параметры
...
Имя параметра
...
Описание
...
Пример
...
name
...
Имя потока, опубликованного на сервере
...
test
Особенности
1. Если HLS нарезка потока запущена при помощи REST запроса /hls/startup, и нет активных HLS подписчиков, нарезка остановится по истечении интервала в секундах
Code Block | ||
---|---|---|
| ||
hls_manager_provider_timeout=300 |
По умолчанию, интервал составляет 5 минут. То же касается автоматически созданных HLS нарезок при установленной настройке
Code Block | ||
---|---|---|
| ||
hls_auto_start=true |
2. Если HLS нарезка потока останавливается при помощи REST запроса /hls/terminate, и есть активные HLS подписчики, то нарезка будет перезапущена. При этом активные HLS подписчики должны повторно подключиться к потоку.
Поддержка HLS ABR
Устаревшая реализация в сборках 5.2.484 - 5.2.582
В сборке 5.2.484 добавлена поддержка HLS ABR плейлистов. Использование этой возможности включается при помощи настройки
Code Block | ||
---|---|---|
| ||
hls_master_playlist_enabled=true |
Имя основного плейлиста указывается при помощи настройки
Code Block | ||
---|---|---|
| ||
hls_manifest_file=index.m3u8 |
Браузер должен запросить основной плейлист по URL
Code Block | ||
---|---|---|
| ||
https://wcs_address:8445/streamName/index.m3u8 |
Здесь
- wcs_address - адрес WCS сервера
- streamName - имя потока на сервере
- index.m3u8 - имя основного плейлиста
При запросе основного плейлиста сервер проверяет наличие потоков, транскодируемых из указанного потока согласно профилям транскодинга, перечисленным в файле настроек cdn_profiles.yml, например:
Code Block | ||
---|---|---|
| ||
profiles:
-720p:
video:
height: 720
bitrate: 1000
codec: h264
-480p:
video:
height: 480
bitrate: 1000
codec: h264
-240p:
video:
height: 240
bitrate: 400
codec: h264 |
Все транскодированные потоки по профилям, которые в момент запроса опубликованы на сервере, попадают в основной плейлист, например:
Code Block | ||
---|---|---|
| ||
#EXTM3U
#EXT-X-STREAM-INF:BANDWIDTH=1000000,RESOLUTION=1280x720,CODECS="avc1.42e01f,mp4a.40.2"
../streamName-720p/streamName-720p.m3u8
#EXT-X-STREAM-INF:BANDWIDTH=1000000,RESOLUTION=852x480,CODECS="avc1.42e01f,mp4a.40.2"
../streamName-480p/streamName-480p.m3u8
#EXT-X-STREAM-INF:BANDWIDTH=400000,RESOLUTION=426x240,CODECS="avc1.42e01f,mp4a.40.2"
../streamName-240p/streamName-240p.m3u8
#EXT-X-STREAM-INF:BANDWIDTH=2500000,RESOLUTION=1280x720,CODECS="avc1.42e01f,mp4a.40.2"
../streamName/streamName.m3u8 |
Затем браузер, в зависимости от пропускной способности канала, переключается между потоками, перечисленными в основном плейлисте.
Warning |
---|
В момент, когда браузер запрашивает основной плейлист, потоки уже должны быть опубликованы на сервере и нарезаться на HLS сегменты |
Чтобы обеспечить наличие потоков, необходимо:
1. На отдельно стоящем сервере:
1.1. Периодически проверять, транскодируются ли потоки к указанным параметрам, и запускать транскодинг при необходимости при помощи REST API
Code Block | ||||
---|---|---|---|---|
| ||||
curl -s -X POST -d "{\"uri\":\"transcoder://tcode_test-240p\",\"remoteStreamName\":\"test\",\"localStreamName\":\"test-240p\",\"encoder\":{\"width\":320,\"height\":240}}" http://localhost:8081/rest-api/transcoder/startup
curl -s -X POST -d "{\"uri\":\"transcoder://tcode_test-480p\",\"remoteStreamName\":\"test\",\"localStreamName\":\"test-480p\",\"encoder\":{\"width\":640,\"height\":480}}" http://localhost:8081/rest-api/transcoder/startup
curl -s -X POST -d "{\"uri\":\"transcoder://tcode_test-720p\",\"remoteStreamName\":\"test\",\"localStreamName\":\"test-720p\",\"encoder\":{\"width\":1280,\"height\":720}}" http://localhost:8081/rest-api/transcoder/startup |
1.2. Периодически запускать HLS потоки для включения в основной плейлист, например
Code Block | ||||
---|---|---|---|---|
| ||||
curl -s -X POST -d "{\"name\":\"test\"}" http://localhost:8081/rest-api/hls/startup
sleep 1
curl -s -X POST -d "{\"name\":\"test-240p\"}" http://localhost:8081/rest-api/hls/startup
sleep 1
curl -s -X POST -d "{\"name\":\"test-480p\"}" http://localhost:8081/rest-api/hls/startup
sleep 1
curl -s -X POST -d "{\"name\":\"test-720p\"}" http://localhost:8081/rest-api/hls/startup |
2. На Edge сервере в CDN периодически запрашивать HLS потоки по профилям, например
Code Block | ||||
---|---|---|---|---|
| ||||
curl -s http://localhost:8082/test/test.m3u8
sleep 1
curl -s http://localhost:8082/test-240p/test-240p.m3u8
sleep 1
curl -s http://localhost:8082/test-480p/test-480p.m3u8
sleep 1
curl -s http://localhost:8082/test-720p/test-720p.m3u8
sleep 1 |
Актуальная реализация в сборках 5.2.585 и новее
В сборке 5.2.585 реализация HLS ABR существенно изменена. Как и прежде, HLS ABR может использоваться только в CDN, при этом все транскодированные потоки для вариантов в ABR манифесте Edge забирает одновременно в пределах одной медиасессии, чтобы варианты одного потока были синхронизированы друг с другом. Это требует совместной настройки Transcoder и Edge узлов и накладывает ряд ограничений. Рассмотрим их ниже.
Настройки Transcoder узлов
Для того, чтобы все варианты одного потока были синхронизированы между собой, на Transcoder узлах должно быть включено выравнивание кодирования
Code Block | ||
---|---|---|
| ||
transcoder_align_encoders=true |
Кроме того, должен быть включен FPS фильтр
Code Block | ||
---|---|---|
| ||
video_filter_enable_fps=true
video_filter_fps=25 |
Ключевые фреймы в вариантах потока должны быть синхронизированы. Например, при 25 кадрах в секунду будем отправлять ключевой фрейм каждые 2 секунды
Code Block | ||
---|---|---|
| ||
video_filter_fps_gop_synchronization=50 |
Настройки HLS Edge узлов
На HLS Edge узлах необходимо отключить использование прелоадера и транскодирование потоков
Code Block | ||
---|---|---|
| ||
hls_preloader_enabled=false
hls_player_width=0
hls_player_height=0 |
Необходимо также настроить профили транскодирования в файле cdn_profiles.yml
Code Block | ||||
---|---|---|---|---|
| ||||
profiles:
-240p:
audio:
codec : mpeg4-generic
rate : 48000
video:
height : 240
bitrate : 300
gop : 50
codec : h264
-480p:
video:
height : 480
bitrate : 600
gop : 50
codec : h264
-720p:
video:
height : 720
bitrate : 1000
gop : 50
codec : h264 |
Обратите внимание, что параметры звука можно указать для первого профиля, т.к. для всех профилей эти параметры должны быть идентичными и будут применены по первому из профилей.
Затем необходимо включить HLS ABR
Code Block | ||
---|---|---|
| ||
hls_abr_enabled=true |
Использование
Клиент должен запрашивать плейлист HLS ABR, указывая имя потока с суффиксом
Code Block | ||
---|---|---|
| ||
https://server:8445/test_0-HLS-ABR-STREAM/test_0-HLS-ABR-STREAM.m3u8 |
Суффикс задается при помощи настройки
Code Block | ||
---|---|---|
| ||
hls_abr_stream_name_suffix=-HLS-ABR-STREAM |
Плейлист содержит ссылки на плейлисты вариантов потока, между которыми клиент может переключаться
Code Block | ||
---|---|---|
| ||
#EXTM3U
#EXT-X-STREAM-INF:BANDWIDTH=614400,RESOLUTION=852x480,CODECS="avc1.42e01f,mp4a.40.2"
-480p/-480p.m3u8
#EXT-X-STREAM-INF:BANDWIDTH=1024000,RESOLUTION=1278x720,CODECS="avc1.42e01f,mp4a.40.2"
-720p/-720p.m3u8
#EXT-X-STREAM-INF:BANDWIDTH=307200,RESOLUTION=426x240,CODECS="avc1.42e01f,mp4a.40.2"
-240p/-240p.m3u8 |
Если запросить поток без суффикса, будет играть HLS без поддержки ABR.
Предотвращение транскодирования к более высоким разрешениям
Если транскодирование к более высоким разрешениями отключено на HLS ABR Edge сервере
Code Block | ||
---|---|---|
| ||
cdn_strict_transcoding_boundaries=true |
то варианты, соответствующие профилям с более высокими разрешениями, для данного потока не будут нарезаться и не будут доступны плееру.
Ограничения
1. HLS Edge может быть использован только для воспроизведения HLS потоков, клиентские сессии с использованием других протоколов работать не будут.
2. Не работают такие функции, как запись, снятие снапшотов, микширование, захват потоков с другого сервера и прочие функции обработки потоков
Хранение сегментов HLS
Использование диска
По умолчанию HLS-сегменты записываются на диск сервера, в каталог /usr/local/FlashphonerWebCallServer/hls. Начиная со сборки 5.2.687, каталог для сохранения сегментов можно изменить при помощи параметра
Code Block | ||
---|---|---|
| ||
hls_dir=/usr/local/FlashphonerWebCallServer/hls |
(Расположение прелоадера настраивается отдельно при помощи параметра hls_preloader_dir.)
На диске хранится количество сегментов, соответствующее заданному размеру плейлиста, по умолчанию 10
Code Block | ||
---|---|---|
| ||
hls_list_size=10 |
Чем меньше количество сегментов в плейлисте, тем меньше задержка при воспроизведении. Однако при коротком плейлисте подписчики с недостаточной пропускной способностью каналов могут запрашивать сегменты, которых уже нет в плейлисте и на диске. В связи с этим, в сборке 5.2.581 добавлена возможность хранить некоторое число сегментов на диске после их ухода из плейлиста. Эта возможность включается настройкой
Code Block | ||
---|---|---|
| ||
hls_hold_segments_before_delete=true |
По умолчанию, будет храниться 5 последних сегментов
Code Block | ||
---|---|---|
| ||
hls_hold_segments_size=5 |
Например, если плейлист содержит 3 сегмента
Code Block | ||
---|---|---|
| ||
#EXTM3U
#EXT-X-VERSION:8
#EXT-X-TARGETDURATION:11
#EXT-X-MEDIA-SEQUENCE:15
#EXT-X-DISCONTINUITY-SEQUENCE:1
#EXTINF:3.415,
test_017.ts
#EXTINF:10.417,
test_018.ts
#EXTINF:9.084,
test_019.ts |
на диске будут храниться 3 текущих сегмента из плейлиста и 5 предшествующих
Code Block | ||
---|---|---|
| ||
test_012.ts
test_013.ts
test_014.ts
test_015.ts
test_016.ts
test_017.ts
test_018.ts
test_019.ts |
Использование оперативной памяти
При больших нагрузках на сервер, например, если он выделен для раздачи потоков по HLS, чтение сегментов с диска для отправки подписчикам может давать задержки. В этом случае необходимо включить хранение HLS сегментов в памяти
Code Block | ||
---|---|---|
| ||
hls_store_segment_in_memory=true |
Для отправки подписчикам сегменты будут считываться из памяти, а также будут записываться на диск, в целях отладки. Необходимо отметить, что в этом случае потребуется больше памяти под Java heap для хранения сегментов.
Отладочные логи для HLS-сессии
Для отчета об ошибке можно, используя CLI, включить сбор отладочных логов для HLS-сессий
Code Block | ||||
---|---|---|---|---|
| ||||
update node-setting --value true hls_enable_session_debug |
Следует учесть, что файл настроек flashphoner.properties будет перезаписан после этой команды.
Поддержка Low Latency HLS
Начиная со сборки 5.2.1181, поддерживается Low Latency HLS (LL HLS). Эта возможность включается при помощи настройки
Code Block | ||
---|---|---|
| ||
hls_ll_enabled=true
hls_new_http_stack=true |
В этом случае плееры, которые поддерживают LL HLS (например, HLS.JS), будут играть дополнительные HLS сегменты и давать меньшую задержку по сравнению с плеерами, которые их не играют (например, VideoJS).
Для того, чтобы LL HLS проигрывался корректно, необходимо, как и для обычного HLS, обеспечить стабильный FPS публикуемого потока и стабильный интервал между ключевыми кадрами. Таким образом, исходный поток рекомендуется публиковать как RTMP с параметрами
При публикации WebRTC потока рекомендуется включать транскодинг для HLS, например
Code Block | ||
---|---|---|
| ||
hls_player_width=848
hls_player_height=480
video_filter_enable_fps=true |
Каталог для нарезки сегментов LL HLS
По умолчанию, сегменты LL HLS помещаются в подкаталоги с именами потоков в каталог
Code Block | ||
---|---|---|
| ||
ll_hls_dir=/usr/local/FlashphonerWebCallServer/ll-hls |
При изменении местоположения, например
Code Block | ||
---|---|---|
| ||
ll_hls_dir=/opt/ll-hls |
необходимо назначить права доступа командой
Code Block | ||||
---|---|---|---|---|
| ||||
/usr/local/FlashphonerWebCallServer/bin/webcallserver set-permissions |
и перезапустить WCS, чтобы применить изменения.
Прелоадер для LL HLS
Как и для обычного HLS, для LL HLS может использоваться прелоадер. Сегменты прелоадера LL HLS по умолчанию помещаются в каталог
Code Block | ||
---|---|---|
| ||
ll_hls_preloader_dir=/usr/local/FlashphonerWebCallServer/ll-hls/.preloader |
Расположение может быть изменено, например
Code Block | ||
---|---|---|
| ||
ll_hls_preloader_dir=/opt/preloader |
Настройка собственного прелоадера
При необходимости, для LL HLS может быть настроен собственный прелоадер. Для этого рекомендуется использовать экземпляр WCS сервера, предназначенный для тестирования, но не для эксплуатации. Прелоадер создается следующим образом:
1. Установить следующие настройки сервера
Code Block | ||
---|---|---|
| ||
hls_preloader_enabled=false
ll_hls_create_preloader=true
hls_auto_start=true |
и перезапустить WCS
2. Опубликовать RTMP поток из OBS на сервер, используя в качестве источника видео с соотношением сторон 16:9, указав имя потока index
Code Block | ||
---|---|---|
| ||
rtmp://wcs:1935/live/index |
При этом необходимо указать Resize output (source size)
3. По умолчанию, сегменты прелоадера будут записаны в каталог
Code Block | ||
---|---|---|
| ||
ll_hls_custom_preloader_dir=/usr/local/FlashphonerWebCallServer/custom-preloader/created-segments |
Достаточно записать до 20 основных сегментов index0.ts
- index20.ts
4. После остановки публикации переместить сегменты прелоадера в каталог, где будет располагаться прелоадер
Code Block | ||||
---|---|---|---|---|
| ||||
cd /usr/local/FlashphonerWebCallServer/custom-preloader/created-segments
cp index*.ts /opt/preloader/16x9
rm -rf index*.ts |
5. Повторить шаги 2-4 с источниками с соотношением сторон 4:3 и 2:1
6. Восстановить настройки сервера и указать расположение прелоадера
Code Block | ||
---|---|---|
| ||
ll_hls_preloader_dir=/opt/preloader |
затем перезапустить сервер
Известные проблемы
1. Невосстанавливаемый фриз HLS потока при воспроизведении в iOS Safari через CDN
Симптомы: через одну минуту после начала публикации изображение останавливается, звук продолжает воспроизводиться
Решение:
а) включить транскодинг на сервере при помощи настройки в файле flashphoner.properties
Code Block | ||||
---|---|---|---|---|
| ||||
disable_streaming_proxy=true |
б) если включение транскодинга нежелательно, установить в файле flashphoner.properties
Code Block | ||||
---|---|---|---|---|
| ||||
hls_discontinuity_enabled=true |
в этом случае возможны щелчки в аудиопотоке, но изображение останавливаться не будет.
2. Прекращение записи сегментов HLS при воспроизведении потока. опубликованного в браузере Firefox
Симптомы: через несколько минут после начала воспроизведения прекращается запись HLS-сегментов, при этом директория потока в директории hls не удаляется, в логе сервера продолжают появляться сообщения
Code Block | ||||
---|---|---|---|---|
| ||||
INFO HLSStreamManager - HLSStreamProviderKeepaliveThread-80 Remove hls channel |
Для восстановления публикующая сторона должна заново опубликовать поток.
Решение: использовать другой браузер для публикации потока, который предполагается воспроизводить по HLS.
3. При воспроизведении HLS в Safari в iOS 12.4 не играет видео для первого подписчика
Симптомы: при подключении первого подписчика к потоку по HLS в Safari в iOS 12.4 видео не воспроизводится, если HLS-подписчики уже есть, видео играет нормально
Решение: установить минимальное количество сегментов в плейлисте HLS не менее 2
Code Block | ||
---|---|---|
| ||
hls_min_list_size=2 |
4. При воспроизведении RTMP-потока как HLS в Safari в iOS 12.4 не играет видео для любого подписчика, если активна настройка
Code Block | ||
---|---|---|
| ||
hls_auto_start=true |
Симптомы: при подключении подписчиков к RTMP потоку по HLS в Safari в iOS 12.4 видео не воспроизводится
Решение: при публикации файла со звуковой дорожкой стерео, использовать моно звук, например, для ffmpeg указать настройку
Code Block | ||
---|---|---|
| ||
-acodec aac -ac 1 |
5. Если по HLS проигрывается поток, транскодированный в CDN, и если при этом изменяется соотношение сторон потока, HLS прелоадер отображается в соответствии с соотношением сторон оригинального потока
Симптомы: при заказе транскодированного потока с указанием профиля в имени, например test-640x480p, отображается прелоадер 16:9, если исходный поток опубликован в разрешении 1280x720
Решение: включить на транскодере сохранение соотношения сторон
Code Block | ||
---|---|---|
| ||
video_transcoder_preserve_aspect_ratio=true |
6. Если в исходном потоке содержатся B-фреймы, в некоторых плеерах могут наблюдаться подергивания
Симптомы: сильно дергается картинка при проигрывании HLS, возможен эффект низкого FPS
Решение: обновить WCS до сборки 5.2.863, в которой решена данная проблема
7. При проигрывании LL HLS в браузере Safari, при первом подключении к потоку может пропадать звук
Симптомы: поток играет по LL HLS, но нет звука
...
/hls/profiles |
|
| 200 – OK 400 – Bad request 404 – Not found | Получить статистику профиля нарезки HLS | ||||||||||||||
/hls/subscribers |
|
| 200 – OK 400 – Bad request 404 – Not found | Получить список подписчиков на HLS нарезку |
Параметры
Имя параметра | Описание | Пример |
---|---|---|
name | Имя потока, опубликованного на сервере | test |
state | Статус HLS нарезки | ACTIVE |
logs | Сообщения о проблемах с LL HLS потоком | [] |
Особенности
1. Если HLS нарезка потока запущена при помощи REST запроса /hls/startup, и нет активных HLS подписчиков, нарезка остановится по истечении интервала в секундах
Code Block | ||
---|---|---|
| ||
hls_manager_provider_timeout=300 |
По умолчанию, интервал составляет 5 минут. То же касается автоматически созданных HLS нарезок при установленной настройке
Code Block | ||
---|---|---|
| ||
hls_auto_start=true |
2. Если HLS нарезка потока останавливается при помощи REST запроса /hls/terminate, и есть активные HLS подписчики, то нарезка будет перезапущена. При этом активные HLS подписчики должны повторно подключиться к потоку.
Отображение сообщений о проблемах с LL HLS потоком
В сборке 5.2.1709 добавлена возможность вывода сообщений о проблемах с LL HLS потоком в ответ на REST API запрос /hls/find_all
:
Code Block | ||||
---|---|---|---|---|
| ||||
{
"test": {
"handler": "com.flashphoner.server.client.handler.wcs4.WCS4Handler@74dbf27b",
"state": "ACTIVE",
"writer": "HLS-test",
"streamStatus": "PLAYING",
"writerStarted": "true",
"logs": [
"2023-07-18T10:22:52.457 WARNING: Playback speed changed to 0.779, segment 49, media type: video",
"2023-07-18T10:22:56.614 WARNING: Gap{from=112000, to=114000, duration=2000}, media type: video",
"2023-07-18T10:22:56.615 WARNING: Fps changed from 30 to 27, segment 50 , media type: video",
"2023-07-18T10:22:56.624 WARNING: Segment 51.1 have no data, pts 112400, duration 400, media type: video",
...
]
}
} |
По умолчанию, для каждого потока выводится до 50 последних сообщений. Это значение может быть изменено при помощи настройки
Code Block | ||
---|---|---|
| ||
hls_metrics_log_size=50 |
Диагностируются следующие проблемы:
Fps changed from x to y
- скачок FPS потока более 10 %Segment x does not start with keyframe
- интервал между ключевыми кадрами потока превышает длительность одного сегментаPlayback speed changed to x
- скорость проигрывания потока измениласьSegment interval is too big
- слишком большой интервал между сегментами- Video resolution changed from x to y - разрешение потока изменилось
Gap{from=x, to=y, duration=z}
- пауза в потоке, в плейлист вставлен тэгEXT-X-GAP
Любая из этих проблем означает ухудшение качества исходной публикации, которая проигрывается по HLS, и может приводить к фризам, рассинхронизации звука и видео и остановке проигрывания в некоторых браузерах. В таких случаях следует принять меры по снижению помех на канале публикации, либо изменить способ публикации, например, с WebRTC на RTMP или SRT как более помехоустойчивые.
Отображение статистики HLS потока
В сборке 5.2.1777 добавлена возможность получения статистики HLS потока при помощи REST API
Данные о потоке в целом
В ответ на запрос /hls/find_all
возвращается список всех HLS потоков на сервере с основной информацией о них:
Code Block | ||||
---|---|---|---|---|
| ||||
[{
"id": "test",
"streamName": "test",
"status": "ACTIVE",
"waitingSize": 0,
"profiles": [
"a_test",
"v_test"
],
"subscribers": 1,
"playlist": "#EXTM3U\n#EXT-X-VERSION:9\n#EXT-X-INDEPENDENT-SEGMENTS\n#EXT-X-MEDIA:TYPE=AUDIO,URI=\"a_test/a_test.m3u8\",GROUP-ID=\"audio\",NAME=\"none\",DEFAULT=YES,AUTOSELECT=YES,CHANNELS=\"2\"\n#EXT-X-STREAM-INF:BANDWIDTH=1761281,CODECS=\"avc1.640028,mp4a.40.2\",RESOLUTION=1280x720,FRAME-RATE=29.0,AUDIO=\"audio\"\nv_test/v_test.m3u8\n",
"createdDate": 1697605114475,
"logs": []
}] |
Здесь
- id - идентификатор HLS потока
- streamName - имя исходного потока, который нарезается на HLS сегменты
- waitingSize - количество HTTP запросов, ожидающих ответа
- profiles - список аудио и видео профилей
- subscribers - число HLS подписчиков
- playlist - содержимое HLS манифеста
- createdDate - дата создания в виде целого числа
- logs - список сообщений о проблемах с HLS потоком
При большом количестве потоков на сервере выдачу запроса можно ограничивать параметрами
Code Block | ||||
---|---|---|---|---|
| ||||
{
"offset":0,
"size":10
} |
Здесь
- offset - с какого элемента выводить список, по умолчанию 0
- size - максимальное количество выводимых элементов, по умолчанию 10
Данные об аудио и видео профилях нарезки
В ответ на запрос /hls/profiles
возвращается статистика аудио или видео профиля нарезки:
Code Block | ||||
---|---|---|---|---|
| ||||
{
"name": "v_test",
"stream": {
"appKey": "defaultApp",
"sessionId": "test-HLS",
"mediaSessionId": "81b8b278-612e-4b72-9153-454be9df0a34-test-HLS",
"name": "test",
"published": false,
"hasVideo": false,
"hasAudio": true,
"status": "PLAYING",
"sdp": "v=0\r\no=- 1988962254 1988962254 IN IP4 0.0.0.0\r\nc=IN IP4 0.0.0.0\r\nt=0 0\r\na=sdplang:en\r\nm=video 0 RTP/AVP 112\r\na=rtpmap:112 H264/90000\r\na=fmtp:112 packetization-mode=1; profile-level-id=42001f\r\na=recvonly\r\n",
"videoCodec": "H264",
"record": false,
"width": 1280,
"height": 720,
"bitrate": 0,
"minBitrate": 0,
"maxBitrate": 0,
"quality": 0,
"parentMediaSessionId": "f3401d2e-7e9a-4e18-a353-d323c947ac94",
"history": false,
"gop": 0,
"fps": 0,
"audioBitrate": 0,
"codecImpl": "",
"transport": "UDP",
"cvoExtension": true,
"createDate": 1697605114875,
"mediaType": "play",
"audioState": {
"muted": false
},
"videoState": {
"muted": false
},
"mediaProvider": "HLS"
},
"keyFrameReceived": true,
"videoProfile": {
"type": "video",
"width": 1280,
"height": 720,
"fps": 29,
"bitrate": 1720,
"codec": "",
"quality": 0,
"audioGroupId": "audio"
},
"metrics": {
"minFPS": 29.962547,
"avgFPS": 30.000088,
"maxFPS": 30.04292,
"countGaps": 0,
"resolutionChanges": 0,
"queueSize": 10,
"startPts": 375400,
"currentPts": 375400
},
"subscribers": 1
} |
Здесь:
- name - имя профиля
- stream - информация о потоке профиля, состав полей аналогичен ответу на запрос
/stream/find
- keyFrameReceived - получен ли хотя бы один ключевой кадр из исходного потока
- audioProfile, videoProfile - исходные данные аудио или видео профиля
- type - тип: видео или аудио
- width - заданная ширина картинки видео
- height - заданная высота картинки видео
- fps - частота кадров видео
- bitrate - заданный битрейт профиля
- codec - заданный кодек профиля
- quality - заданное качество видео профиля
- audioGroupId - идентификатор аудио профиля, заданный в видео профиле
- rate - частота дискретизации аудио профиля
- channels - количество каналов аудио профиля
- groupId - идентификатор аудио профиля для привязки видео
- metrics - текущие метрики профиля:
- minFPS - минимальный FPS
- avgFPS - средний FPS
- maxFPS - максимальный FPS
- countGaps - количество пауз, вставленных в поток
- resolutionChanges - изменения разрешения видео
- queueSize - размер очереди кадров потока
- startPts - стартовая метка времени MPEG
- currentPts - текущая метка времени MPEG
- subscribers - количество HLS подписчиков на данный профиль
Данные о подписчиках на HLS поток
В ответ на запрос /hls/subscribers
возвращается статистика подписчиков на HLS поток:
Code Block | ||||
---|---|---|---|---|
| ||||
[
{
"id": "192.168.0.83-59000-Mozilla/5.0 (X11; Linux x86_64) Chrome/118.0.0.0",
"ip": "192.168.0.83",
"port": 59000,
"userAgent": "Mozilla/5.0 (X11; Linux x86_64) Chrome/118.0.0.0",
"active": true,
"metrics": {
"profileTime": {
"test": 71,
"v_test": 541353
},
"requestsNumber": 5930,
"requestsStatuses": {
"200 OK": 5930
},
"profileSwitches": 1,
"maxResponseTime": 29,
"minResponseTime": 0,
"avgResponseTime": 0.4436762225969646
}
}
] |
Здесь:
- id - идентификатор подписчика
- ip - IP адрес подписчика
- port - исходящий порт подписчика
- userAgent - данные заголовка
User-Agent
, переданные подписчиком - active - подписчик активен
- metrics - текущие метрики подписчика:
- profileTime - время, в течение которого подписчик запрашивал данный профиль, указанное для каждого профиля
- requestsNumber - количество запросов от подписчика
- requestStatuses - количество статусов ответов на запросы подписчика, указанное для каждого запроса
- profileSwitches - число переходов подписчика с одного HLS ABR профиля на другой
- maxResponseTime - максимальное время ответа на запрос
- minResponseTime - минимальное время ответа на запрос
- avgResponseTime - среднее время ответа на запроc
Особенности отображения количества подписчиков и количества соединений HLS
В ответ на запросы /hls/find_all
, /hls/profiles
, /hls/subscribers
возвращаются текущие количество и состав HLS подписчиков с точностью до вкладки браузера. Однако количество сетевых соединений для загрузки HLS, которое отображается на странице статистики сервера
Code Block | ||||
---|---|---|---|---|
| ||||
curl -s http://localhost:8081/?action=stat¶ms=connections_hls |
может отличаться от количества подписчиков. В большинстве случаев, HLS подписчики используют HTTP 2 протокол, и все вкладки одного браузера, которые получают HLS потоки с одного WCS сервера, будут использовать одно соединение.
При этом количество соединений, отображаемое параметром connections_hls
, соответствует количеству установленных соединений на HLS порт, отображаемых командой netstat
:
Code Block | ||||
---|---|---|---|---|
| ||||
sudo netstat -np | grep ESTABLISHED | grep java | grep 8445 |
Здесь 8445 - HTTPS HLS порт WCS сервера
Поддержка HLS ABR
Для потоков с видео (только видео или видео+аудио) WCS поддерживает HLS ABR в CDN (в этом случае качества кодируются на выделенном Transcoder сервере) и на одном узле.
Warning |
---|
Для потоков только с аудио HLS ABR не работает, при попытке запросить HLS ABR манифест для такого потока сервер вернет |
Устаревшая реализация в сборках 5.2.484 - 5.2.582
В сборке 5.2.484 добавлена поддержка HLS ABR плейлистов. Использование этой возможности включается при помощи настройки
Code Block | ||
---|---|---|
| ||
hls_master_playlist_enabled=true |
Имя основного плейлиста указывается при помощи настройки
Code Block | ||
---|---|---|
| ||
hls_manifest_file=index.m3u8 |
Браузер должен запросить основной плейлист по URL
Code Block | ||
---|---|---|
| ||
https://wcs_address:8445/streamName/index.m3u8 |
Здесь
- wcs_address - адрес WCS сервера
- streamName - имя потока на сервере
- index.m3u8 - имя основного плейлиста
При запросе основного плейлиста сервер проверяет наличие потоков, транскодируемых из указанного потока согласно профилям транскодинга, перечисленным в файле настроек cdn_profiles.yml, например:
Code Block | ||
---|---|---|
| ||
profiles:
-720p:
video:
height: 720
bitrate: 1000
codec: h264
-480p:
video:
height: 480
bitrate: 1000
codec: h264
-240p:
video:
height: 240
bitrate: 400
codec: h264 |
Все транскодированные потоки по профилям, которые в момент запроса опубликованы на сервере, попадают в основной плейлист, например:
Code Block | ||
---|---|---|
| ||
#EXTM3U
#EXT-X-STREAM-INF:BANDWIDTH=1000000,RESOLUTION=1280x720,CODECS="avc1.42e01f,mp4a.40.2"
../streamName-720p/streamName-720p.m3u8
#EXT-X-STREAM-INF:BANDWIDTH=1000000,RESOLUTION=852x480,CODECS="avc1.42e01f,mp4a.40.2"
../streamName-480p/streamName-480p.m3u8
#EXT-X-STREAM-INF:BANDWIDTH=400000,RESOLUTION=426x240,CODECS="avc1.42e01f,mp4a.40.2"
../streamName-240p/streamName-240p.m3u8
#EXT-X-STREAM-INF:BANDWIDTH=2500000,RESOLUTION=1280x720,CODECS="avc1.42e01f,mp4a.40.2"
../streamName/streamName.m3u8 |
Затем браузер, в зависимости от пропускной способности канала, переключается между потоками, перечисленными в основном плейлисте.
Warning |
---|
В момент, когда браузер запрашивает основной плейлист, потоки уже должны быть опубликованы на сервере и нарезаться на HLS сегменты |
Чтобы обеспечить наличие потоков, необходимо:
1. На отдельно стоящем сервере:
1.1. Периодически проверять, транскодируются ли потоки к указанным параметрам, и запускать транскодинг при необходимости при помощи REST API
Code Block | ||||
---|---|---|---|---|
| ||||
curl -s -X POST -d "{\"uri\":\"transcoder://tcode_test-240p\",\"remoteStreamName\":\"test\",\"localStreamName\":\"test-240p\",\"encoder\":{\"width\":320,\"height\":240}}" http://localhost:8081/rest-api/transcoder/startup
curl -s -X POST -d "{\"uri\":\"transcoder://tcode_test-480p\",\"remoteStreamName\":\"test\",\"localStreamName\":\"test-480p\",\"encoder\":{\"width\":640,\"height\":480}}" http://localhost:8081/rest-api/transcoder/startup
curl -s -X POST -d "{\"uri\":\"transcoder://tcode_test-720p\",\"remoteStreamName\":\"test\",\"localStreamName\":\"test-720p\",\"encoder\":{\"width\":1280,\"height\":720}}" http://localhost:8081/rest-api/transcoder/startup |
1.2. Периодически запускать HLS потоки для включения в основной плейлист, например
Code Block | ||||
---|---|---|---|---|
| ||||
curl -s -X POST -d "{\"name\":\"test\"}" http://localhost:8081/rest-api/hls/startup
sleep 1
curl -s -X POST -d "{\"name\":\"test-240p\"}" http://localhost:8081/rest-api/hls/startup
sleep 1
curl -s -X POST -d "{\"name\":\"test-480p\"}" http://localhost:8081/rest-api/hls/startup
sleep 1
curl -s -X POST -d "{\"name\":\"test-720p\"}" http://localhost:8081/rest-api/hls/startup |
2. На Edge сервере в CDN периодически запрашивать HLS потоки по профилям, например
Code Block | ||||
---|---|---|---|---|
| ||||
curl -s http://localhost:8082/test/test.m3u8
sleep 1
curl -s http://localhost:8082/test-240p/test-240p.m3u8
sleep 1
curl -s http://localhost:8082/test-480p/test-480p.m3u8
sleep 1
curl -s http://localhost:8082/test-720p/test-720p.m3u8
sleep 1 |
Актуальная реализация в сборках 5.2.585 и новее
В сборке 5.2.585 реализация HLS ABR существенно изменена. Как и прежде, HLS ABR может использоваться только в CDN, при этом все транскодированные потоки для вариантов в ABR манифесте Edge забирает одновременно в пределах одной медиасессии, чтобы варианты одного потока были синхронизированы друг с другом. Это требует совместной настройки Transcoder и Edge узлов и накладывает ряд ограничений. Рассмотрим их ниже.
Настройки Transcoder узлов
Для того, чтобы все варианты одного потока были синхронизированы между собой, на Transcoder узлах должно быть включено выравнивание кодирования
Code Block | ||
---|---|---|
| ||
transcoder_align_encoders=true |
Кроме того, должен быть включен FPS фильтр
Code Block | ||
---|---|---|
| ||
video_filter_enable_fps=true
video_filter_fps=25 |
Ключевые фреймы в вариантах потока должны быть синхронизированы. Например, при 25 кадрах в секунду будем отправлять ключевой фрейм каждые 2 секунды
Code Block | ||
---|---|---|
| ||
video_filter_fps_gop_synchronization=50 |
Настройки HLS Edge узлов
На HLS Edge узлах необходимо отключить использование прелоадера и транскодирование потоков
Code Block | ||
---|---|---|
| ||
hls_preloader_enabled=false
hls_player_width=0
hls_player_height=0 |
Необходимо также настроить профили транскодирования в файле cdn_profiles.yml
Code Block | ||||
---|---|---|---|---|
| ||||
profiles:
-240p:
audio:
codec : mpeg4-generic
rate : 48000
video:
height : 240
bitrate : 300
gop : 50
codec : h264
-480p:
video:
height : 480
bitrate : 600
gop : 50
codec : h264
-720p:
video:
height : 720
bitrate : 1000
gop : 50
codec : h264 |
Обратите внимание, что параметры звука можно указать для первого профиля, т.к. для всех профилей эти параметры должны быть идентичными и будут применены по первому из профилей.
Затем необходимо включить HLS ABR
Code Block | ||
---|---|---|
| ||
hls_abr_enabled=true |
Использование
Клиент должен запрашивать плейлист HLS ABR, указывая имя потока с суффиксом
Code Block | ||
---|---|---|
| ||
https://server:8445/test_0-HLS-ABR-STREAM/test_0-HLS-ABR-STREAM.m3u8 |
Суффикс задается при помощи настройки
Code Block | ||
---|---|---|
| ||
hls_abr_stream_name_suffix=-HLS-ABR-STREAM |
Плейлист содержит ссылки на плейлисты вариантов потока, между которыми клиент может переключаться
Code Block | ||
---|---|---|
| ||
#EXTM3U
#EXT-X-STREAM-INF:BANDWIDTH=614400,RESOLUTION=852x480,CODECS="avc1.42e01f,mp4a.40.2"
-480p/-480p.m3u8
#EXT-X-STREAM-INF:BANDWIDTH=1024000,RESOLUTION=1278x720,CODECS="avc1.42e01f,mp4a.40.2"
-720p/-720p.m3u8
#EXT-X-STREAM-INF:BANDWIDTH=307200,RESOLUTION=426x240,CODECS="avc1.42e01f,mp4a.40.2"
-240p/-240p.m3u8 |
Если запросить поток без суффикса, будет играть HLS без поддержки ABR.
Предотвращение транскодирования к более высоким разрешениям
Если транскодирование к более высоким разрешениями отключено на HLS ABR Edge сервере
Code Block | ||
---|---|---|
| ||
cdn_strict_transcoding_boundaries=true |
то варианты, соответствующие профилям с более высокими разрешениями, для данного потока не будут нарезаться и не будут доступны плееру.
Ограничения
1. HLS Edge может быть использован только для воспроизведения HLS потоков, клиентские сессии с использованием других протоколов работать не будут.
2. Не работают такие функции, как запись, снятие снапшотов, микширование, захват потоков с другого сервера и прочие функции обработки потоков
HLS ABR на одном узле
В большинстве случаев, для проигрывания HLS ABR целесообразно использовать CDN, поскольку такое решение лучше масштабируется по вычислительной мощности. Однако, начиная со сборки 5.2.1582, поддерживается и транскодирование с нарезкой плейлистов по заданным качествам HLS ABR на одном узле
Code Block | ||
---|---|---|
| ||
hls_abr_enabled=true
hls_abr_with_cdn=false |
В этом случае необходимо отключить прелоадер и транскодирование к определенному разрешению, поскольку поток будет транскодироваться по заданным профилям
Code Block | ||
---|---|---|
| ||
hls_preloader_enabled=false
hls_player_width=0
hls_player_height=0 |
Также необходимо включить выравнивание FPS при транскодинге
Code Block | ||
---|---|---|
| ||
transcoder_align_encoders=true
video_filter_enable_fps=true
video_filter_fps=30
video_filter_fps_gop_synchronization=60 |
Профили транскодинга настраиваются в файле /usr/local/FlashphonerWebCallServer/conf/hls_abr_profiles.yml
Code Block | ||||
---|---|---|---|---|
| ||||
profiles:
-180p:
audio:
codec : mpeg4-generic
rate : 48000
video:
height : 180
bitrate : 300
codec : h264
codecImpl : OPENH264
gop : 60
fps : 30
-240p:
audio:
codec : mpeg4-generic
rate : 48000
video:
height : 240
bitrate : 500
codec : h264
codecImpl : OPENH264
gop : 60
fps : 30
-480p:
audio:
codec : mpeg4-generic
rate : 48000
video:
height : 480
bitrate : 1000
codec : h264
codecImpl : OPENH264
gop : 60
fps : 30
-720p:
audio:
codec : mpeg4-generic
rate : 48000
video:
height : 720
bitrate : 1500
codec : h264
codecImpl : OPENH264
gop : 60
fps : 30 |
Для HLS ABR поддерживается и Low Latency HLS
Code Block | ||
---|---|---|
| ||
hls_ll_enabled=true
hls_new_http_stack=true |
Warning |
---|
При использовании HLS ABR на одном сервере, на этом сервере будет работать транскодинг к нескольким качествам для каждого опубликованного потока. Это потребует большого количества ядер CPU и оперативной памяти. |
Предотвращение транскодирования к более высоким разрешениям
Начиная со сборки 5.2.1611, если поток, опубликованный на сервере, имеет разрешение по высоте меньшее, чем какой-то из вариантов, перечисленных в hls_abr_profiles.yml
, то все варианты с большими разрешениями не будут кодироваться и не попадут в манифест, например, при публикации 960x540 манифест будет таким:
Code Block | ||
---|---|---|
| ||
#EXTM3U
#EXT-X-STREAM-INF:BANDWIDTH=300000,RESOLUTION=320x180,CODECS="avc1.42e01f,mp4a.40.2"
180/180.m3u8
#EXT-X-STREAM-INF:BANDWIDTH=500000,RESOLUTION=428x240,CODECS="avc1.42e01f,mp4a.40.2"
240/240.m3u8
#EXT-X-STREAM-INF:BANDWIDTH=1000000,RESOLUTION=848x480,CODECS="avc1.42e01f,mp4a.40.2"
480/480.m3u8 |
поскольку транскодирования вверх до 1280x720 не будет.
Если разрешение потока, опубликованного на сервере, ниже минимального профиля, такой поток будет транскодирован к минимальному профилю, и в плейлисте будет только этот профиль
Code Block | ||
---|---|---|
| ||
#EXTM3U
#EXT-X-STREAM-INF:BANDWIDTH=300000,RESOLUTION=320x180,CODECS="avc1.42e01f,mp4a.40.2"
180/180.m3u8 |
Если в списке профилей есть такой, для которого не указаны ни высота, ни ширина, по этому профилю поток будет транскодироваться с оригинальным разрешением и заданными FPS и GOP, и этот вариант будет всегда включаться в плейлист:
Code Block | ||
---|---|---|
| ||
profiles:
original:
video:
codec : h264
codecImpl : OPENH264
gop : 60
fps : 30 |
Очередность качеств в манифесте HLS ABR потока
До сборки 5.2.1606, качества в манифесте HLS ABR потока сортировались в алфавитном порядке именования профилей, например, при таком cdn_profiles.yml
или hls_abr_profiles.yml
Code Block | ||||
---|---|---|---|---|
| ||||
profiles:
360:
video:
height : 360
bitrate : 1000
codec : h264
codecImpl : OPENH264
gop : 60
fps : 30
720:
video:
height : 720
bitrate : 2000
codec : h264
codecImpl : OPENH264
gop : 60
fps : 30
1080:
video:
height : 1080
bitrate : 2500
codec : h264
codecImpl : OPENH264
gop : 60
fps : 30 |
манифест будет таким
Code Block | ||
---|---|---|
| ||
#EXTM3U
#EXT-X-STREAM-INF:BANDWIDTH=2500000,RESOLUTION=1920x1080,CODECS="avc1.42e01f,mp4a.40.2"
1080/1080.m3u8
#EXT-X-STREAM-INF:BANDWIDTH=1000000,RESOLUTION=640x360,CODECS="avc1.42e01f,mp4a.40.2"
360/360.m3u8
#EXT-X-STREAM-INF:BANDWIDTH=2000000,RESOLUTION=1280x720,CODECS="avc1.42e01f,mp4a.40.2"
720/720.m3u8 |
Начиная со сборки 5.2.1606, порядок следования качеств в манифесте соответствует порядку перечисления профилей в cdn_profiles.yml
или hls_abr_profiles.yml
Code Block | ||
---|---|---|
| ||
#EXTM3U
#EXT-X-STREAM-INF:BANDWIDTH=1000000,RESOLUTION=640x360,CODECS="avc1.42e01f,mp4a.40.2"
360/360.m3u8
#EXT-X-STREAM-INF:BANDWIDTH=2000000,RESOLUTION=1280x720,CODECS="avc1.42e01f,mp4a.40.2"
720/720.m3u8
#EXT-X-STREAM-INF:BANDWIDTH=2500000,RESOLUTION=1920x1080,CODECS="avc1.42e01f,mp4a.40.2"
1080/1080.m3u8 |
При этом, если в настройке встречаются два профиля с одинаковыми названиями, сервер будет использовать только последний из профилей с одинаковыми именами.
Транскодирование максимального качества только при наличии B-фреймов в исходном потоке
Для того, чтобы снизить нагрузку на сервер при кодировании видео, в сборке 5.2.1840 добавлена возможность транскодировать максимальное ABR качество (которое обычно соответствует оригинальному разрешению потока) только при наличии B-фреймов в потоке. Эта возможность включается настройкой
Code Block | ||
---|---|---|
| ||
h264_b_frames_force_transcoding=true |
При этом сервер проверяет наличие B-фреймов в исходном потоке, анализируя заданное количество фреймов (по умолчанию 10)
Code Block | ||
---|---|---|
| ||
frame_cnt_to_determine_their_type=10 |
Если в потоке есть B-фреймы, максимальное ABR качество будет транскодироваться, и будет доступно плееру в HLS манифесте
Code Block | ||
---|---|---|
| ||
#EXTM3U
#EXT-X-STREAM-INF:BANDWIDTH=1000000,RESOLUTION=640x360,CODECS="avc1.42e01f,mp4a.40.2"
360/360.m3u8
#EXT-X-STREAM-INF:BANDWIDTH=2000000,RESOLUTION=1280x720,CODECS="avc1.42e01f,mp4a.40.2"
720/720.m3u8
#EXT-X-STREAM-INF:BANDWIDTH=2500000,RESOLUTION=1920x1080,CODECS="avc1.42e01f,mp4a.40.2"
1080/1080.m3u8 |
Если в потоке нет B-фреймов, максимальное ABR качество не будет транскодироваться
Code Block | ||
---|---|---|
| ||
#EXTM3U
#EXT-X-STREAM-INF:BANDWIDTH=1000000,RESOLUTION=640x360,CODECS="avc1.42e01f,mp4a.40.2"
360/360.m3u8
#EXT-X-STREAM-INF:BANDWIDTH=2000000,RESOLUTION=1280x720,CODECS="avc1.42e01f,mp4a.40.2"
720/720.m3u8 |
В этом случае оригинальное качество необходимо запросить отдельно с клиента.
Начиная со сборки 5.2.1916, эта возможность доступна и для HLS ABR в CDN. Для этого все серверы в CDN должны быть обновлены до сборки 5.2.1916 или новее, и на Edge сервере указаны следующие настройки
Code Block | ||
---|---|---|
| ||
cdn_strict_transcoding_boundaries=true
h264_b_frames_force_transcoding=true |
Максимальный размер плейлиста
Максимальный размер плейлиста в сегментах задается настройкой
Code Block | ||
---|---|---|
| ||
hls_list_size=8 |
По умолчанию размер HLS плейлиста равен 8 сегментам. Отметим, что, когда нарезка HLS только стартовала, количество сегментов в первых плейлистах будет меньше заданного.
Хранение сегментов HLS
Использование диска
В сборках до 5.2.1713 HLS-сегменты по умолчанию записываются на диск сервера, в каталог /usr/local/FlashphonerWebCallServer/hls
. Начиная со сборки 5.2.687, каталог для сохранения сегментов можно изменить при помощи параметра
Code Block | ||
---|---|---|
| ||
hls_dir=/usr/local/FlashphonerWebCallServer/hls |
(Расположение прелоадера настраивается отдельно при помощи параметра hls_preloader_dir
.)
На диске хранится количество сегментов, соответствующее заданному размеру плейлиста. Чем меньше количество сегментов в плейлисте, тем меньше задержка при воспроизведении. Однако при коротком плейлисте подписчики с недостаточной пропускной способностью каналов могут запрашивать сегменты, которых уже нет в плейлисте и на диске. В связи с этим, в сборке 5.2.581 добавлена возможность хранить некоторое число сегментов на диске после их ухода из плейлиста. Эта возможность включается настройкой
Code Block | ||
---|---|---|
| ||
hls_hold_segments_before_delete=true |
По умолчанию, будет храниться 5 последних сегментов
Code Block | ||
---|---|---|
| ||
hls_hold_segments_size=5 |
Например, если плейлист содержит 3 сегмента
Code Block | ||
---|---|---|
| ||
#EXTM3U
#EXT-X-VERSION:8
#EXT-X-TARGETDURATION:11
#EXT-X-MEDIA-SEQUENCE:15
#EXT-X-DISCONTINUITY-SEQUENCE:1
#EXTINF:3.415,
test_017.ts
#EXTINF:10.417,
test_018.ts
#EXTINF:9.084,
test_019.ts |
на диске будут храниться 3 текущих сегмента из плейлиста и 5 предшествующих
Code Block | ||
---|---|---|
| ||
test_012.ts
test_013.ts
test_014.ts
test_015.ts
test_016.ts
test_017.ts
test_018.ts
test_019.ts |
Использование оперативной памяти
При больших нагрузках на сервер, например, если он выделен для раздачи потоков по HLS, чтение сегментов с диска для отправки подписчикам может давать задержки. В этом случае необходимо включить хранение HLS сегментов в памяти
Code Block | ||
---|---|---|
| ||
hls_store_segment_in_memory=true |
Для отправки подписчикам сегменты будут считываться из памяти. Необходимо отметить, что в этом случае потребуется больше памяти под Java heap для хранения сегментов.
В сборке 5.2.1713 хранение сегментов в оперативной памяти включено по умолчанию.
Отладочные логи для HLS-сессии
Для отчета об ошибке можно, используя CLI, включить сбор отладочных логов для HLS-сессий
Code Block | ||||
---|---|---|---|---|
| ||||
update node-setting --value true hls_enable_session_debug |
Следует учесть, что файл настроек flashphoner.properties будет перезаписан после этой команды.
Поддержка Low Latency HLS
Начиная со сборки 5.2.1181, поддерживается Low Latency HLS (LL HLS). Эта возможность включается при помощи настройки
Code Block | ||
---|---|---|
| ||
hls_ll_enabled=true
hls_new_http_stack=true |
В этом случае плееры, которые поддерживают LL HLS (например, HLS.JS), будут играть дополнительные HLS сегменты и давать меньшую задержку по сравнению с плеерами, которые их не играют (например, VideoJS).
Для того, чтобы LL HLS проигрывался корректно, необходимо, как и для обычного HLS, обеспечить стабильный FPS публикуемого потока и стабильный интервал между ключевыми кадрами. Таким образом, исходный поток рекомендуется публиковать как RTMP с параметрами
Рекомендованные настройки сервера для LL HLS
Начиная со сборки 5.2.1345, рекомендуются следующие настройки для проигрывания Low latency HLS:
Code Block | ||
---|---|---|
| ||
hls_ll_enabled=true
hls_auto_start=true
hls_preloader_enabled=false
hls_player_width=848
hls_player_height=480
video_filter_enable_fps=true
video_filter_fps=30
video_encoder_h264_gop=60 |
Использование HTTP/2 и HTTP/1
Согласно спецификации, LL HLS должен воспроизводиться с использованием HTTP/2, то есть через безопасное соединение
Code Block | ||
---|---|---|
| ||
https://wsc:8445/test/test.m3u8 |
В WCS также возможно использование HTTP/1 через небезопасное соединение
Code Block | ||
---|---|---|
| ||
http://wsc:8082/test/test.m3u8 |
Отметим, что LL HLS через HTTP/1 работает во всех основных браузерах, кроме Safari, поэтому не рекомендуется использовать эту возможность в промышленной эксплуатации.
Каталог для нарезки сегментов LL HLS
По умолчанию, сегменты LL HLS помещаются в подкаталоги с именами потоков в каталог
Code Block | ||
---|---|---|
| ||
ll_hls_dir=/usr/local/FlashphonerWebCallServer/ll-hls |
При изменении местоположения, например
Code Block | ||
---|---|---|
| ||
ll_hls_dir=/opt/ll-hls |
необходимо назначить права доступа командой
Code Block | ||||
---|---|---|---|---|
| ||||
/usr/local/FlashphonerWebCallServer/bin/webcallserver set-permissions |
и перезапустить WCS, чтобы применить изменения.
Максимальный размер LL HLS плейлиста
Максимальный размер LL HLS плейлиста в сегментах задается настройкой
Code Block | ||
---|---|---|
| ||
ll_hls_list_size=12 |
По умолчанию размер LL HLS плейлиста равен 12 полным сегментам. Отметим, что, когда нарезка HLS только стартовала, количество полных сегментов в первых плейлистах будет меньше заданного.
Прелоадер для LL HLS
Начиная со сборки 5.2.1729, для LL HLS, как и для обычного HLS, может использоваться прелоадер
Code Block | ||
---|---|---|
| ||
hls_preloader_enabled=true |
Файлы прелоадера LL HLS по умолчанию помещаются в каталог
Code Block | ||
---|---|---|
| ||
ll_hls_preloader_dir=/usr/local/FlashphonerWebCallServer/ll-hls/.preloader |
Расположение может быть изменено, например
Code Block | ||
---|---|---|
| ||
ll_hls_preloader_dir=/opt/preloader |
По умолчанию, LL HLS прелоадер состоит из следующих файлов, по одному на каждое соотношение сторон видео потоков
Code Block | ||
---|---|---|
| ||
16x9.mp4
2x1.mp4
4x3.mp4 |
Если соотношение сторон публикуемого потока неизвестно, используется прелоадер с соотношением 16:9. Если файлы прелоадера отстутствуют, нарезка LL HLS будет начинаться без прелоадера, аналогично настройке
Code Block | ||
---|---|---|
| ||
hls_preloader_enabled=false |
Настройка собственного прелоадера
При необходимости, для LL HLS может быть настроен собственный прелоадер. Для этого необходимо подготовить файлы в трех основных аспектах 16:9, 4:3 и 2:1 согласно следующим требованиям:
- контейнер MP4, кодек видео H264, кодек аудио AAC
- файлы должны позволять немедленное проигрывание (MP4 атом
moov
должен быть перед атомомmdat
) - файлы не должны содержать B-фреймов
- длительность файла должна быть около 1 минуты
- файл должен иметь ровный FPS
- интервал между ключевыми кадрами должен быть около 2 секунд
Предполагается, что исходные файлы уже записаны в нужном аспекте, например, при помощи OBS Studio или подготовлены в видеоредакторе. Пример команды для преобразования файла под указанные требования:
Code Block | ||||
---|---|---|---|---|
| ||||
ffmpeg -i 16x9-source.mp4 -bf 0 -acodec aac -vcodec h264 -preset ultrafast -g 60 -strict -2 -r 30 -ar 48000 -movflags faststart -ss 00:00:00 -t 00:01:00 16x9.mp4 |
Затем подготовленными файлами необходимо заменить файлы прелоадера по умолчанию и перезапустить WCS.
Для восстановления прелоадера по умолчанию достаточно удалить файлы собственного прелоадера и перезапустить WCS.
Поддержка m4s контейнера
В сборке 5.2.1626 добавлена поддержка m4s контейнера для нарезки HLS сегментов, а в сборке 5.2.1632 поддержка данного контейнера включена и для HLS ABR
Code Block | ||
---|---|---|
| ||
ll_hls_fragmented_mp4=true |
Начиная со сборки 5.2.1724, контейнер m4s поддерживается и для HLS ABR в CDN.
При необходимости, можно переключиться на использование ts контейнера
Code Block | ||
---|---|---|
| ||
ll_hls_fragmented_mp4=false |
Использование общего сетевого стека для обычного и Low Latency HLS
В сборке 5.2.1749 добавлена настройка, разрешающая использование унифицированного сетевого стека для обычного HLS и Low latency HLS. Эта настройка включена по умолчанию:
Code Block | ||
---|---|---|
| ||
use_new_hls=true |
При этом:
- по умолчанию используется контейнер m4s для записи сегментов
- настройки с префиксом
hls
применяются и к обычному HLS, и к LL HLS - настройки с префиксом
ll_hls
применяются к LL HLS и к контейнеру m4s
Warning |
---|
Начиная со сборки 5.2.1793, данная настройка удалена. Для доставки HLS и LL HLS сегментов используется унифицированный сетевой стек. |
Настройка URL манифеста
Начиная со сборки 5.2.1852, можно задать шаблоны URL, по которому должен запрашиваться основной плейлист (манифест) потока. По умолчанию используются следующие шаблоны:
Code Block | ||
---|---|---|
| ||
hls_path_template={streamName}/{streamName}.m3u8
hls_abr_path_template={streamName}{abrSuffix}/{streamName}{abrSuffix}.m3u8 |
Здесь:
- streamName - имя потока, опубликованного на сервере
- abrSuffix - суффикс для ABR потока, заданный настройкой
hls_abr_stream_name_suffix
В этом случае для получения манифеста HLS потока используется URL
Code Block | ||
---|---|---|
| ||
https://wcs:8445/stream/stream.m3u8 |
а для HLS ABR потока
Code Block | ||
---|---|---|
| ||
https://wcs:8445/stream-HLS-ABR-STREAM/stream-HLS-ABR-STREAM.m3u8 |
Если необходимо, например, задать фиксированное имя манифеста и при этом различать ABR и не ABR потоки, можно задать следующие шаблоны
Code Block | ||
---|---|---|
| ||
hls_path_template={streamName}/playlist.m3u8
hls_abr_path_template={streamName}/playlist{abrSuffix}.m3u8 |
В этом случае для получения манифеста HLS потока будет использоваться URL
Code Block | ||
---|---|---|
| ||
https://wcs:8445/stream/playlist.m3u8 |
а для HLS ABR потока
Code Block | ||
---|---|---|
| ||
https://wcs:8445/stream/playlist-HLS-ABR-STREAM.m3u8 |
Известные проблемы
1. Невосстанавливаемый фриз HLS потока при воспроизведении в iOS Safari через CDN
Симптомы: через одну минуту после начала публикации изображение останавливается, звук продолжает воспроизводиться
Решение:
а) включить транскодинг на сервере при помощи настройки в файле flashphoner.properties
Code Block | ||||
---|---|---|---|---|
| ||||
disable_streaming_proxy=true |
б) если включение транскодинга нежелательно, установить в файле flashphoner.properties
Code Block | ||||
---|---|---|---|---|
| ||||
hls_discontinuity_enabled=true |
в этом случае возможны щелчки в аудиопотоке, но изображение останавливаться не будет.
2. Прекращение записи сегментов HLS при воспроизведении потока. опубликованного в браузере Firefox
Симптомы: через несколько минут после начала воспроизведения прекращается запись HLS-сегментов, при этом директория потока в директории hls не удаляется, в логе сервера продолжают появляться сообщения
Code Block | ||||
---|---|---|---|---|
| ||||
INFO HLSStreamManager - HLSStreamProviderKeepaliveThread-80 Remove hls channel |
Для восстановления публикующая сторона должна заново опубликовать поток.
Решение: использовать другой браузер для публикации потока, который предполагается воспроизводить по HLS.
3. При воспроизведении HLS в Safari в iOS 12.4 не играет видео для первого подписчика
Симптомы: при подключении первого подписчика к потоку по HLS в Safari в iOS 12.4 видео не воспроизводится, если HLS-подписчики уже есть, видео играет нормально
Решение: установить минимальное количество сегментов в плейлисте HLS не менее 2
Code Block | ||
---|---|---|
| ||
hls_min_list_size=2 |
4. При воспроизведении RTMP-потока как HLS в Safari в iOS 12.4 не играет видео для любого подписчика, если активна настройка
Code Block | ||
---|---|---|
| ||
hls_auto_start=true |
Симптомы: при подключении подписчиков к RTMP потоку по HLS в Safari в iOS 12.4 видео не воспроизводится
Решение: при публикации файла со звуковой дорожкой стерео, использовать моно звук, например, для ffmpeg указать настройку
Code Block | ||
---|---|---|
| ||
-acodec aac -ac 1 |
5. Если по HLS проигрывается поток, транскодированный в CDN, и если при этом изменяется соотношение сторон потока, HLS прелоадер отображается в соответствии с соотношением сторон оригинального потока
Симптомы: при заказе транскодированного потока с указанием профиля в имени, например test-640x480p, отображается прелоадер 16:9, если исходный поток опубликован в разрешении 1280x720
Решение: включить на транскодере сохранение соотношения сторон
Code Block | ||
---|---|---|
| ||
video_transcoder_preserve_aspect_ratio=true |
6. Если в исходном потоке содержатся B-фреймы, в некоторых плеерах могут наблюдаться подергивания
Симптомы: сильно дергается картинка при проигрывании HLS, возможен эффект низкого FPS
Решение: обновить WCS до сборки 5.2.863, в которой решена данная проблема
7. При проигрывании LL HLS в браузере Safari, при первом подключении к потоку может пропадать звук
Симптомы: поток играет по LL HLS, но нет звука
Решение: обновить WCS до сборки 5.2.1345 или новее, где эта проблема решена
8. Браузер Chrome на Ubuntu 22.04 может давать ошибку CORS при загрузке плейлистов по HTTPS
Симптомы: браузер Chrome на Ubuntu 22.04 играет HLS по HTTPS нормально, затем выдает ошибку CORS при загрузке очередного плейлиста
Решение: не отправлять из браузера Chrome HTTP запросы на тот же сайт, с которого проигрывается HLS по HTTPS
9. При проигрывании LL HLS ABR в iOS Safari 16 подписчики могут играть поток с большой задержкой.
Симптомы: подписчики, использующие iOS Safari 16, играют с большой задержкой (20 и более секунд) относительно публикации
Решение: обновить WCS до сборки 5.2.1677, чтобы использовать контейнер m4s по умолчанию для LL HLS, и ожидать возможного исправления в iOS Safari 17
10. HLS ABR не играет при использовании контейнера m4s
Симптомы: нарезка HLS ABR не стартует, в серверном логе сообщение
Code Block | ||
---|---|---|
| ||
02:18:01,957 ERROR HlsAbrStreamProvider - HLS-HTTPS-pool-5-thread-1 Failed to check stream null
java.lang.NullPointerException |
Решение: обновить WCS до сборки 5.2.1677, где эта проблема решена
11. VLC требует, чтобы LL HLS манифест включал как минимум 4-6 сегментов при подключении первого подписчика
Симптомы: VLC играет LL HLS в контейнере m4s с рассинхронизацией звука и видео, либо дает фризы при переключении качества для LL HLS ABR
Решение: обновить WCS до сборки 5.2.1677 и увеличить минимальный размер манифеста
Code Block | ||
---|---|---|
| ||
hls_min_list_size=6 |
12. HLS поток только с аудио в контейнере ts проигрывается с заметными щелчками в браузере Safari
Симптомы: HLS поток только с аудио щелкает при проигрывании с использованием native HTML5 плеера в браузере Safari
Решение: начиная со сборки 5.2.1690, использовать контейнер m4s для потоков только с аудио
13. При использовании HLS ABR под нагрузкой может возникать утечка ресурсов кодирования
Симптомы: при использовании HLS ABR, при большой нагрузке на CPU сервера (например, общее число профилей кодирования для всех опубликованных потоков превышает возможности CPU), после остановки публикаций ресурсы кодирования могут не освобождаться, это видно в статистике, например
Code Block | ||
---|---|---|
| ||
streams_hls=0
...
native_resources.video_encoders=5 |
Решение: обновить WCS до сборки 5.2.1947 и установить следующий параметр
Code Block | ||
---|---|---|
| ||
handler_async_disconnect=false |