zoukankan      html  css  js  c++  java
  • 自己写RTPserver——大约RTP协议

    自己写RTPserver——大约RTP协议


    本文将带领你一步一步地实现一个简单的手RTP变速器server,旨在了解RTP流媒体传输协议以及有关多媒体编解码器的一些知识。


    RTP协议的必备知识

    要动手实现一个协议,当然首先须要阅读该协议的文档。

    RTP协议的文档,有rfc1889、rfc1890、rfc3550。当中rfc3550是如今的版本号,另外两个是过期版。这个协议能够在ietf的官网找到:http://tools.ietf.org/html/rfc3550

    RTP packet

    RTP是基于UDP协议的。RTPserver会通过UDP协议,通常每次会发送一个RTP packet。

    client通过解析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


    以上的一些概念是一些要实现RTPserver所必备的知识。介绍的很简略,具体的定义还是要參考rfc3550原文。

    动手实践

    我们既然已经知道了RTP packet的结构,那么我们曾经用到的RTP流是否也是这种结构呢?怎样验证呢?接下来。我们就一步步验证RTP流的结构。

    我们知道RTP是基于UDP协议的,那么我们就先做一个简单的UDP接受端,看看我们能够从RTPserver接受到什么信息。

    要实现这个接受端。你须要有一定的网络编程经验,至于详细到操作系统、编程环境、开发语言等都不限制。为了简单,我这里用python给出一个小小的样例程序。

    import socket
    
    # Build a socket to receive data from RTP server.
    # Here we use SOCK_DGRAM, because RTP is on UDP.
    sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    sock.bind(("localhost", 6666))
    
    for i in range(5):
            # We just get 16 bytes to analyze the RTP Header.
            buf = sock.recv(16)
    
            # Output the result in octal.
            for c in buf:
                    print "%x" % ord(c),
            print
    
    sock.close()
    

    这就是接受程序啦,很短小,并且有简单凝视,这里就不解释了。

    接受端已经做好了。那么去哪里找RTPserver作发送端呢?你能够用一些搭建流媒体server的工具。我这里选用的是强大的VLC。关于VLC搭建流媒体server的方法,请參考我前面的文章基于移动平台的多媒体框架——用VLC搭建简单的流媒体server。这里须要注意几个配置的地方。一是选择Destination的时候要选择RTP而不要选择RTSP,然后地址能够填写本机ip地址或直接写localhost,port号填写的要和接受端一致,这里是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详细数据流,并没有意识到RTPserver直接的帮助。但协议本身可以让你变得更熟悉和编程环境,也便于调试后,执行过程。不管你意识到什么环境什么语言,强烈建议写一个小程序,。

  • 相关阅读:
    Php ArrayIterator的几个常用方法
    13 子元素和后代元素选择器 1 元素之间的关系 2 后代元素选择器 后代 元素用的是空格 3 子元素选择器 用的是>号 4 ietest的使用
    12常用选择器 1元素选择器 2 id选择器3 class类选择器 4 一个元素可以设置多个class属性值 5 选择器分组又叫并集选择器 6 通配选择器 * 7 复合选择器 交集选择器
    11 1 块元素div的定义 2 常见的块元素 3 块元素的用途 4 内联元素,行内元素,span 5 内联元素和块元素的用途 6 a元素超链接的用法 7 p元素不可以包含任何其他的块元素
    10 1、IDE,dreamweaver,webstorm,hbuilder 2 Hbuilder快捷键
    9 1 css的注释 2 css的语法:选择器,声明块
    8 1 css 2 元素就是标签 2 内联样式 3 css选择器 style ,head ,内部样式表 4 外部样式表 css文件, link标签 ,href,
    7 1 超链接 a标签 href ,_self,_blank 2 center标签 居中显示 3 # 4 回到顶部 5 id定位 6 电子邮件超链接
    5 1 html的语法规范 大小写,注释嵌套,标签成对出现,属性,值,加引号
    4 1meta标签,name ,content,keywords,description,url,refresh
  • 原文地址:https://www.cnblogs.com/mengfanrong/p/4573281.html
Copyright © 2011-2022 走看看