【问题标题】:Grabbing video with RTSP over TCP通过 TCP 使用 RTSP 抓取视频
【发布时间】:2012-08-24 13:37:34
【问题描述】:

我想从具有 RTSP 的设备中检索一些视频数据。

RTSP over UDP 运行良好,但我需要它通过 TCP。

发出 RTSP 命令后,我收到了 RTP,但我不知道如何在此处处理它们。 有效载荷如下:$[channel - 1 byte][length - 2bytes][data]

问题是我收到了这样的数据包,有时还会收到更多的数据包,其中通道是 10 或 99 等。

那么任何人都可以就如何处理有效载荷提供一些意见吗?

【问题讨论】:

    标签: tcp h.264 rtsp rtp


    【解决方案1】:

    RFC 2326 "Real Time Streaming Protocol (RTSP)" 拥有一切。你需要“10.12 Embedded (Interleaved) Binary Data”:

    RTP数据包等流数据用ASCII美元符号(24位十六进制)封装,后跟一字节通道标识符,后跟封装二进制数据的长度为二进制,网络字节中的二字节整数命令。流数据紧随其后,没有 CRLF,但包括上层协议头。每个$块正好包含一个上层协议数据单元,例如一个RTP包。

    还有一个小例子:

     S->C: $\000{2 byte length}{"length" bytes data, w/RTP header}
     S->C: $\000{2 byte length}{"length" bytes data, w/RTP header}
     S->C: $\001{2 byte length}{"length" bytes  RTCP packet}
    

    【讨论】:

    • 那是我所遵循的确切文件;但我没有发现足够的数据。此外,我使用 Wireshark 检查了输入并看到了这条消息:[Malformed Packet: RTP]。我是否应该连接 RTP 的所有有效负载,直到收到另一个有效负载,如您描述的前两行?此外,有效负载非常大,而数据长度仅为 22 个字节。在这种情况下,我可以从哪里获取 PPS 和 SPS?
    • 它应该与您通过 UDP 接收的数据基本相同。
    【解决方案2】:

    获取 PPS 很简单,不需要解析数据包。

    我猜您对 SPS 的请求将需要进入数据包(我认为您无需担心 WS msg 'invalid packet'。

    在 0x09 的 PT 处使用 Type 怎么样?

    请参阅here 了解数据包说明

    答案here中解包RTP的示例实现

    尝试查看here 以获取有关 RTSP 控制和基于 TCP 的 SDP 的更多信息。如果您要检查 RTSP 会话/对话的详细信息以及有关视频中各个轨道的控制协议选择的消息传递详细信息。如果您可以在不转移到 SDP / RTCP 的情况下获得答案,那么显然,那会更快/更好。

    【讨论】:

      【解决方案3】:

      这是 TCP/RTP 的数据包格式:

      [$ - 1byte][Transport Channel - 1byte][RTP data length - 2bytes][RTP data]
      

      剩下的跟upd一样

      更多信息请阅读process raw rtp packets

      【讨论】:

        【解决方案4】:

        解释一下,我也在为此工作,如果你想通过 TCP 使用 RTSP,请注意你的套接字读取代码。 合适的socket流程如下:

        while (socket.connected) {
          char magic = socket.read a char;
          if (magic == '$') {  // is a RTP over TCP packet
             byte channel = socket.read 1 byte;
             unsigned short len = socket.read 2 byte; // len = ((byte1 & 0xFF) << 8) + (byte2 &0xFF);
             int readTotal = 0;
             byte rtpPacket[len];
             while (readTotal < len) {
                 // read remaing bytes to rtpPacket from index readTotal
                 int r = socket.read(rtpPacket, readTotal, len - readTotal); 
                 if (r > 0)
                    readTotal += r;
                 else    // -1 means socket read error
                    break;   
             }
             // now we get full RTP packet, process it!
             call back channel, rtpPacket;
          } else {  // is RTSP protocol response
             string array header;
             while (line = socket.readline() != null) {
                if (line == "") {
                   int body_len = Parse header "Content-Length";
                   byte body[body_len];
                   int readBody = 0;
                   while (readBody < body_len) {
                      int r = socket.read(body, readBody, body_len - readBody);
                      if (r>0)
                        readBody += r;
                      else
                        break;
                   }
        
                   // Now we get full header, body of RTSP response, process it
                   Callback header, body;   
                } else {
                   header.add(line);
                }
             }
          }
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-05-05
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2019-08-02
          相关资源
          最近更新 更多