1
<?xml version="1.0" encoding="utf-8"?>
3
<title>RTMP Protocol</title>
6
This document is based mostly on my own reverse engineering of the
7
RTMP protocol and AMF format. <emphasis>tcpdump</emphasis> and
8
<emphasis>ethereal</emphasis> are your friend. Some additional info that got
9
me started was from the <ulink type="http"
10
url="http://www.osflash.org/red5">Red5</ulink>
11
project. <emphasis>Red5</emphasis> is the only other open source SWF
12
server. So some details are still vague, but as the implementation
13
appears to work, we'll figure out what they are later.
17
The Real Time Messaging Protocol was created by MacroMedia (now
18
Adobe) for delivering SWF objects and video over a network
19
connection. Currently the only servers which support this format
20
are the MacroMedia Media sever, and the Open Source Red5 project.
24
This is a simple protocol, optimized for poor bandwidth
25
connections. It can support up to 64 concurrent streams over the
26
same network connection. Part of each AMF packet header contains
27
the index number of the stream. A single RTMP message can contain
32
An RTMP connection uses Tcp/ip port 1935. It is also possible to
33
tunnel RTMP over an HTTP connection using port 80. Each AMF packet
34
is 128 bytes long except for streaming audio, which has 64 byte
39
The basics of the RTMP protocol are as follows. All communications
40
are initiated by the client.
43
<imagedata align="center" fileref="images/rtmp.png"/>
49
The client starts the RTMP connection by sending a single byte
50
with a value of 0x3. This byte is followed by a data block of 1536
51
bytes. The format if this data block is unknown, but it appears to
52
not be actually used by the protocol except as a handshake.
56
The server receives this packet, stores the 1536 byte data block,
57
and then send a single byte with the value of 0x3, followed by two
58
1536 data blocks. The second data block is the full contents of
59
the original data block as sent by the client.
63
The client receives the 1536 byte data block, and if they match,
64
the connection is established. After the handshake process is
65
done, there are three other messages that the client sends to the
66
sever to start the data flowing.
70
The first AMF packet sent to the server contains the
71
<emphasis>connect</emphasis> packet. This doesn't appear to do
72
much but notify the server the client is happy with the
73
handshake, and ready to start reading packets.
77
The second packet is the <emphasis>NetConnection</emphasis> object from
78
the client. This ActionScript class is used by the SWF movie to
79
create the network connection to the server.
83
The third packet is the <emphasis>NetStream</emphasis> object from the
84
client. This is the ActionScript class used to specify the file to
85
be streamed by the server.
89
The RTMP packet for our example looks like this:
92
030000190000c91400000000020007connect00?f0000000000000030003app0200#
93
software/gnash/tests/1153948634.flv0008flashVer02000cLNX 6,0,82,0 0006
94
swfUrl02001dfile:///file|%2Ftmp%2Fout.swfc30005tcUrl\002\0004
95
rtmp://localhost/software/gnash/tests/1153948634.flv\000\000\t
99
We'll take this apart in a bit, but you can see how all three AMF
100
packets are in the same message. The message is received in
101
several 128 byte blocks, with the last one being less than
102
that. The total size of the RTMP message is in the header, so the
103
reader can tell if the entire message was read or not.
107
The RTMP header is first, followed by the connect message as an
108
ASCII string as the message body. The following AMF packet is the
109
<emphasis>NetConnection</emphasis> one, which specifies that this is coming
110
from a SWF application. This also contains the file path the server
111
can use to find the file to stream. This is then followed by the
112
version number, which I assume is the version of the SWF player,
113
so the server knows what it is talking to.
117
The third packet is the one from <emphasis>NetStream</emphasis>, which
118
specifies the URL used for the movie, followed by the user name
119
for a semblance of security.
123
For the next level of detail, we'll explain the format of AMF. AMF
124
is used by the RTMP protocol to transfer data. Each SWF object
125
is encapsulated in an AMF packet, including streaming audio or
130
The first byte of the RTMP header determines two things about the
131
rest of the message. The first 2 bits of this byte signify the
132
total size of the RTMP header. The RTMP header is of a variable
133
size, so this is important.
140
This specifies the header contains 12 bytes, including
149
This specifies the header contains 8 bytes, including this
158
This specifies the header contains 4 bytes, including this
167
This specifies the header contains 1 byte, so this is the
176
The other 6 bits in this byte represent the AMF index. As a single
177
RTMP connection can support multiple data streams, this signifies
178
which stream this packet is for. Once an AMF object is fully
179
received by the client, the AMF index may be reused.
183
For messages with headers of at least 4 bytes, the next 3 bytes are
184
used by audio and video data packets, but at this time the meaning
185
of this field is unknown.
189
For messages with a 8 byte or larger header, the next 3 bytes
190
determine the size of the RTMP message being transmitted. Messages
191
with a 1 byte or 4 byte header use a standard size, 128 bytes for
192
video, and 64 bytes for audio.
196
For messages with an 8 byte or larger header, the next byte is the
197
type of the AMF object.
204
This specifies the content type of the RTMP packet is the
205
number of bytes read. This is used to start the RTMP
214
This specifies the content type of the RTMP message is a
215
<emphasis>ping</emphasis> packet.
223
This specifies the content type of the RTMP message is
224
server response of some type.
232
This specifies the content type of the RTMP packet is
233
client request of some type.
241
This specifies the content type of the RTMP packet is an
250
This specifies the content type of the RTMP message is a
259
This specifies the content type of the RTMP message is
268
This specifies the content type of the RTMP message is
277
This specifies the content type of the RTMP message is
278
remote procedure call. This invokes the method of a SWF
288
There are two sets of data types to consider. One set is used by
289
the to specify the content type of the AMF object, the other is an
290
ActionScript data type tag used to denote which type of object is
295
The values of the initial type byte are:
302
This specifies the data in the AMF packet is a numeric
303
value. All numeric values in SWF are 64 bit,
304
<emphasis>big-endian</emphasis>.
313
This specifies the data in the AMF packet is a boolean
323
This specifies the data in the AMF packet is an
324
<emphasis>ASCII</emphasis> string.
333
This specifies the data in the AMF packet is a SWF
334
object. The SWF object data type field further along in
335
the message specifies which type of ActionScript object it
345
This specifies the data in the AMF packet is a SWF
346
movie, ie. another SWF movie.
355
This specifies the data in the AMF packet is a NULL
356
value. NULL is often used as the return code from calling
366
This specifies the data in the AMF packet is a
367
undefined. This is also used as the return code from
368
calling SWF functions.
377
This specifies the data in the AMF packet is a reference.
386
This specifies the data in the AMF packet is a ECMA
396
This specifies the data in the AMF packet is the end of an
397
object definition. As an object is transmitted with
398
multiple AMF packets, this lets the server know when the
399
end of the object is reached.
409
This specifies the data in the AMF packet is a Strict
419
This specifies the data in the AMF packet is a date.
428
This specifies the data in the AMF packet is a multi-byte
429
string. Multi-byte strings are used for international
430
language support to represent non <emphasis>ASCII</emphasis>
440
This specifies the data in the AMF packet is a an
450
This specifies the data in the AMF packet is a record
460
This specifies the data in the AMF packet is a AML
461
object. XML objects are then parsed by the
462
<emphasis>XML</emphasis> ActionScript class.
471
This specifies the data in the AMF packet is a typed object.
481
For messages with a 12 byte header, the last 4 bytes are the
482
routing of the message. If the destination is the server, this
483
value is the NetStream object source. If the destination is the
484
client, this is the NetStream object for this RTMP message. A
485
value of 0x00000000 appears to be reserved for the NetConnection
490
Multiple AMF streams can be contained in a single RTMP messages,
491
so it's important to check the index of each AMF packet.
495
An example RTMP header might look like this. (spaces added between
496
fields for clarity) All the numbers are in hex.
499
03 000019 0000c9 14 000000000
507
The first two bits of this byte are the size of the
508
header, which in this example is 00, for a 12 byte
509
header. The next 6 bits is the AMF stream index number,
510
which in this example is 0x3.
519
These 3 bytes currently have an unknown purpose.
528
Since this example has a 12 byte header, this is the size
529
of the RTMP message, in this case 201 bytes.
538
This is the content type of the RTMP message, which in
539
this case is to invoke a remote function call. (which we
540
later see is the connect function).
546
<term>00000000</term>
549
The source is the NetConnection object used to start this