Введение

Протокол связи для потоковой передачи данных через Интернет

Протокол обмена сообщениями в реальном времени (RTMP) — это протокол связи для потоковой передачи аудио, видео и данных через Интернет. Первоначально разработанный компанией Macromedia как проприетарный протокол для потоковой передачи между Flash Player и Flash Communication Server, компания Adobe (которая приобрела Macromedia) опубликовала неполную версию спецификации протокола для общего пользования. Протокол RTMP имеет несколько вариантов:

RTMP, собственно, — «простой» протокол, работающий поверх протокола управления передачей (TCP) и использующий порт 1935 по умолчанию. RTMPS, который представляет собой RTMP через соединение безопасности транспортного уровня (TLS/SSL). RTMPE, который зашифрован с использованием собственного механизма безопасности Adobe. Хотя детали реализации являются проприетарными, механизм использует стандартные криптографические примитивы. RTMPT, который инкапсулирован в HTTP-запросы для обхода брандмауэров. RTMPT часто использует незашифрованные запросы на TCP-портах 80 и 443 для обхода большинства фильтров корпоративного трафика. В инкапсулированной сессии могут передаваться обычные пакеты RTMP, RTMPS или RTMPE. RTMFP, который представляет собой RTMP через протокол пользовательских датаграмм (UDP) вместо TCP, заменяя RTMP Chunk Stream. Пакет протоколов Secure Real Time Media Flow Protocol был разработан компанией Adobe Systems и позволяет конечным пользователям напрямую подключаться и общаться друг с другом (P2P). Хотя основной целью разработки RTMP было создание протокола для воспроизведения видео Flash, он также используется в некоторых других приложениях, таких как Adobe LiveCycle Data Services ES.

Основная работа

RTMP — это протокол на основе TCP, поддерживающий постоянные соединения и обеспечивающий связь с низкой задержкой. Для обеспечения плавной передачи потоков и максимальной передачи информации он разделяет потоки на фрагменты, размер которых динамически согласовывается между клиентом и сервером. Иногда размер фрагментов остается неизменным; по умолчанию он составляет 64 байта для аудиоданных и 128 байт для видеоданных и большинства других типов данных. Фрагменты из разных потоков могут быть переплетены и мультиплексированы по одному соединению. При использовании более крупных блоков данных протокол передает только один байт заголовка на фрагмент, что обеспечивает минимальные накладные расходы. Однако на практике отдельные фрагменты обычно не переплетаются. Вместо этого переплетение и мультиплексирование выполняются на уровне пакетов, при этом пакеты RTMP по нескольким активным каналам переплетаются таким образом, чтобы каждый канал соответствовал требованиям к полосе пропускания, задержке и другим параметрам качества обслуживания. Пакеты, переплетенные таким образом, рассматриваются как неделимые и не переплетаются на уровне фрагментов. RTMP определяет несколько виртуальных каналов, по которым могут отправляться и приниматься пакеты, работающие независимо друг от друга. Например, существует канал для обработки RPC-запросов и ответов, канал для данных видеопотока, канал для данных аудиопотока, канал для служебных сообщений (согласование размера фрагмента и т. д.) и так далее. Во время типичной сессии RTMP одновременно может быть активно несколько каналов. При кодировании данных RTMP генерируется заголовок пакета, в котором указывается, в частности, идентификатор канала, по которому он должен быть отправлен, временная метка создания (при необходимости) и размер полезной нагрузки пакета. За этим заголовком следует фактическое содержимое полезной нагрузки пакета, которое фрагментируется в соответствии с текущим согласованным размером фрагмента перед отправкой по соединению. Сам заголовок пакета никогда не фрагментируется, и его размер не учитывается при определении данных в первом фрагменте пакета. Иными словами, фрагментации подвергается только фактическая полезная нагрузка пакета (медиаданные). На более высоком уровне RTMP инкапсулирует мультимедийные потоки MP3 или AAC аудио и FLV1 видео, а также может выполнять удаленные вызовы процедур (RPC) с использованием формата сообщений Action Message Format. Все необходимые RPC-сервисы выполняются асинхронно, с использованием единой модели запрос/ответ клиент/сервер, что исключает необходимость в коммуникации в реальном времени.

Туннелирование HTTP

В RTMP Tunneled (RTMPT) данные RTMP инкапсулируются и передаются по протоколу HTTP, а сообщения от клиента (в данном случае медиаплеера) адресуются на порт 80 (порт по умолчанию для HTTP) на сервере. Хотя сообщения в RTMPT больше, чем соответствующие нетуннелизированные сообщения RTMP из-за HTTP-заголовков, RTMPT может упростить использование RTMP в ситуациях, когда использование нетуннелизированного RTMP было бы невозможно, например, когда клиент находится за брандмауэром, блокирующим исходящий трафик, отличный от HTTP и HTTPS. Протокол работает путем отправки команд через URL POST-запроса, а AMF-сообщений – в теле POST-запроса. Например:

POST /open/1 HTTP/1.1

для установления соединения.

Документ спецификации и патентная лицензия

Adobe выпустила спецификацию версии 1.0 протокола, датированную 21 декабря 2012 года. На веб-странице, ведущей к этой спецификации, указано, что "для обеспечения преимуществ клиентам, желающим защитить свой контент, открытая спецификация RTMP не включает уникальные средства защиты RTMP, разработанные Adobe". В документе, сопровождающем спецификацию Adobe, предоставляется "неисключительная, безвозмездная, непередаваемая, не подлежащая сублицензированию, персональная, всемирная" патентная лицензия на все реализации протокола с двумя ограничениями: одно запрещает использование для перехвата потоковых данных ("любая технология, перехватывающая потоковое видео, аудио и/или данные для хранения на любом устройстве или носителе"), а другое – обход "технологических мер защиты аудио-, видео- и/или данных, включая любые средства защиты RTMP от Adobe".

Патенты и связанные с ними судебные споры

Стефан Рихтер, автор нескольких книг о Flash, отметил в 2008 году, что, несмотря на некоторую неопределенность Adobe в отношении применимых к RTMP патентов, один из них, по всей видимости, относится к RTMP. В 2011 году Adobe подала в суд на Wowza Media Systems, обвинив компанию, в частности, в нарушении их патентных прав на RTMP. В 2015 году Adobe и Wowza объявили об урегулировании судебных разбирательств и прекращении исков без права на повторное обращение.

Структура сообщений ServerBw/ClientBw (0x05, 0x06)

Это относится к сообщениям, касающимся скорости передачи данных от клиента (upstream) и от сервера (downstream). Тело сообщения состоит из четырех байтов, отображающих значение пропускной способности, с возможным расширением на один байт, определяющим Тип ограничения. Этот параметр может принимать одно из трех значений: жесткое, мягкое или динамическое (либо мягкое, либо жесткое).

Установка размера куска (0x01)

Значение, полученное в четырех байтах тела сообщения. Значение по умолчанию составляет 128 байт, и сообщение отправляется только при необходимости внесения изменений.

Пожимание рук

После установления TCP-соединения, первым устанавливается RTMP-соединение, осуществляя рукопожатие посредством обмена тремя пакетами с каждой стороны (также называемыми "chunks" в официальной документации). В официальной спецификации они обозначаются как C0 2 для пакетов, отправленных клиентом, и S0 2 для серверной стороны соответственно, и их не следует путать с RTMP-пакетами, которыми можно обмениваться только после завершения рукопожатия. Эти пакеты имеют собственную структуру, и C1 содержит поле для установки временной метки "epoch", однако, поскольку его можно установить в ноль, как это делается в сторонних реализациях, пакет можно упростить. Клиент инициирует соединение, отправляя пакет C0 с постоянным значением 0x03, представляющим текущую версию протокола. За отправкой C1 следует немедленно, без ожидания получения S0, который содержит 1536 байт: первые четыре байта представляют временную метку epoch, следующие четыре – нули, а остальные – случайные значения (которые также могут быть установлены в 0 в сторонних реализациях). C2 и S2 являются эхом S1 и C1 соответственно, за исключением того, что вторые четыре байта содержат время получения соответствующего сообщения (вместо нулей). После получения C2 и S2 рукопожатие считается завершенным.

Прокрутить видео

Чтобы начать видеопоток, клиент отправляет запрос "createStream", за которым следует сообщение ping, а затем запрос "play" с именем файла в качестве аргумента. Сервер ответит серией команд "onStatus", за которыми последуют видеоданные, инкапсулированные в сообщения RTMP. После установления соединения медиаданные передаются путем заключения содержимого тегов FLV в сообщения RTMP типа 8 и 9 для аудио и видео соответственно.

rtmpdump

Открытый RTMP-клиент командной строки rtmpdump предназначен для воспроизведения или сохранения на диск полного RTMP-потока, включая протокол RTMPE, используемый Adobe для шифрования. RTMPdump работает в Linux, Android, Solaris, Mac OS X и большинстве других Unix-подобных операционных систем, а также в Microsoft Windows. Изначально поддерживая все 32-битные версии Windows, включая Windows 98, начиная с версии 2.2 программное обеспечение работает только на Windows XP и выше (хотя более ранние версии остаются полностью функциональными). Пакеты программного обеспечения rtmpdump доступны в основных репозиториях с открытым исходным кодом (дистрибутивах Linux). В их состав входят клиентские приложения "rtmpdump", "rtmpsrv" и "rtmpsuck". Разработка RTMPdump была возобновлена в октябре 2009 года за пределами США на сайте MPlayer. Текущая версия обладает значительно улучшенной функциональностью и была переписана с использованием преимуществ языка программирования C. В частности, основная функциональность была реализована в виде библиотеки (librtmp), которую легко использовать в других приложениях. Разработчики RTMPdump также добавили поддержку librtmp в MPlayer, FFmpeg, XBMC, cURL, VLC и ряд других проектов с открытым исходным кодом. Использование librtmp обеспечивает этим проектам полную поддержку RTMP во всех его вариантах без дополнительных усилий по разработке.

FLVstreamer (потоковый видеоролик)

FLVstreamer — это форк RTMPdump, исключающий код, который, по утверждению Adobe, нарушает закон DMCA в США. Он был разработан в ответ на попытку Adobe в 2008 году заблокировать RTMPdump. FLVstreamer — это RTMP-клиент, который позволяет сохранять аудио- или видеопоток с любого RTMP-сервера на диск, при условии, что поток не зашифрован (RTMPE).

Улучшенная RTMP

Flash-видео контейнер в RTMP в большинстве реализаций ограничен кодеком H.264. По этой причине организация Veovera Software Organization, включающая Adobe, Google и Veriskope, опубликовала расширенную спецификацию RTMP, добавляющую поддержку кодеков VP9, H.265 и AV1 в контейнере Flash Video FLV.