本文會帶領着你一步步動手實現一個簡單的RTP傳輸服務器,旨在瞭解RTP流媒體傳輸協議以及一些關於多媒體編解碼的知識。html
RTP packet的結構以下:python
這是RTP流的頭部,在網上搜索RTP格式,就會搜到不少文章介紹這個頭部的定義。咱們這裏參考rfc3550的定義,在5.1節(http://tools.ietf.org/html/rfc3550#section-5.1)。算法
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|V=2|P|X| CC |M| PT | sequence number |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| timestamp |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| synchronization source (SSRC) identifier |
+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
| contributing source (CSRC) identifiers |
| .... |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+編程
每行是32 bits,由此能夠直觀看到每一個表示部分所佔的位數。簡單介紹一下:小程序
V(version):2 bits,RTP的版本,這裏統一爲2服務器
P(padding):1 bit,若是置1,在packet的末尾被填充,填充有時是方便一些針對固定長度的算法的封裝網絡
X(extension):1 bit,若是置1,在RTP Header會跟着一個header extension框架
CC(CSRC count): 4 bits,表示頭部後contributing sources的個數socket
M(marker): 1 bit,具體這位的定義會在一個profile裏ide
PT(playload type): 7 bits,表示所傳輸的多媒體的類型,對應的編號在另外一份文檔rfc3551中有列出(http://tools.ietf.org/html/rfc3551)
sequence number: 16 bits,每一個RTP packet的sequence number會自動加一,以便接收端檢測丟包狀況
timestamp: 32 bits,時間戳
SSRC: 32 bits,同步源的id,沒兩個同步源的id不能相同
CSRC: 上文說到,個數由CC指定,範圍是0-15
以上的一些概念是一些要實現RTP服務器所必備的知識。介紹的很是簡略,詳細的定義仍是要參考rfc3550原文。
咱們既然已經知道了RTP packet的結構,那麼咱們之前用到的RTP流是否也是這樣的結構呢?如何驗證呢?接下來,咱們就一步步驗證RTP流的結構。
咱們知道RTP是基於UDP協議的,那麼咱們就先作一個簡單的UDP接受端,看看咱們能夠從RTP服務器接受到什麼信息。要實現這個接受端,你須要 有必定的網絡編程經驗,至於具體到操做系統、編程環境、開發語言等都不限制。爲了簡單,我這裏用python給出一個小小的例子程序。
接受端已經作好了,那麼去哪裏找RTP服務器做發送端呢?你能夠用一些搭建流媒體服務器的工具,我這裏選用的是強大的VLC。關於VLC搭建流媒體服務器的方法,請參考我前面的文章基於移動平臺的多媒體框架——用VLC搭建簡單的流媒體服務器。這裏須要注意幾個配置的地方,一是選擇Destination的時候要選擇RTP而不要選擇RTSP,而後地址能夠填寫本機ip地址或直接寫localhost,端口號填寫的要和接受端一致,這裏是6666。配置好以後的string應該相似於:
:sout=#rtp{dst=localhost,port=6666,mux=ts} :no-sout-rtp-sap :no-sout-standard-sap :ttl=1
服務端配置完成以後,開始Stream。這時打開接受端,就會接受到一些數據,我接收到的數據開頭是:
80 a1 20 43 8c cf 76 3c 93 59 d 74 47 0 44 10
80 a1 20 44 8c cf 79 4b 93 59 d 74 47 40 42 36
80 a1 20 45 8c cf 7d 36 93 59 d 74 47 0 44 1a
80 a1 20 46 8c cf 81 21 93 59 d 74 47 40 45 1a
80 a1 20 47 8c cf 85 c 93 59 d 74 47 0 45 1b
這是十六進制的表示。咱們依照上面的Header的格式對其進行解讀:
第一個byte 80 表示:
V(version)=2
P(padding)=0
X(extension)=0
CC(CSRC count)=0
第二個byte a1 表示:
M(marker)=1
PT(playload type)=33(對照rfc3551能夠發現,33表示MP2T AV,正是咱們用VLC Stream的格式類型)
後面的2bytes的sequence number咱們能夠直觀的看出是在加一,4bytes的timestamp也是在不斷遞增的。再以後的93 59 d 74就是SSRC id了,因爲CC爲0,因此沒有CCRC。再以後的幾位都是RTP所要傳輸的數據了。
對RTP協議的熟悉是實現它的基礎。這裏我只是作一個簡單的介紹,須要詳細瞭解,讀官方的文檔是必不可少的步驟。
經過寫一個小程序打印出RTP流中具體的數據,並無對實現RTP服務器有直接幫助。可是可讓你對協議自己以及編程環境更加熟悉,也方便了之後實現過程當中進行調試。不論你在什麼環境用什麼語言實現,都強烈建議寫一個這樣的小程序。