Протокол RTMP
Материал взят из ВИКИ отсюда и
отсюда
Спецификация самого протокола лежит тут
Real Time Messaging Protocol - протокол , придуманный Adobe , предназначен для передачи флеш-обьектов и видео по сети.
В качестве серверов могут выступать : MacroMedia Media sever, Open Source Red5 , и другие.
Это упрощенный протокол , оптимизированный для сетей со слабой пропускной способностью.
Один коннект может поддерживать до 64 потоков. Каждый пакет должен включать в себя id потока.
Пакеты бьются на фиксированные части одинакового размера, называемые chunk.
Для коннекта используется Tcp/ip port 1935. Коннект инициируется клиентом.
1. Вначале клиент посылает 1 байт -
0x3. Затем посылает блок данных размером 1536 байт.
2. Сервер получает эти данные , затем также в свою очередь
посылает сначала байт 0x3 , затем произвольный блок 1536 байт,
затем повторно тот же клиентский блок данных размером 1536 байт.
3. Клиент получает этот блок , отсылает еще раз те же 1536 байт,
после чего устанавливается коннект - handshake выполнен.
Далее клиент посылает серверу 3 стандартных пакета : первый пакет - это пакет , подтверждающий коннект.
Во втором пакете клиент посылает обьект NetConnection.
В третьем пакете клиент посылает обьект NetStream.
RTMP-пакет состоит из хидера фиксированной длины и тела переменной длины, последняя по умолчанию равна 128 байт.
Рассмотрим формат RTMP хидера , возьмем его первый байт. Первые 2 бита определяют размер самого хидера.
Тут возможны всего 4 варианта для комбинации из двух бит:
0 - в этом случае размер хидера = 12 байтам
1 - в этом случае размер хидера = 8 байтам
2 - в этом случае размер хидера = 4 байта
3 - в этом случае размер хидера = 1 байт
В оставшихся 6 битах байта прописывается id-шник потока, что ограничивает число потоков в одном коннекте до 64.
Если размер хидера 8 и более байт, 3 следующих байта используется для записи размера самого пакета.
Если размер хидера 4 байта и менее, размер пакета будет стандартным: 128 байт для видео и 64 байта для аудио.
Для 8-байтных и выше хидеров , следующий - пятый байт - указывает тип обьекта :
0x3 - start rtmp connection
0x4 - ping packet
0x5 - server response
0x6 - client request
0x8 - audio
0x9 - video
0x12 - notify
0x13 - shared object
0x14 - rpc
Типы данных :
0x0 - numeric value
0x1 - boolean value
0x2 - ASCII string
0x3 - Flash object
0x4 - Flash movie
0x5 - NULL
0x6 - undefined
0x7 - reference
0x8 - ECMA array
0x9 - end of an object
0xa - Strict array
...
Пример RTMP - хидера (16-ричный расклад):
03 000019 0000c9 14 00000000
Первый байт :
первые 2 бита - нули - говорят о том , что размер хидера - 12 байт
следующие 6 бит - три - id-шник потока
Следующие 3 байта :
000019 - timestamp относительно предыдущего пакета
Следующие 3 байта :
0000c9 - размер самого пакета - 201 байт
Следующий байт :
14 - content type - в данном случае rpc
Следующие 4 байта :
00000000 - NetConnection object
Рассмотрим еще один пример RTMP-пакета , посылаемого клиентом после handshake -
это результат работы флешового NetConnection.Connect :
03
00 00 01
00 01 05
14
00 00 00 00
02 00 07 63
...
03 - первый байт , в двоичной форме это выглядит так :
0000 0011 -> 0x03
первые 2 бита равны нулю - значит хидер равен 12 байтам
00 00 01 - следующие 3 байта всегда имеют место быть , когда мы имеем дело с видео/аудио данными
00 01 05 - следующие 3 байта указывают размер самих данных пакета : 256 + 5 = 261 байт
14 - этот байт указывает тип обьекта - function call
00 00 00 00 - NetStream обьект
02 00 07 63 - дальше идут сами данные в форме chunks по 128 байт , каждый последующий chunk
имеет свой однобайтный хидер - 0xc3
В случае, когда размер хидера равен 4 байтам, внутри пакета поле - длина - может присутствовать,
а может и нет, во втором случае размер пакета берется таким же, как у предыдущего пакета.
Рассмотрим случай, когда клиент посылает запрос CreateStream.
При этом происходит следующий диалог:
1.
Client -> Server : посылает CreateStream запрос.
2.
Server -> Client : посылает streamIndex число
3. Client -> Server : проверка publish
4.
Server -> Client : посылает аудио и видео-пакеты
RTMP protocol использует следующую разрядность при идентификации потока:
64-bit floats
32-bit little-endian integers
32-bit big-endian integers
Рассмотрим пример , когда имеются 4 порции аудио-данных по 32 байта каждая :
123 8 1000 32
123 8 1020 32
123 8 1040 32
123 8 1060 32
123 - это Message Stream ID
8 - это Message TYpe ID
В 3-м столбце стоит timestamp
В 4-м - размер данных.
Получаем четыре chank-а :
3 0 32 44
3 2 32 36
3 3 32 33
3 3 32 33
В 3-м столбце - размер данных , в 4-м - суммарный размер
В первом чанке в хидере будет полная информация - хидер будет размером в 11 байт :
delta: 1000
length: 32
type: 8
stream ID: 123
Во втором чанке хидер будет 3-байтовый - там будет delta=20
Начиная с 3-го чанка , хидер будет размером в 1 байт - в нем будет id потока и тип самого чанка : 3 и 3
Еще один пример - с видео-данными , имеется одна порция :
456 9 (video) 1000 307
Здесь идет разбиение на 3 чанка :
4 0 128 140
4 3 128 129
4 3 51 52
В первом чанке хидер будет 11-байтный
Начиная со второго - однобайтные .
|