Протокол RTMP¶
RTMP (Real Time Messaging Protocol) — проприетарный и закрытый протокол передачи видео поверх TCP. Главным плюсом RTMP стала его реализация в Adobe Flash Player, который на короткий период был главным способом показать потоковое видео в браузере и на мобильном телефоне.
Широчайшее распространение в течении короткого промежутка времени стало предпосылкой к тому, чтобы этот протокол не исчез, а остался и сегодня в качестве contribution средства. Никто сегодня не смотрит видео по RTMP, но по нему публикуют видео в социальные сети.
Применимость и ограничения¶
RTMP терпимо справляется с отправкой одной видео дорожки среднего качества и одной аудиодорожки среднего качества по хорошему, желательно проводному интернет соединению. Сегодня этот протокол встречается, например, в OBS - бесплатной программе для вещания с ноутбука в соцсети.
Когда RTMP не подойдет?
- Несколько языков по этому протоколу стандартными методами передать нельзя. Нужна специальная доработка клиента и сервера.
- Мультибитрейтная доставка по нему практически невозможна, это прерогатива HLS.
- Плохой канал станет непреодолимым препятствием из-за проблемы Head of line blocking, т.е. достаточно одного потерянного пакета и соединение приходит в негодность, потеря многих секунд видео.
- Качественные современные кодеки (AV1, Opus) доступны только через расширения, ещё не получившие массового рапространения.
- Нет стандартного способа передачи субтитров, как и прочих метаданных.
Технические детали RTMP¶
В RTMP заложено очень много идей для RPC (remote procedure call). Его авторы планировали сделать что-то типа Corba (но без схем, т.е. с соответствующей перспективой поддержки): вызовы методов, ссылки на объекты, отдельные каналы вызовов методов на объектах.
Дизайнились, но не получили распространения Shared Objects - способ синхронизации данных между подключенными клиентами. Весь RTMP вырос из сервера приложений, который должен был обеспечивать серверную логику для подключенных флеш клиентов. Видео и аудио были не первичны.
Это хорошо видно по списку ограничений:
- не больше одной видео дорожки
- не большое одной аудио дорожки
- фиксированный выбор кодеков, из которых буквально три сохраняют актуальность на сегодня (H.264, AAC, PCMA)
Итеративный дизайн RTMP привел к тому, что в нём существует много способ делать одно и то же и ещё больше ситуативных недокументированных решений, работающих в конкретной связке клиента и сервера. Плюс к этому в него заложены скрытые механизмы конкурентной борьбы.
Судебные иски Adobe¶
В 2012-м году Adobe опубликовали спецификацию на RTMP, которая начиналась со слов «читающий эту спецификацию обязан ей следовать байт в байт и ничего не придумывать от себя», после чего сразу побежали судиться с альтернативным реализациями на основании того, что они нарушают эту спецификацию.
Не мудрено, ведь если флеш плеер подключался к серверу, написанному по этой спецификации, то он не мог проигрывать H264 (хитрым образом проверяя мусорную часть первого пакета). Правда так торопились, что вообще ничего нельзя было сделать по этой спецификации, но судебные дела были.
Аналогичная судьба постигла утилиту rtmpdump, авторы которой провели реверсинжиниринг протокола RTMPE, который заявлялся как передовая защита от копирования данных (вместо DRM). Под RTMPE уходили немалые маркетинговые бюджеты, а выяснилось, что вся безопасность основана на обфусцированном ключе, который лежит открытым текстом в каждой копии флеш плеера. Т.е. банальный TLS (и работающий по нему RTMPS) несравненно более защищен от копирования, потому что RTMPE не только не защищает от копирования клиентом, он не защищает и от прослушивания трафика.
Замедленный хендшейк RTMP¶
На старте по протоколу необходимо дважды обменяться пакетами, в которых нет никаких данных, только мусор, который особенным образом интерпретируется в различных клиентах и серверах. Это добавляет на старте минимум 2 ненужных RTT, без которых можно обойтись.
Нарезание видео на чанки¶
Один из артефактов идеи о сервере приложений с протоколом для RPC - нарезание видео на чанки. Это планировалось делать для того, чтобы в середине длинного кейфрейма можно было воткнуть посылку какого-нибудь вызова метода, но на практике это сегодня никому не нужно, ведь никому кроме подключенного флеш плеера это не нужно.
Особенно удачным дизайн решением было сделать дефолтный размер чанка чуть больше MTU, чем обеспечить фрагментирование пакетов и увеличить packet rate на передаче видео.
FLV в основе¶
В основе RTMP лежит формат FLV сравнимый с ним по удачности дизайна. Это означает фиксированный набор поддерживаемых кодеков, миллисекундная точность таймстемпов и невозможность указания больше одной видео и аудио дорожки.
Миллисекундная точность указания таймстемпов недостаточна для перепаковки в mpegts или fmp4. Так, например, для убирания заикания на айфоне, приходилось перевычислять DTS аудиокадров, исходя из их реальной длительности.
Подробнее о борьбе с ограничениями кодеков ниже.
Неопределенность с URL в RTMP¶
При дизайне этого протокола получилось так, что в нём нет классических URL.
Дело в том, что когда указывается URL: rtmp://server/live/tvchannels/cnn
, то он будет в плеере разбит на несколько частей:
- имя сервера
server
- application name, например
live
- имя потока
tvchannels/cnn
Тут возникает неоднозначность, ведь может быть правильное разбиение live/tvchannels
и cnn
?
Клиент угадать не может, у разных CDN-ов сложились разные дефолты. Выходов несколько:
- сокращать количество сегментов до 2-х, тогда можно угадать, где какая часть
- указывать разделитель в пути:
rtmp://server/live/tvchannels///cnn
, например тройной слеш.
Это техническое решение имеет свои причины, ведь RTMP делался для сервера приложений, вот так эти приложения и именовались.
Сегодня такое решение практического смысла не имеет, но продолжает вносить сумбур.
К этому добавляется то, что иногда можно встретить такие имена приложений: live?key1=value1
. Если в имени потока тоже есть query string,
то как их собирать в URL не очень понятно, и получаются такие монстры: rtmp://server/live?key1=value1///cnn?key2=value2
RTMFP, RTMPT¶
Мимолетным явлением мелькнули RTMFP (купили компанию с её технологиями и хотели воткнуть UDP в Flash Player, но рынок не был готов, впереди было десятилетие HLS) и RTMPT — low latency вещание по HTTP. Второй был неплохой идеей, если бы не был таким монстром, который регулярным поллингом должен быть скачивать чанки несколько раз в секунду с сервера.
Enhanced RTMP¶
Закрепившася у телевизионщиков практика публиковать видео на сервера по RTMP (и чего им HTTP MPEG-TS не подошел? В нём ведь абсолютно всё лучше) привела к неприятной ситуации: протокол не позволяет покупать новое железо и внедрять новые кодеки H265 и AV1. Аналогично и со звуком, а без Opus довольно странно строить сервис.
Первая итерация добавления H265 довольно просто воспользовалась невостребованным номером кодека и этого хватило, чтобы клиент и сервер смогли объясниться.
Однако YouTube принял решение о внедрении более расширенной спецификации Enhanced RTMP в которой возможны дальнейшие добавления новых кодеков. Этот протокол ещё побудет с нами.
Реализация RTMP в Flussonic¶
Настройка приема и передачи потоков по RTMP в Flussonic выполняется стандартными способами. Важно учитывать приведенные выше особенности URL.
Также для использования RTMP/Enhanced RTMP и RTMPS необходимо задать порты во Flussonic.
Flussonic поддерживает:
- Проигрывание по RTMP.
- Захват по RTMP
- Прием публикации по RTMP. Пример настройки см. на странице Публикация из OBS Studio в Flussonic Media Server.
- Отправку по RTMP. Настройка осуществляется стандартным образом с учетом особенностей формирования URL, описанных ниже. Примеры настройки для популярных соцсетей приведены на странице Публикация в социальные сети.
Задание портов для RTMP/Enhanced RTMP и RTMPS¶
Порты для RTMP/Enhanced RTMP и RTMPS можно задать в разделе Listeners на вкладке Config -> Settings.
Note
Для использования RTMPS необходимо получить SSL-сертификат.