# rtp **Repository Path**: springborland/rtp ## Basic Information - **Project Name**: rtp - **Description**: Real-time Transport Protocol - **Primary Language**: Go - **License**: AGPL-3.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 1 - **Created**: 2026-09-07 - **Last Updated**: 2026-09-07 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # rtp #### 介绍 实时传输协议(Real-time Transport Protocol,RTP),用于在IP网络中传输实时音视频数据,广泛应用于实时通信、视频监控、直播、WebRTC等场景。本项目是纯Go语言实现的轻量级RTP/RTCP协议栈,严格遵循相关国际标准,无第三方依赖,可直接嵌入各类项目使用。 #### 特性 1. 协议完整性:完整实现RTP封包、解包、头部解析与合法性校验,支持RTCP SR(发送端报告)、RR(接收端报告)报文的构造与解析,满足实时传输控制需求; 2. 编码兼容性:内置标准音视频编码Payload Type(PT)映射表,涵盖PCMU、PCMA、G722、H264、H265、OPUS、AAC等主流编码,支持静态与动态PT类型校验; 3. 传输灵活性:同时支持UDP、TCP两种传输模式,提供完整的客户端与服务端实现,适配不同网络场景需求; 4. 会话自动化:内置RTP会话管理模块,自动生成随机SSRC、序列号与时间戳,严格遵循RFC标准的时间戳增长规则(按时钟率匀速增长); 5. 代码规范性:常量采用全大写下划线命名,见名知意,所有字段、方法、常量均带有详细注释,并标注RFC标准出处,便于二次开发与维护; 6. 轻量无依赖:纯Go语言实现,无任何第三方依赖,编译简单、部署便捷,可灵活嵌入各类Go项目。 #### 协议规范 本项目严格遵循以下国际标准,确保协议兼容性与规范性: 1. RFC 3550:RTP: A Transport Protocol for Real-Time Applications(RTP核心协议规范); 2. RFC 3551:RTP Profile for Audio and Video Conferences(音视频会议RTP配置文件,定义静态PT类型); 3. RFC 6184:RTP Payload Format for H.264 Video(H.264视频的RTP负载格式); 4. RFC 7798:RTP Payload Format for HEVC (H.265)(H.265视频的RTP负载格式); 5. RFC 7587:RTP Payload Format for the OPUS Speech and Audio Codec(OPUS编码的RTP负载格式)。 #### 软件架构 软件采用分层架构设计,模块职责清晰、低耦合,便于扩展与维护,整体架构分为4个核心模块,具体说明如下: 1. rtp模块:负责RTP协议核心实现,包含常量定义(PT类型、版本号等)、头部结构体、数据包封装与解析、合法性校验等功能,是整个协议栈的核心; 2. rtcp模块:负责RTCP控制协议实现,包含RTCP头部、SR/RR报文结构体、报文构造与解析,用于实时监控传输质量、同步音视频、统计传输数据; 3. transport模块:负责网络传输实现,分别提供UDP、TCP两种传输模式的客户端与服务端,封装发送、接收逻辑,对外提供统一的调用接口; 4. session模块:负责RTP会话管理,自动生成并维护SSRC、序列号、时间戳,按照RFC标准管理会话生命周期,简化上层调用; 5. example模块:提供8个完整的示例程序,涵盖RTP/RTCP、UDP/TCP、客户端/服务端的所有组合,便于开发者快速上手使用。 #### 项目结构说明 项目目录结构清晰,各模块独立划分,具体如下: ```shell . ├── go.mod # Go模块依赖配置 ├── README.md # 中文项目说明文档 ├── README.en.md # 英文项目说明文档 ├── LICENSE # MIT许可证文件 ├── rtp/ # RTP协议核心实现 │ ├── const.go # RTP常量(版本、PT类型等) │ ├── error.go # RTP标准化错误定义 │ ├── header.go # RTP头部结构体与序列化 │ ├── packet.go # RTP数据包(头部+负载)实现 │ └── serialize.go # RTP数据包解析与序列化 ├── rtcp/ # RTCP控制协议实现 │ ├── const.go # RTCP常量(版本、包类型等) │ ├── error.go # RTCP标准化错误定义 │ ├── header.go # RTCP头部结构体与序列化 │ ├── sr.go # SR(发送端报告)结构体 │ ├── rr.go # RR(接收端报告)结构体 │ └── serialize.go # RTCP报文解析与构造 ├── transport/ # 网络传输模块 │ ├── rtp_udp.go # RTP UDP客户端与服务端 │ ├── rtp_tcp.go # RTP TCP客户端与服务端 │ ├── rtcp_udp.go # RTCP UDP客户端与服务端 │ └── rtcp_tcp.go # RTCP TCP客户端与服务端 ├── session/ # RTP会话管理模块 │ └── session.go # 会话创建、数据包生成等功能 └── example/ # 示例程序(8个,全覆盖场景) ├── rtp_udp_server.go ├── rtp_udp_client.go ├── rtp_tcp_server.go ├── rtp_tcp_client.go ├── rtcp_udp_server.go ├── rtcp_udp_client.go ├── rtcp_tcp_server.go └── rtcp_tcp_client.go ``` #### 安装教程 1. 环境准备:确保本地安装Go 1.18及以上版本(推荐Go 1.20+),配置好Go环境变量; 2. 克隆仓库:在终端执行命令 git clone https://gitee.com/waiot/rtp.git,克隆项目到本地; 3. 依赖安装:进入项目根目录,执行命令 go mod tidy,自动安装所需依赖(本项目无第三方依赖,此步骤仅用于校验模块); 4. 编译测试:进入example目录,执行任意示例程序(如 go run rtp_udp_server.go),验证项目可正常运行。 #### 使用说明 ##### 1. 导入依赖 ```go import ( "gitee.com/waiot/rtp/rtp" "gitee.com/waiot/rtp/rtcp" "gitee.com/waiot/rtp/transport" "gitee.com/waiot/rtp/session" ) ``` ##### 2. RTP使用示例(UDP模式) (1)启动RTP UDP服务端 ```go package main import ( "log" "gitee.com/waiot/rtp/rtp" "gitee.com/waiot/rtp/transport" ) func main() { address := ":5004" ctx, cancel := context.WithCancel(context.Background()) defer cancel() srv, err := transport.NewRTPUDPServer(ctx, address) if err != nil { log.Fatalf("server err: %v", err) } defer srv.Close() log.Println("[RTP UDP SERVER] starting on :5004") srv.SetHandler(func(pkt *rtp.Packet) { log.Printf( "[RTP UDP SERVER] seq=%d, ts=%d, ssrc=0x%08x, pt=%s, payload len=%d", pkt.Header.SequenceNumber, pkt.Header.Timestamp, pkt.Header.SSRC, rtp.PayloadTypeName(pkt.Header.PayloadType), len(pkt.Payload), ) }) srv.Start() sigChan := make(chan os.Signal, 1) signal.Notify(sigChan, syscall.SIGINT, syscall.SIGTERM) <-sigChan log.Println("[RTP UDP SERVER] shutting down gracefully...") } ``` (2)创建RTP UDP客户端并发送数据 ```go package main import ( "log" "time" "gitee.com/waiot/rtp/rtp" "gitee.com/waiot/rtp/session" "gitee.com/waiot/rtp/transport" ) func main() { // 创建RTP UDP客户端,连接服务端 client, err := transport.NewRTPUDPClient("127.0.0.1:5004") if err != nil { log.Fatalf("客户端连接失败: %v", err) } defer client.Close() // 创建RTP会话(视频时钟率90000,音频时钟率8000) sess := session.NewSession(90000) log.Println("[RTP UDP Client] 开始发送数据") // 循环发送测试数据(模拟H.264视频帧) for { payload := []byte{0x00, 0x01, 0x02, 0x03, 0x04} // 模拟H.264负载 pkt, err := sess.GeneratePacket(rtp.PT_H264, payload) if err != nil { log.Printf("生成RTP包失败: %v", err) continue } _, _ = client.SendRTP(pkt) time.Sleep(30 * time.Millisecond) // 模拟30ms一帧 } } ``` ##### 3. RTCP使用示例(UDP模式) (1)启动RTCP UDP服务端 ```go package main import ( "log" "gitee.com/waiot/rtp/rtcp" "gitee.com/waiot/rtp/transport" ) func main() { address := ":5005" ctx, cancel := context.WithCancel(context.Background()) defer cancel() srv, err := transport.NewRTCPUDPServer(ctx, address) if err != nil { log.Fatalf("server err: %v", err) } defer srv.Close() log.Println("[RTCP UDP SERVER] starting on :5005") srv.SetHandler(func(h *rtcp.Header, sr *rtcp.SR, rr *rtcp.RR) { if sr != nil { log.Printf("[RTCP UDP SR] ssrc=0x%08x, packets=%d, octets=%d", sr.SSRC, sr.SenderPacketCount, sr.SenderOctetCount) } if rr != nil { log.Printf("[RTCP UDP RR] ssrc=0x%08x, jitter=%d, lost=%d", rr.SSRC, rr.Jitter, rr.CumulativeLost) } }) srv.Start() sigChan := make(chan os.Signal, 1) signal.Notify(sigChan, syscall.SIGINT, syscall.SIGTERM) <-sigChan log.Println("[RTCP UDP SERVER] shutting down gracefully...") } ``` (2)创建RTCP UDP客户端并发送报告 ```go package main import ( "log" "time" "gitee.com/waiot/rtp/rtcp" "gitee.com/waiot/rtp/transport" ) func main() { client, err := transport.NewRTCPUDPClient("127.0.0.1:5005") if err != nil { log.Fatalf("客户端连接失败: %v", err) } defer client.Close() log.Println("[RTCP UDP Client] 开始发送SR/RR报告") ticker := time.NewTicker(1 * time.Second) // 每秒发送一次报告 defer ticker.Stop() for range ticker.C { // 发送SR(发送端报告) srBuf := rtcp.BuildSR(0x12345678, 0x1122334455667788, 0x99AABBCC, 12345, 67890) _, _ = client.SendRTCP(srBuf) // 发送RR(接收端报告) rrBuf := rtcp.BuildRR(0x12345678, 5, 1234) _, _ = client.SendRTCP(rrBuf) } } ``` ##### 4. TCP模式使用 TCP模式与UDP模式调用逻辑一致,仅需替换transport包中的客户端/服务端方法(如NewRTPTCPClient、RTPTCPServer),具体可参考example目录下的rtp_tcp_xxx.go、rtcp_tcp_xxx.go示例。