SRT¶
SRT (Secure Reliable Transport) — это протокол передачи видео, похожий на RTP и основанный на UDP, который инкапсулирует MPEG-TS и добавляет к нему механизм повторной передачи.
Основные характеристики SRT:
- Протокол основан на UDP.
- Компенсация потери пакетов осуществляется за счет повторной передачи с фиксированной задержкой, но возможно использование FEC (Forward Error Correction).
- Опциональное шифрование с фиксированным секретом (
passphrase
), известным обеим сторонам. Современные безопасные технологии вроде DTLS не используются. - Не поддерживается проверка сертификатов TLS.
- Нет сигнализации метаданных: обычно для различения потоков используются порты.
- Нет перенаправлений, повторных попыток подключения и других функций, необходимых для создания системы крупного масштаба.
- Нулевая совместимость с существующей инфраструктурой HTTP: все балансировщики должны быть реализованы заново.
По сравнению с протоколами, основанными на TCP, он решает только проблему блокировки очереди и обеспечивает стабильную задержку.
Протокол SRT произошёл от UDT — протокола для доставки файлов через Torrent, но особенности трансляции в реальном времени подразумевают, что вам не нужно задумываться о механизмах управления перегрузками: у вас почти постоянный битрейт трафика и нужно отправлять все данные. Не быстрее, не медленнее, просто стараться отправить каждый кадр.
Реализация SRT в Flussonic¶
SRT не имеет надежного механизма для определения:
- имени потока, который будет передан по данному соединению,
- того, хочет ли клиент проигрывать или публиковать видео.
Поэтому Flussonic поддерживает несколько способов настройки порта для SRT:
- Один порт для одного потока (рекомендуется) или мультиплексированный порт для множества потоков.
- Порт только для воспроизведения/публикации или "однонаправленный" порт, при использовании которого клиент сам должен указать режим.
Протокол SRT предлагает отправку от клиента к серверу только одной строки, которая может быть прочитана и интерпретирована на сервере. Эта строка будет прочитана только если совпадает passphrase
, поэтому предполагается, что вы не можете иметь разные passphrase
для разных потоков (если не считать костылей вроде угадывания одной из нескольких подходящих passphrase
). Только одна правильная passphrase
на порт.
По каким-то причинам SRT использует собственный стандарт для кодирования этой строки, и это не стандартное кодирование URL, как в других протоколах, а конструкция вида #!::r=my-stream,m=publish
. То есть в начале идут символы #!::
, а затем стандартные KEY=VALUE,KEY=VALUE
.
У некоторых параметров есть определенные значения, описанные ниже.
Warning
Некоторые клиенты до сих пор не поддерживают передачу строки streamid
, поэтому нельзя рассчитывать на наличие имени потока и режима. Мы рекомендуем использовать отдельные порты с указанным режимом.
Совместимость SRT с облаком¶
Отсутствие перенаправлений, балансировки и современных средств шифрования в SRT становится проблемой, когда у вас есть кластер из нескольких десятков серверов, принимающих публикации от клиентов.
Вы не можете дать клиенту один IP-адрес, потому что этот сервер может быть выключен по любой причине. Поэтому вы предоставляете имя хоста, за которым стоит пул серверов. При этом помните, что на всех этих серверах должен быть зарезервирован один и тот же порт для этого клиента.
Учитывая проблему с отсутствием стандартного способа сигнализации о том, хочет ли клиент публиковать или проигрывать, а также проблемы с passphrase
, мы разработали систему балансировки, основанную на портах, вместо имен потоков.
Когда клиент подключается к порту SRT, Flussonic может сделать HTTP-запрос на конфигурационный бэкенд, сообщая IP-адрес сервера и порт сервера. Бэкенд знает, что это должен быть клиент N с потоком S и сообщит все детали конфигурации порта в ответе. Таким образом, порт SRT будет настроен динамически при первом запросе. Подробнее см. в схеме.
Режимы SRT¶
Протокол SRT имеет несколько режимов работы: Caller (Инициатор), Listener (Слушатель) и Rendezvous. Flussonic поддерживает следующие режимы SRT:
- Прием публикации по SRT. Flussonic выступает в роли Listener, т.к. ожидает получения потока от Инициатора (Caller).
- Захват SRT. Flussonic выступает в роли Caller, т.к. сам инициирует соединение, запрашивая поток из источника.
- Отправка SRT (push). Flussonic выступает в роли Caller, т.к. сам является источником потока и отправляет поток на другой сервер.
- Проигрывание SRT. Flussonic выступает в роли Listener, т.к. ожидает запроса потока от Инициатора (Caller).
Режим задается в URL потока с помощью streamid
.
Streamid¶
Для передачи потока по SRT обычно необходимо указать параметр streamid
. Это строка длиной до 512 символов, которая задается на сокете перед установлением соединения. Она отправляется в составе вызова Caller и регистрируется на стороне Listener. Основываясь на переданной в ней информации, Listener может принять или отклонить соединение, выбрать нужный поток данных или задать нужный пароль для подключения.
Эта строка начинается с символов #!::
, после которых могут быть указаны следующие параметры:
r=
— имя потокаm=
— ожидаемый режим соединения:publish
(если Caller хочет отправить поток) илиrequest
(если Caller хочет получить поток)password=
— пароль для авторизации публичного сеанса (не рекомендуется, лучше используйте параметрpassphrase
в параметрах URL, т.к. его ожидает большинство клиентов)
Во время SRT сеанса между двумя экземплярами Flussonic в streamid
автоматически добавляются следующие параметры:
s=
— идентификатор сеансаa=
— версия Flussonic
Пример: streamid="#!::r=my-stream,m=publish"
.
См. также документацию разработчика.
Порт для SRT¶
При захвате и отправке по SRT настройки порта и streamid
задаются на стороне клиентского приложения, которое формирует URL потока. При настройке публикации и проигрывания URL потока формируется на стороне Flussonic, поэтому важно выбрать правильный способ указания порта для потоков. Flussonic предлагает гибкую настройку SRT-портов для передачи и получения видео. От того, какой способ задания порта вы выберете, будет зависеть вид streamid
, который вам нужно будет использовать для приема или передачи потоков. Есть следующие варианты настройки:
- Задать отдельный SRT-порт для каждого потока или группы потоков (в шаблоне). Это самый оптимальный вариант, поддерживаемый большинством сторонних клиентов. Можно использовать в конфигурации потока опцию
srt
, если для проигрывания и публикации будет использоваться один порт, либоsrt_play
иsrt_publish
, если порты для проигрывания и публикации разные. Задавать имя потока в параметреr=
необязательно, т.к. оно уже задано в конфигурации. Если используетеsrt
, обязательно указывайте режим соединения в параметреm=
вstreamid
. -
Задать глобальный порт для всех режимов приема и передачи всех SRT потоков на вашем сервере. Этот способ больше подходит для тестовых целей, так как не поддерживается сторонними клиентами. Задать порт можно в UI в разделе Config - Settings.
Соответствующая глобальная опция в конфигурационном файле
srt
.Также можно задать отдельные глобальные порты для проигрывания
srt_play
и публикацииsrt_publish
. Это можно сделать только в конфигурационном файле. Такой режим также не поддерживается большинством клиентов.Если используете
srt
, обязательно указывайте режим соединения в параметреm=
вstreamid
, а при использованииsrt_play
иsrt_publish
эта опция не обязательна, т.к. режим соединения по указанному порту и так известен. Задавать имя потока вr=
обязательно, т.к. при использовании глобального порта непонятно, к какому потоку вы хотите обратиться. -
Задать диапазон портов для публикации и проигрывания потоков в директиве
listeners
. Этот способ используется совместно сconfig_external
, когда нужно определять имя потока по его SRT-порту. Подробнее см. в схеме.
Warning
Если вы определяете одновременно глобальные и локальные настройки портов, локальные имеют больший приоритет и применяются первыми.
Сводная таблица значений streamid
для различных режимов соединения в зависимости от способа указания порта:
Локальный srt |
Локальные srt_play /srt_publish |
Глобальный srt |
Глобальные srt_play /srt_publish |
|
---|---|---|---|---|
Публикация* |
"#!::m=publish" | Можно не указывать streamid |
"#!::r=stream_name,m=publish" | "#!::r=stream_name" |
Отправка | "#!::m=publish" | Можно не указывать streamid |
"#!::r=stream_name,m=publish" | "#!::r=stream_name" |
Проигрывание | "#!::m=request" | Можно не указывать streamid |
"#!::r=stream_name,m=request" | "#!::r=stream_name" |
Захват* |
"#!::m=request" | Можно не указывать streamid |
"#!::r=stream_name,m=request" | "#!::r=stream_name" |
Note
*
Режим в streamid
является характеристикой источника, поэтому для публикации указан m=publish
, хотя Flussonic работает в режиме Listener, а для захвата m=request
, хотя Flussonic выступает в роли Caller.
Параметры SRT¶
Во всех режимах приема и передачи потоков по SRT Flussonic поддерживает следующие параметры URL:
Параметры | Тип данных | Описание | Пример |
---|---|---|---|
minversion |
x.y.z | Минимальна версия SRT, требуемая от пира. По умолчанию значение равно 1.0.0 . |
minversion=1.1.0 |
version |
x.y.z | Необходимая для установления соединения версия SRT. По умолчанию значение равно 1.0.0 . |
version=1.3.0 |
enforcedencryption |
булево значение | Если значение равно true , то отправитель и получатель должны иметь один и тот же пароль (включая пустую строку, иными словами, без защиты). Если пароли не совпадают или только одна из сторон использует защиту, то соединение разрывается. По умолчанию значение параметра равно true . |
enforcedencryption=false |
passphrase |
строка | Пароль для защиты передачи данных. Длина пароля должна быть не менее 10 и не более 79 символов. Значение по умолчанию — пустая строка (""). | passphrase=9876543210 |
timeout |
секунды | Если равно -1 , то время отправки данных не ограничено. Поведение по умолчанию. |
timeout=-1 |
linger |
секунды | Время ожидания получения данных сокетом. По умолчанию равно 180 (подставляется автоматически в зависимости от вида передачи данных). |
linger=1 |
connect_timeout |
секунды | Время ожидания подключения. По умолчанию значение равно 0 . |
connect_timeout=2 |
latency |
миллисекунды | Время ожидания, необходимое на доставку пакета данных от отправителя к получателю. По умолчанию равно 120 . |
latency=100 |