Skip to content

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.

    Также можно задать отдельные глобальные порты для проигрывания 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