• RTSP协议


    RTSP协议

    RTSP简述

    RTSP协议是一个基于文本的多媒体播放控制协议,属于应用层。它主要用来控制具有实时特性的数据的发送,但其本身并不用于传送流媒体数据,而必须依赖下层传输协议(如RTP/RTCP)所提供的服务来完成流媒体数据的传送。RTSP负责定义具体的控制信息、操作方法、状态码,以及描述与RTP之间的交互操作。

    RTSP的URL格式一般如下:

    rtsp://host{:port}/{abs_path}/content_name
    
    • host:有效的域名或IP地址;
    • port:端口号,缺省为554,若为缺省可不填写,否则必须写明。

    例如,一个完整的RTSP URL写为:

    rtsp://192.168.1.55:554/test
    

    RTSP报文

    RTSP是一种基于文本的协议,用CRLF(回车换行)作为每一行的结束符(类似http协议),其好处是,在使用过程中可以方便地增加自定义仓鼠,也方便抓包分析。从消息传送方向上来分,RTSP的报文有两类:请求报文和响应报文。请求报文是指从客户端项服务器发送的请求,响应报文是指从服务器到客户端的回应。

    RTSP请求报文的常用方法与作用:

    方法 描述
    OPTIONS 获得服务器支持的可用方法
    DESCRIBE 得到会话描述信息
    SETUP 客户端请求建立会话,并确立传输模式
    TEARDOWN 客户端发起关闭会话请求
    PLAY 客户端发起播放请求

    一次基本的RTSP交互过程如下,C表示客户端,S表示服务端。

    步骤 方向 信息 描述
    1 C->S OPTION request Client询问Server有哪些方法可用
    S->C OPTION response Server回应信息中包含所有可用的方法
    2 C->S DESCRIBE request Client请求得到Server提供的媒体初始化描述信息
    S->C DESCRIBE response Server回应媒体初始化信息,主要是SDP(会话描述协议)
    3 C->S SETUP request 设置会话属性以及传输模式,请求建立会话
    S->C SETUP response Server建议会话,返回会话标识符以及会话相关信息
    4 C->S PLAY request Client请求播放
    S->C PLAY response Server回应播放请求信息
    5 S->C Media Data Transfer 发送流媒体数据
    6 C->S TEARDOWN request Client请求关闭会话
    S->C TEARDOWN response Server回应关闭会话请求

    OPTIONS

    示例代码如下:

    static void Main(string[] args)
    {
        IPAddress iPAddress = IPAddress.Parse("172.20.124.156");
        IPEndPoint iPEndPoint = new IPEndPoint(iPAddress, 554);
        TcpClient tcpClient = new TcpClient();
        tcpClient.Connect(iPEndPoint);
        Thread thread = new Thread(Recv)
        {
            IsBackground = true,
        };
        thread.Start(tcpClient);
        const string CRLF = "
    ";
        string options = "OPTIONS rtsp://172.20.124.156:554/Stream RTSP/1.0" + CRLF;
        options += "CSeq: 1" + CRLF;
        options += CRLF;//切记这个一定要多发送一个CRLF,否则服务器一直等待这个结束符,而不返回信息
        byte[] bys = Encoding.UTF8.GetBytes(options);
        tcpClient.GetStream().Write(bys, 0, bys.Length);
        Console.ReadKey();
    }
    /// <summary>
    /// 接收
    /// </summary>
    /// <param name="sender"></param>
    private static void Recv(object sender)
    {
        TcpClient tcpClient = sender as TcpClient;
        NetworkStream networkStream = tcpClient.GetStream();
        StreamReader streamReader = new StreamReader(networkStream);
        while(tcpClient.Connected)
        {
            string line = streamReader.ReadLine();
            if(line == null)
            {
                break;
            }
            Console.WriteLine(line);
        }
        Console.WriteLine("连接断开了!");
    }
    

    服务端返回示例信息:

    RTSP/1.0 200 OK
    CSeq: 1
    Session: pcNoizrGg
    Public: DESCRIBE, SETUP, TEARDOWN, PLAY, PAUSE, OPTIONS, ANNOUNCE, RECORD
    

    DESCRIBE

    客户端向服务器请求媒体资源描述,服务器端通过SDP格式回应客户端的请求。资源描述中会列出所有请求媒体的媒体流及其相关信息,示例代码如下:

    static void Main(string[] args)
    {
        IPAddress iPAddress = IPAddress.Parse("172.20.124.156");
        IPEndPoint iPEndPoint = new IPEndPoint(iPAddress, 554);
        TcpClient tcpClient = new TcpClient();
        tcpClient.Connect(iPEndPoint);
        Thread thread = new Thread(Recv)
        {
            IsBackground = true,
        };
        thread.Start(tcpClient);
        const string CRLF = "
    ";
        string options = "OPTIONS rtsp://172.20.124.156:554/Stream RTSP/1.0" + CRLF;
        options += "CSeq: 1" + CRLF;
        options += CRLF;//切记这个一定要多发送一个CRLF,否则服务器一直等待这个结束符,而不返回信息
        byte[] bys = Encoding.UTF8.GetBytes(options);
        tcpClient.GetStream().Write(bys, 0, bys.Length);
        Thread.Sleep(1000);
        //请求媒体资源描述
        string describe = "DESCRIBE rtsp://172.20.124.156:554/Stream RTSP/1.0" + CRLF;
        describe += "CSeq: 2" + CRLF;
        describe += CRLF;
        bys = Encoding.UTF8.GetBytes(describe);
        tcpClient.GetStream().Write(bys, 0, bys.Length);
        Console.ReadKey();
    }
    /// <summary>
    /// 接收
    /// </summary>
    /// <param name="sender"></param>
    private static void Recv(object sender)
    {
        TcpClient tcpClient = sender as TcpClient;
        NetworkStream networkStream = tcpClient.GetStream();
        StreamReader streamReader = new StreamReader(networkStream);
        while(tcpClient.Connected)
        {
            string line = streamReader.ReadLine();
            if(line == null)
            {
                break;
            }
            Console.WriteLine(line);
        }
        Console.WriteLine("连接断开了!");
    }
    

    服务器响应信息如下:

    RTSP/1.0 200 OK
    CSeq: 1
    Session: pqFLiz9Mg
    Public: DESCRIBE, SETUP, TEARDOWN, PLAY, PAUSE, OPTIONS, ANNOUNCE, RECORD
    
    RTSP/1.0 200 OK
    Session: pqFLiz9Mg
    Content-Length: 380
    CSeq: 2
    
    v=0
    o=- 0 0 IN IP4 127.0.0.1
    s=EasyDarwin
    i=EasyDarwin
    c=IN IP4 127.0.0.1
    t=0 0
    a=x-qt-text-nam:EasyDarwin
    a=x-qt-text-inf:EasyDarwin
    a=x-qt-text-cmt:source application::EasyDarwin
    a=x-qt-text-aut:
    a=x-qt-text-cpy:
    m=video 0 RTP/AVP 96
    a=rtpmap:96 H264/90000
    a=fmtp:96 packetization-mode=1;sprop-parameter-sets=,2QAH6y0AoAt0IAAAAMAgAAAHkeMGVA=
    a=control:streamid=0
    

    SETUP

    SETUP请求确定了具体的媒体流如何传输,该请求必须在PLAY请求之前发送。SETUP请求包含媒体流的URL和客户端用于接收RTP数据(audio or video)的端口以及接收RTCP数据(meta information)的端口。服务器端的回复通常包含客户端请求参数的确认,并会补充缺失的部分,比如服务器选择的发送端口。每一个媒体流在发送PLAY请求之前,都要首先通过SETUP请求来进行相应的配置。

    示例代码如下:

    static void Main(string[] args)
    {
        IPAddress iPAddress = IPAddress.Parse("172.20.124.156");
        IPEndPoint iPEndPoint = new IPEndPoint(iPAddress, 554);
        TcpClient tcpClient = new TcpClient();
        tcpClient.Connect(iPEndPoint);
        Thread thread = new Thread(Recv)
        {
            IsBackground = true,
        };
        thread.Start(tcpClient);
        const string CRLF = "
    ";
        string options = "OPTIONS rtsp://172.20.124.156:554/Stream RTSP/1.0" + CRLF;
        options += "CSeq: 1" + CRLF;
        options += CRLF;//切记这个一定要多发送一个CRLF,否则服务器一直等待这个结束符,而不返回信息
        byte[] bys = Encoding.UTF8.GetBytes(options);
        tcpClient.GetStream().Write(bys, 0, bys.Length);
        Thread.Sleep(1000);
        //请求媒体资源描述
        string describe = "DESCRIBE rtsp://172.20.124.156:554/Stream RTSP/1.0" + CRLF;
        describe += "CSeq: 2" + CRLF;
        describe += CRLF;
        bys = Encoding.UTF8.GetBytes(describe);
        tcpClient.GetStream().Write(bys, 0, bys.Length);
        Thread.Sleep(1000);
        //SETUP
        string setup = "SETUP rtsp://172.20.124.156:554/Stream RTSP/1.0" + CRLF;
        setup += "CSeq: 3" + CRLF;
        setup += "Transport: RTP/AVP;unicast;client__port=8000-9000" + CRLF;
        setup += CRLF;
        bys = Encoding.UTF8.GetBytes(setup);
        tcpClient.GetStream().Write(bys, 0, bys.Length);
    
        Console.ReadKey();
    }
    /// <summary>
    /// 接收
    /// </summary>
    /// <param name="sender"></param>
    private static void Recv(object sender)
    {
        TcpClient tcpClient = sender as TcpClient;
        NetworkStream networkStream = tcpClient.GetStream();
        StreamReader streamReader = new StreamReader(networkStream);
        while(tcpClient.Connected)
        {
            string line = streamReader.ReadLine();
            if(line == null)
            {
                break;
            }
            Console.WriteLine(line);
        }
        Console.WriteLine("连接断开了!");
    }
    

    服务器返回信息:

    RTSP/1.0 200 OK
    CSeq: 1
    Session: 9R52ZzrGg
    Public: DESCRIBE, SETUP, TEARDOWN, PLAY, PAUSE, OPTIONS, ANNOUNCE, RECORD
    
    RTSP/1.0 200 OK
    Content-Length: 380
    CSeq: 2
    Session: 9R52ZzrGg
    
    v=0
    o=- 0 0 IN IP4 127.0.0.1
    s=EasyDarwin
    i=EasyDarwin
    c=IN IP4 127.0.0.1
    t=0 0
    a=x-qt-text-nam:EasyDarwin
    a=x-qt-text-inf:EasyDarwin
    a=x-qt-text-cmt:source application::EasyDarwin
    a=x-qt-text-aut:
    a=x-qt-text-cpy:
    m=video 0 RTP/AVP 96
    a=rtpmap:96 H264/90000
    a=fmtp:96 packetization-mode=1;sprop-parameter-sets=,2QAH6y0AoAt0IAAAAMAgAAAHkeMGVA=
    a=control:streamid=0
    
    RTSP/1.0 200 OK
    CSeq: 3
    Session: 9R52ZzrGg
    Transport: RTP/AVP;unicast;client__port=8000-9000
    

    PLAY

    客户端通过PLAY请求来播放一个或全部媒体流,PLAY请求可以发送一次或多次,发送一次时,URL为包含所有媒体流的地址,发送多次时,每一次请求携带的URL只包含一个响应的媒体流。PLAY请求中可指定播放的range,若未指定,则从媒体流的开始播放到结束,如果媒体流在播放过程中被暂停,则可在暂停处重新启动流的播放。

    播放示例代码为:

    string play = "PLAY rtsp://172.20.124.156:554/Stream RTSP/1.0" + CRLF;
    play += "CSeq: 4" + CRLF;
    play += CRLF;
    

    PAUSE

    PAUSE请求会暂停一个或所有媒体流,后续可通过PLAY请求恢复播放。PAUSE请求中携带所请求媒体流的URL,若参数range存在,则指明在何处暂停,若该参数不存在,则暂停立即生效,切暂停时长不确定。

    暂停示例代码:

    string pause = "PAUSE rtsp://172.20.124.156:554/Stream RTSP/1.0" + CRLF;
    pause += "CSeq: 5" + CRLF;
    pause += $"Session: {session}" + CRLF;
    pause += CRLF;
    

    TEARDOWN

    结束会话请求,该请求会停止所有媒体流,并释放服务器上的相关会话数据。

    string teardown = "TEARDOWN rtsp://172.20.124.156:554/Stream RTSP/1.0" + CRLF;
    teardown += "CSeq: 8" + CRLF;
    teardown += $"Session: {session}" + CRLF;
    teardown += CRLF;
    
  • 相关阅读:
    vscode clang-format
    MyBatis中比较(大于、小于)符号的转义写法
    byte数组(byte[])与MultipartFile相互转化
    IDEA报错 Error:(24, 35) java: 常量字符串过长
    Nginx中配置反向代理的proxy_pass的不同斜杠的区别
    使用docker-compose一起安装kafka(zookeeper)
    docker启动报错:Failed to Setup IP tables: Unable to enable SKIP DNAT rule
    Xftp设置指定记事本(notepad++)打开文件
    Linux使用docker安装Nginx
    使用openssl生成证书,并通过Nginx配置
  • 原文地址:https://www.cnblogs.com/zzr-stdio/p/14693409.html
Copyright © 2020-2023  润新知