# rtsp_proxy_server **Repository Path**: learnhow/rtsp_proxy_server ## Basic Information - **Project Name**: rtsp_proxy_server - **Description**: rtsp代理转发服务可以实现基于rtsp的协商和rtp、rtcp端口动态代理转发。基于libevent开发,并实现了负载均衡配置。 - **Primary Language**: C++ - **License**: MIT - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 9 - **Forks**: 9 - **Created**: 2020-07-21 - **Last Updated**: 2024-12-17 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # RTPS代理与转发服务 #### Proxy介绍 利用libevent实现网络连接和线程池。通过tcp连接的方式实现rtsp消息转发,再通过udp连接进行rtp与rtcp转发。报文解析使用到了Qt库。请尽量使用qmake进行编译。 #### 通讯时序图 ![时序图](https://images.gitee.com/uploads/images/2020/0726/131004_84166d18_1020354.png "视频分发服务(media_server)开发流程图.png") #### RTSP协议介绍 RTSP协议是一套用来进行音视频发送与接收的网络协议,与HTTP协议不同。它包含了一套tcp连接和两套udp连接。通过对协议的实测,大致的交互流程如下: 1. 服务端监听tcp连接:默认的连接端口是554,如果你希望实现自己的rtsp服务也可以自定义。 2. 客户端连接后需要根据固定的顺序完成握手:OPTIONS、DESCRIBE、SETUP、PLAY和TEARDOWN。除此以外的其它请求都为可选。 3. 服务端的返回值最常见的是200和403。如果返回200则表示请求通过,403表示需要验证验证权限。 4. 在客户端发送SETUP请求的报文中需要包含client_port=xxxx-xxxx的信息,通常是相邻的两个端口号,前一个是偶数端口用来接收rtp音视频报文,后一个端口是奇数端口用来发送rtcp同步报文。 5. 服务端收的应答中会包含server_port=xxxx-xxxx的信息,也是两个相邻端口号。偶数为rtp发送端口,奇数为rtcp接收端口。 6. 最后等待客户端发送PLAY请求,双方开始启用udp通信,tcp连接保持。海康的硬盘录像机除可以使用rtsp协议获取直播流以外还能获取录像流。当客户端与服务器建立完成连接后,客户端通过重新发送PLAY请求动态调整录像的播放速率。服务器调整播放速度其实只是调整了rtp端口的报文发送速度而已,具体解码播放还是要播放器来实现。 #### Proxy做了哪些工作 通过tcp连接,proxy接受客户端的连接后会向服务器发起连接,并将服务器的rtsp报文转发回客户端处理。因此握手与校验的工作依然需要由客户端来完成。 当proxy接收到来自客户端的SETUP请求后会将client_port=xxxx-xxxx的报文替换成自己的代理端口。服务器返回的server_port=xxxx-xxxx报文也会被替换。proxy内部会将这4个udp端口两两配对,两个偶数端口组成一个rtp管线负责向下转发,两个奇数端口组成rtcp管线负责向上转发。这两条管线(UdpPipe)我们称为StreamTask,会分配给一个线程(StreamThread)运行。线程来自一个用libevent实现的线程池(ThreadPool)。每当有一个StreamTask被创建的时候,proxy会从线程池中找一条负载最小的线程来分配任务。会在客户端连接断开后从线程池释放。 ![udp管线](https://images.gitee.com/uploads/images/2020/0726/130847_d9b21211_1020354.png "UDP管线转发图.png") #### Proxy的下一个版本 目前还不能确定proxy是否会有下一个版本的更新。如果有精力维护它,在下一个版本中我会实现以下功能: 1. 增加一个播放器的代理功能,使得真正的客户端可以只通过tcp连接来直接获取rtp流。 2. 增加一个本地录像功能,解析rtp报文并分离出h264裸流后转储到硬盘上。