Протокол обмена сообщениями в реальном времени ( RTMP ) изначально был проприетарным протоколом, разработанным Macromedia для потоковой передачи аудио, видео и данных через Интернет между Flash- плеером и сервером. Macromedia теперь принадлежит Adobe , которая выпустила неполную версию спецификации протокола для публичного использования.
Протокол RTMP имеет несколько разновидностей:
- Собственно RTMP, «простой» протокол, который работает поверх протокола управления передачей (TCP) и по умолчанию использует номер порта 1935.
- RTMPS, который RTMP по безопасности уровня транспортного соединения (TLS / SSL).
- RTMPE, который зашифрован по протоколу RTMP с использованием собственного механизма безопасности Adobe. Хотя детали реализации являются проприетарными, механизм использует стандартные криптографические примитивы. [1]
- RTMPT, который инкапсулируется в HTTP- запросы для прохождения межсетевых экранов. RTMPT часто используется с использованием запросов открытого текста на портах TCP 80 и 443, чтобы обойти большую часть фильтрации корпоративного трафика. Инкапсулированный сеанс может нести в себе простые пакеты RTMP, RTMPS или RTMPE.
- RTMFP, который представляет собой RTMP по протоколу дейтаграмм пользователя (UDP) вместо TCP, заменяющий поток фрагментов RTMP. Пакет 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) с использованием формата сообщения действия . Любые требуемые службы RPC выполняются асинхронно с использованием единой модели запрос / ответ клиент / сервер, так что связь в реальном времени не требуется. [ требуется разъяснение ] [2] [3]
Шифрование
Сессии RTMP могут быть зашифрованы одним из двух способов:
- Использование стандартных механизмов TLS / SSL . Базовый сеанс RTMP просто заключен в обычный сеанс TLS / SSL.
- Использование RTMPE, которое оборачивает сеанс RTMP в более легкий уровень шифрования.
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 года. [4] На целевой веб-странице, ведущей к этой спецификации, отмечается, что «В интересах клиентов, которые хотят защитить свой контент, открытая спецификация RTMP не включает уникальную систему безопасности Adobe. RTMP меры ». [5]
Документ, сопровождающий спецификацию Adobe, предоставляет «неисключительную, бесплатную, непередаваемую, не подлежащую сублицензированию, персональную, всемирную» патентную лицензию на все реализации протокола с двумя ограничениями: одно запрещает использование для перехвата потоковых данных («любая технология который перехватывает потоковое видео, аудио и / или содержимое данных для хранения на любом устройстве или носителе "), а другой запрещает обход" технологических мер для защиты аудио, видео и / или содержимого данных, включая любые меры безопасности RTMP Adobe " . [6]
Стефан Рихтер, автор нескольких книг по Flash, в 2008 году отметил, что, хотя Adobe нечетко определяет, какие патенты применяются к RTMP, Патент США 7 246 356, по- видимому, является одним из них. [2]
В 2011 году Adobe подала в суд на Wowza Media Systems, утверждая, среди прочего, нарушение их патентов RTMP. [7] [8] [9] В 2015 году Adobe и Wowza объявили, что иски были урегулированы и отклонены с предубеждением. [10]
Структура пакета
Пакеты отправляются через TCP-соединение, которое сначала устанавливается между клиентом и сервером. Они содержат заголовок и тело, которое в случае команд подключения и управления кодируется с использованием формата сообщения действия (AMF). Заголовок разделен на основной заголовок (показанный на схеме отдельно от остальных) и заголовок сообщения фрагмента . Основной заголовок является единственной постоянной частью пакета и обычно состоит из одного составного байта, где два наиболее значимых бита - это тип блока ( fmt в спецификации), а остальные образуют идентификатор потока. В зависимости от значения первого, некоторые поля заголовка сообщения могут быть опущены, а их значение получено из предыдущих пакетов, в то время как в зависимости от значения последнего базовый заголовок может быть расширен одним или двумя дополнительными байтами (как в случае диаграммы, содержащей всего три байта (c)). Если значение остальных шести битов основного заголовка (BH) (наименее значимое) равно 0, то BH составляет два байта и представляет от идентификатора потока 64 до 319 (64 + 255); если значение равно 1, то BH составляет три байта (с последними двумя байтами, закодированными как 16-битный Little Endian) и представляет от идентификатора потока 64 до 65599 (64 + 65535); если значение равно 2, то BH составляет один байт и зарезервирован для сообщений и команд управления протоколом низкого уровня. Заголовок сообщения фрагмента содержит информацию о метаданных, такую как размер сообщения (измеряется в байтах), разность отметок времени и тип сообщения . Это последнее значение представляет собой один байт и определяет, является ли пакет звуковым, видео, командным или «низкоуровневым» пакетом RTMP, таким как RTMP Ping.
Ниже показан пример, когда флеш-клиент выполняет следующий код:
var stream : NetStream = новый NetStream ( connectionObject );
это сгенерирует следующий чанк:
Шестнадцатеричный код | ASCII |
---|---|
03 00 0B 68 00 00 19 14 00 00 00 00 02 00 0C 63 72 65 61 74 65 53 74 72 65 61 6D 00 40 00 00 00 00 00 00 00 00 05 | ␃ ␀ @ I ␀ ␀ ␙ ␔ ␀ ␀ ␀ ␀ ␂ ␀ ␌ create S tream ␀ @ ␀ ␀ ␀ ␀ ␀ ␀ ␅ |
В пакете начинается с базовым заголовком одного байта (0x03) , где два наиболее значимые биты (б 00 000011) определяют тип заголовка фрагмента из 0 , а остальные (B00 000011 ) определяют Кусок идентификатор потока 3. четыре возможных значения типа заголовка и их значение:
- b00 = 12-байтовый заголовок (полный заголовок).
- b01 = 8 байт - как тип b00. не включая идентификатор сообщения (4 последних байта).
- b10 = 4 байта - включены базовый заголовок и метка времени (3 байта).
- b11 = 1 байт - включен только базовый заголовок.
Последний тип (b11) всегда используется в случае агрегированных сообщений, где в приведенном выше примере второе сообщение будет начинаться с идентификатора 0xC3 (b11000011) и будет означать, что все поля заголовка сообщения должны быть получены из сообщения с идентификатор потока 3 (это будет сообщение прямо над ним). Шесть младших значащих битов, образующих идентификатор потока, могут принимать значения от 3 до 63. Некоторые значения имеют особое значение, например 1, обозначающее расширенный формат идентификатора, и в этом случае за ним следуют два байта. Значение два предназначено для сообщений низкого уровня, таких как Ping и Set Client Bandwidth.
Следующие байты заголовка RTMP (включая значения в приведенном выше примере пакета) декодируются следующим образом:
- байт # 1 (0x03) = Тип заголовка блока.
- байт # 2-4 (0x000b68) = дельта отметки времени.
- byte # 5-7 (0x000019) = Длина пакета - в данном случае это 0x000019 = 25 байт.
- байт # 8 (0x14) = идентификатор типа сообщения - 0x14 (20) определяет командное сообщение в кодировке AMF0 .
- byte # 9-12 (0x00000000) = идентификатор потока сообщений. Это в порядке от младшего к старшему
Байт идентификатора типа сообщения определяет, содержит ли пакет аудио / видеоданные, удаленный объект или команду. Вот некоторые возможные значения:
- 0x01 = Установить размер пакета сообщения.
- 0x02 = Прервать.
- 0x03 = Подтверждение.
- 0x04 = Контрольное сообщение.
- 0x05 = пропускная способность сервера
- 0x06 = Пропускная способность клиента.
- 0x07 = Виртуальный контроль.
- 0x08 = Аудиопакет.
- 0x09 = пакет видео.
- 0x0F = данные расширены.
- 0x10 = Контейнер расширен.
- 0x11 = Команда расширена (команда типа AMF3).
- 0x12 = Данные (Invoke (информация onMetaData отправляется как таковая)).
- 0x13 = Контейнер.
- 0x14 = Команда (команда типа AMF0).
- 0x15 = UDP
- 0x16 = агрегировать
- 0x17 = Присутствует
После заголовка 0x02 обозначает строку размером 0x000C и значениями 0x63 0x72 ... 0x6D (команда createStream). После этого у нас есть 0x00 (число), которое является идентификатором транзакции со значением 2.0. Последний байт - 0x05 (ноль), что означает отсутствие аргументов.
Вызов структуры сообщения (0x14, 0x11)
Некоторые из типов сообщений, показанных выше, такие как Ping и Set Client / Server Bandwidth, считаются сообщениями протокола RTMP низкого уровня, которые не используют формат кодирования AMF. С другой стороны, командные сообщения, будь то AMF0 (тип сообщения 0x14) или AMF3 (0x11), используют формат и имеют общую форму, показанную ниже:
(Строка) <Имя команды>(Число) <Идентификатор транзакции>(Смешанный) <Аргумент> пр. Нулевой, Строка, Объект: {ключ1: значение1, ключ2: значение2 ...}
Идентификатор транзакции используется для команд, которые могут иметь ответ. Значение может быть либо строкой, как в приведенном выше примере, либо одним или несколькими объектами, каждый из которых состоит из набора пар ключ / значение, где ключи всегда кодируются как строки, а значения могут быть любым типом данных AMF, включая сложные типы, такие как массивы.
Структура управляющего сообщения (0x04)
Управляющие сообщения не кодируются AMF. Они начинаются с идентификатора потока 0x02, что подразумевает полный заголовок (тип 0) и имеет тип сообщения 0x04. За заголовком следуют шесть байтов, которые интерпретируются как таковые:
- # 0-1 - Тип управления.
- # 2-3 - Второй параметр (имеет значение в определенных типах управления)
- # 4-5 - Третий параметр (то же)
Первые два байта тела сообщения определяют тип Ping, который, очевидно, [11] может принимать шесть возможных значений.
- Тип 0 - Clear Stream: отправляется, когда соединение установлено и не несет дополнительных данных.
- Тип 1 - Очистить буфер.
- Тип 2 - Stream Dry.
- Тип 3 - время буферизации клиента. Третий параметр содержит значение в миллисекундах.
- Тип 4 - сбросить поток.
- Тип 6 - Пинг клиента с сервера. Второй параметр - текущее время.
- Тип 7 - Pong ответ от клиента. Второй параметр - это время, когда клиент получает пинг.
- Тип 8 - UDP-запрос.
- Тип 9 - UDP-ответ.
- Тип 10 - Предел пропускной способности.
- Тип 11 - Пропускная способность.
- Тип 12 - Полоса пропускания дроссельной заслонки.
- Тип 13 - поток создан.
- Тип 14 - поток удален.
- Тип 15 - Установить доступ для чтения.
- Тип 16 - Установить доступ для записи.
- Тип 17 - Мета-запрос потока.
- Тип 18 - поток мета-ответа.
- Тип 19 - Получить границу сегмента.
- Тип 20 - Установить границу сегмента.
- Тип 21 - при отключении.
- Тип 22 - Установить критическую ссылку.
- Тип 23 - Отключить.
- Тип 24 - Обновление хэша.
- Тип 25 - Тайм-аут хеширования.
- Тип 26 - запрос хеширования.
- Тип 27 - Хеш-ответ.
- Тип 28 - проверьте пропускную способность.
- Тип 29 - Установить доступ к аудиосэмплу.
- Тип 30 - Установить доступ к образцу видео.
- Тип 31 - Дроссельная заслонка.
- Тип 32 - Дроссельная заслонка.
- Тип 33 - уведомление DRM.
- Тип 34 - RTMFP Sync.
- Тип 35 - Запрос IHello.
- Тип 36 - Нападающий Привет.
- Тип 37 - перенаправить IHello.
- Тип 38 - уведомить EOF.
- Тип 39 - Продолжить прокси.
- Тип 40 - Удаление прокси-сервера в восходящем направлении.
- Тип 41 - RTMFP Set Keepalive.
- Тип 46 - сегмент не найден.
Pong - это имя ответа на Ping со значениями, указанными выше.
Структура сообщения ServerBw / ClientBw (0x05, 0x06)
Это относится к сообщениям, которые связаны с битрейтом восходящего потока клиента и нисходящего потока сервера. Тело состоит из четырех байтов, показывающих значение полосы пропускания с возможным расширением на один байт, который устанавливает тип ограничения. Он может иметь одно из трех возможных значений: жесткий, мягкий или динамический (мягкий или жесткий).
Установить размер блока (0x01)
Значение, полученное в четырех байтах тела. Существует значение по умолчанию 128 байтов, и сообщение отправляется только тогда, когда требуется изменение.
Протокол
Рукопожатие
После установления TCP-соединения сначала устанавливается RTMP-соединение, выполняя рукопожатие посредством обмена тремя пакетами с каждой стороны (также называемых Chunks в официальной документации). В официальной спецификации они обозначаются как C0-2 для пакетов, отправленных клиентом, и S0-2 для стороны сервера соответственно, и их не следует путать с пакетами RTMP, которыми можно обмениваться только после завершения рукопожатия. Эти пакеты имеют собственную структуру, а C1 содержит поле, устанавливающее временную метку «эпохи», но поскольку это может быть установлено на ноль, как это сделано в реализациях сторонних производителей, пакет можно упростить. Клиент инициализирует соединение, отправляя пакет C0 с постоянным значением 0x03, представляющим текущую версию протокола. Он следует прямо с C1, не дожидаясь получения S0 первым, который содержит 1536 байтов, причем первые четыре представляют временную метку эпохи, вторые четыре все равны 0, а остальные являются случайными (и которые могут быть установлены на 0 в третьей стороне. реализации). C2 и S2 являются эхо-сигналом S1 и C1 соответственно, за исключением того, что вторые четыре байта являются временем получения соответствующего сообщения (вместо 0). После получения C2 и S2 рукопожатие считается завершенным.
Соединять
На этом этапе клиент и сервер могут согласовывать соединение, обмениваясь сообщениями в кодировке AMF . К ним относятся пары ключ-значение, которые относятся к переменным, которые необходимы для установления соединения. Пример сообщения от клиента:
( Invoke ) "connect" ( ID транзакции ) 1.0 ( Object1 ) { app : "sample" , flashVer : "MAC 10,2,153,2" , swfUrl : null , tcUrl : "rtmpt: //127.0.0.1/sample" , fpad : false , возможности : 9947.75 , audioCodecs : 3191 , videoCodecs : 252 , videoFunction : 1 , pageUrl : null , objectEncoding : 3.0 }
Flash Media Server и другие реализации используют концепцию «приложения» для концептуального определения контейнера для аудио / видео и другого контента, реализованного как папка в корне сервера, которая содержит медиа-файлы для потоковой передачи. Первая переменная содержит имя этого приложения как «образец», которое является именем, предоставленным сервером Wowza для их тестирования. flashVer
Строка такая же , как возвращаемый Action-скрипт getversion()
функции. audioCodec
И videoCodec
кодируются как двойники и их значение можно найти в оригинальной спецификации. То же самое верно и для videoFunction
переменной, которая в данном случае является самоочевидной константой SUPPORT_VID_CLIENT_SEEK. Особый интерес представляет то, objectEncoding
что будет определять, будет ли остальная часть сообщения использовать расширенный формат AMF3 или нет. Поскольку версия 3 является текущей версией по умолчанию, флэш-клиент должен явно указать в коде сценария действия использовать AMF0, если это требуется. Затем сервер отвечает последовательностью сообщений ServerBW, ClientBW и SetPacketSize, за которыми, наконец, следует Invoke с примером сообщения.
( Invoke ) "_result" ( идентификатор транзакции ) 1.0 ( Object1 ) { fmsVer : "FMS / 3,5,5,2004" , возможности : 31.0 , режим : 1.0 } ( Object2 ) { level : "status" , code : " NetConnection.Connect.Success " , описание : " Соединение успешно " , данные : ( массив ) { версия : " 3,5,5,2004 " }, clientId : 1728724019 , objectEncoding : 3.0 }
Некоторые из приведенных выше значений сериализованы в свойства универсального объекта Action-script, который затем передается прослушивателю событий NetConnection. clientId
Установит номер для сессии, которая началась в связи. Кодировка объекта должна соответствовать ранее установленному значению.
Проиграть видео
Чтобы запустить видеопоток, клиент отправляет вызов createStream, за которым следует сообщение ping, за которым следует вызов play с именем файла в качестве аргумента. Затем сервер ответит серией команд «onStatus», за которыми следуют видеоданные, инкапсулированные в сообщениях RTMP.
После установления соединения медиафайлы отправляются путем инкапсуляции содержимого тегов FLV в сообщения RTMP типа 8 и 9 для аудио и видео соответственно.
HTTP-туннелирование (RTMPT)
Это относится к версии протокола с туннелированием HTTP. Он обменивается данными через порт 80 и передает данные AMF внутри запроса и ответов HTTP POST. Последовательность подключения следующая:
POST / fcs / identify2 HTTP / 1.1 Content-Type : application / x-fcs \ r \ nHTTP / 1.0 404 не найдено
POST / open / 1 HTTP / 1.1 Content-Type : application / x-fcs \ r \ nHTTP / 1.1 200 ОКТип содержимого: application / x-fcs \ r \ n 1728724019
У первого запроса есть /fcs/ident2
путь, и правильным ответом является ошибка 404 Not Found. Затем клиент отправляет запрос / open / 1, в котором сервер должен ответить сообщением 200 ok, добавив случайное число, которое будет использоваться в качестве идентификатора сеанса для указанного сообщения. В этом примере в теле ответа возвращается 1728724019.
POST / idle / 1728724019/0 HTTP / 1.1 HTTP / 1.1 200 OK 0x01
С этого момента /idle/
это запрос на опрос, в котором идентификатор сеанса был сгенерирован и возвращен сервером, а последовательность - это просто число, которое увеличивается на единицу для каждого запроса. Соответствующий ответ - 200 OK с целым числом, возвращенным в теле, обозначающим интервал времени. Данные AMF отправляются через/send/
Программные реализации
RTMP реализуется на трех этапах:
- Кодировщик видео в реальном времени
- Сервер потоковой передачи мультимедиа в реальном времени и по запросу
- Живой клиент и клиент по запросу
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 . [12] В настоящее время версия имеет значительно улучшенные функциональные возможности , и была переписана , чтобы воспользоваться преимуществами на языке программирования Си . В частности, основная функциональность была встроена в библиотеку (librtmp), которую могут легко использовать другие приложения. Разработчики RTMPdump также написали поддержку librtmp для MPlayer , FFmpeg , XBMC , cURL , VLC и ряда других программных проектов с открытым исходным кодом. Использование librtmp обеспечивает этим проектам полную поддержку RTMP во всех его вариантах без каких-либо дополнительных усилий по разработке.
FLVstreamer
FLVstreamer - это форк RTMPdump без кода, который, по утверждению Adobe, нарушает DMCA в США. Это было разработано как ответ на попытку Adobe в 2008 году подавить RTMPdump. FLVstreamer - это клиент RTMP, который сохранит поток аудио- или видеоконтента с любого сервера RTMP на диск, если шифрование (RTMPE) для потока не включено.
Смотрите также
- Защищенная потоковая информация о RTMPS и RTMPE
- Видео по запросу (VoD)
Рекомендации
- ^ "RTMPE" . Справка по Adobe Flash Lite 4 . Adobe . Проверено 29 декабря 2013 года .
- ^ а б «TheRealTimeWeb.com: Adobe Patents RTMP» . therealtimeweb.com .
- ^ «Использование сервисов RPC в Flex Data Services 2» . Архивировано из оригинала 3 апреля 2007 года . Проверено 16 апреля 2007 года . Цитировать журнал требует
|journal=
( помощь ) - ^ H. Parmar, М. Thornburgh (ред.) Протокол компании Adobe Real Time Messaging , Adobe, 21 декабря 2012
- ^ «Спецификация протокола обмена сообщениями в реальном времени (RTMP)» . Проверено 8 мая 2014 .
- ^ Лицензия на спецификацию RTMP , опубликована в апреле 2009 г.
- ^ Шумахер-Расмуссен, Эрик (27 мая 2011 г.). «Wowza отрицает утверждения Adobe о нарушении патентных прав» . streamingmedia.com .
- ^ Лоулер, Райан (31 мая 2011 г.). «Wowza стреляет в Adobe в патентном иске Flash» . gigaom.com .
- ^ «ADOBE SYSTEMS INCORPORATE - № C 11-2243 CW. - 20120907565 - Leagle.com» . leagle.com .
- ^ Wowza Media Systems и Adobe Systems урегулировали патентные дела http://www.wowza.com/news/wowza-media-systems-and-adobe-systems-settle-patent-cases
- ^ Проект Red5 (2009) Пинг. Доступно по адресу: http://trac.red5.org/wiki/Documentation/Tutorials/Ping . Доступ: 25 декабря 2011 г.
- ^ «Обновления: 01.11.2009» . Проверено 1 ноября 2009 года .
Внешние ссылки
- Страница разработчика Adobe - RTMP - официальная спецификация