RTSP传输协议之URL格式及URL解析

1、URL格式介绍

“rtsp”和“rtspu”表示要通过 RTSP 协议来定位网络资源。 RTSP URL 的语法和语义如下所示:

rtsp_URL =  "rtsp:" | "rtspu:" ) "//" host [ ":" port ] [ abs_path ]

host  = <合法的 Internet 主机域名或 IP 地址(用十进制数及点组成),如 192.168.0.64

port  = *DIGIT

abs_path 的定义如下所示:

abs_path = "/" rel_path

rel_path = [ path ] [ ";" params ] [ "?" query ]

path = fsegment *( "/" segment )

fsegment = 1*pchar

segment = *pchar

params = param *( ";" param )

param = *( pchar | "/" )

scheme = 1*( ALPHA | DIGIT | "+" | "-" | "." )

net_loc = *( pchar | ";" | "?" )

query = *( uchar | reserved )

fragment = *( uchar | reserved )

pchar = uchar | ":" | "@" | "&" | "=" | "+"

uchar = unreserved | escape

unreserved = ALPHA | DIGIT | safe | extra | national

escape = "%" HEX HEX

reserved = ";" | "/" | "?" | ":" | "@" | "&" | "=" | "+"

extra = "!" | "*" | "'" | "(" | ")" | ","

safe = "$" | "-" | "_" | "."

unsafe = CTL | SP | <"> | "#" | "%" | "<" | ">"

national = <any OCTET excluding ALPHA, DIGIT,

reserved, extra, safe, and unsafe>

权威的 URL 语法及语义信息请参见 RFC1738[4]和 RFC1808[9]。

[注意]:段(fragment)和询问(query)标识符在这时没有明确的定义,需要到 RTSP服务器上解释。

rtsp 要求使用可靠协议(Internet 的 TCP 协议)发出命令,而 rtspu 则使用不可靠协议(Internet 的 UDP 协议)。如果端口为空或没指定,则缺省为 80 端口。对于rtsp_URI 来说,拥有被请求的资源的服务器主机通过侦听该端口的 TCP 连接(rtsp)或 UDP 包(rtspu)来接收该 URI 请求。只要可能,应尽量避免的在 URL 中直接使用IP 地址。(请参考 RFC1924)文本媒体标识符使用 URL 中的字符集及转义规则(参考RFC1738)来标识一个表示(presentation)与单个流(stream)。URL 可以用于单个流或者多个流的集合,比如表示(presentation)。因此,请求(request)可以用于整个表示(presentation)或表示中的单个流。注意,有些请求方法仅能用于流而不能用于表示,反之亦然。

例如:RTSP URL:rtsp://media.example.com:554/twister/audiotrack

标识了 twister 表示(presentation)中,可以通过 media.example.com554 端口的 TCP 连接发送 RTSP 请求来控制的音频流。

也可以是这样 RTSP URL:rtsp://media.example.com:554/twister

标识了由音频和视频流组成的 twister 表示(presentation)。

这并没有给出 URL 中相关流的标准方法。表示描述定义了表示中的层次关系以及单独流的 URL。如一个表示描述可能将一个流命名为 a.mov,而将整个表示命名为 b.mov。RTSP URL 的路径组成对客户端来说不可见并且也并没有给出服务器的具体文件系统结构。

只需进行简单替换后,表示描述同样可以用于非 RTSP 媒体控制协议。

2、URL解析

下面的代码示例用于解析RTSP的URL,以获得有用的信息。代码为本人自己实现,可能会存在一些问题,望指正。代码中用到了几个字符串处理换函数,如strchr()、strncpy()、strtoul()等。

URL解析代码示例:

static int parsingRTSPURL(char const* url, char* username, char* password, char* address,int* portNum, char* path) 
{
    // Parse the URL as "rtsp://[<username>[:<password>]@]<server-address-or-name>[:<port>][/<path>]"
    uint32_t const prefixLength = 7;
    char const* from = &url[prefixLength];	
    char const* tmpPos;

    if ((tmpPos = strchr(from, '@')) != NULL) {
	// We found <username> (and perhaps <password>).
        char const* usernameStart = from;
        char const* passwordStart = NULL;
        char const* p = tmpPos;

        if ((tmpPos = strchr(from, ':')) != NULL && tmpPos < p) {
            passwordStart = tmpPos;
            uint32_t passwordLen = p - passwordStart;
            strncpy(password, passwordStart, passwordLen);
            password[passwordLen] = '\0'; //Set the ending character.
        }
            
        uint32_t usernameLen = 0;
        if (passwordStart != NULL) {
            usernameLen = tmpPos - usernameStart;
        } else {
            usernameLen = p - usernameStart;    
        }		
        strncpy(username, usernameStart, usernameLen);
        username[usernameLen] = '\0';  //Set the ending character.

        from = p + 1; // skip the '@'
    }

    const char* pathStart = NULL;
    if ((tmpPos = strchr(from, '/')) != NULL) {
        uint32_t pathLen = strlen(tmpPos + 1);  //Skip '/'
        strncpy(path, tmpPos + 1, pathLen + 1);
        pathStart = tmpPos;
    }

    // Next, will parse the address and port.
    tmpPos = strchr(from, ':');
    if (tmpPos == NULL) {
        if (pathStart == NULL) {
            uint32_t addressLen = strlen(from);
            strncpy(address, from, addressLen + 1);  //Already include '\0'
        } else {
            uint32_t addressLen = pathStart - from;
            strncpy(address, from, addressLen);
            address[addressLen] = '\0';   //Set the ending character.
        }
        *portNum = 554; // Has not the specified port, and will use the default value
    } else if (tmpPos != NULL) {
        uint32_t addressLen = tmpPos - from;
        strncpy(address, from, addressLen);
        address[addressLen] = '\0';  //Set the ending character.
        *portNum = strtoul(tmpPos + 1, NULL, 10); 
    }
    return 1;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值