<menu id="w8yyk"><menu id="w8yyk"></menu></menu>
  • <dd id="w8yyk"><nav id="w8yyk"></nav></dd>
    <menu id="w8yyk"></menu>
    <menu id="w8yyk"><code id="w8yyk"></code></menu>
    <menu id="w8yyk"></menu>
    <xmp id="w8yyk">
    <xmp id="w8yyk"><nav id="w8yyk"></nav>
  • 網站首頁 > 物聯資訊 > 技術分享

    自己動手寫RTP服務器――關于RTP協議

    2016-09-28 00:00:00 廣州睿豐德信息科技有限公司 閱讀
    睿豐德科技 專注RFID識別技術和條碼識別技術與管理軟件的集成項目。質量追溯系統、MES系統、金蝶與條碼系統對接、用友與條碼系統對接

    本文會帶領著你一步步動手實現一個簡單的RTP傳輸服務器,旨在了解RTP流媒體傳輸協議以及一些關于多媒體編解碼的知識。

     

    關于RTP協議的必備知識

    要動手實現一個協議,當然首先需要閱讀該協議的文檔。RTP協議的文檔,有rfc1889、rfc1890、rfc3550,其中rfc3550是現在的版本,另外兩個是過期版。這個協議可以在ietf的官網找到:http://tools.ietf.org/html/rfc3550

    RTP packet

    RTP是基于UDP協議的,RTP服務器會通過UDP協議,通常每次會發送一個RTP packet。客戶端通過解析RTP packet,讀取其中的數據然后進行播放了。

    RTP packet的結構如下:

    1. RTP Header:RTP 包的頭部
    2. contributing sources:個數為0-n個,所以可以為空。具體定義參考rfc3550
    3. RTP payload:即RTP要傳輸的數據

    RTP Header

    這是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的個數

    M(marker): 1 bit,具體這位的定義會在一個profile里

    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給出一個小小的例子程序。

     

    [python] view plaincopy在CODE上查看代碼片派生到我的代碼片  
    1. import socket  
    2.   
    3. # Build a socket to receive data from RTP server.  
    4. # Here we use SOCK_DGRAM, because RTP is on UDP.  
    5. sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)  
    6. sock.bind(("localhost", 6666))  
    7.   
    8. for i in range(5):  
    9.         # We just get 16 bytes to analyze the RTP Header.  
    10.         buf = sock.recv(16)  
    11.   
    12.         # Output the result in octal.  
    13.         for c in buf:  
    14.                 print "%x" % ord(c),  
    15.         print  
    16.   
    17. sock.close()  


    這就是接受程序啦,非常短小,而且有簡單注釋,這里就不解釋了。

     

    接受端已經做好了,那么去哪里找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服務器有直接幫助。但是可以讓你對協議本身以及編程環境更加熟悉,也方便了以后實現過程中進行調試。不論你在什么環境用什么語言實現,都強烈建議寫一個這樣的小程序。

    RFID管理系統集成商 RFID中間件 條碼系統中間層 物聯網軟件集成
    最近免费观看高清韩国日本大全