rave/README.md

179 lines
6.2 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Rave
纯 Rust 实现的全协议流媒体服务器引擎,零第三方依赖。
受 [lal (Go)](https://github.com/q191201771/lal) 和 [Monibuca v6 (Rust)](https://monibuca.com/) 启发,但除 `tokio` 异步运行时外不依赖任何外部 crate。
## 协议支持
| 协议 | 推流 | 拉流 | 状态 |
|------|:----:|:----:|:----:|
| RTMP | ✅ | ✅ | 握手、Chunk 协议、AMF0、Publish/Play |
| RTSP/RTP | ✅ | ✅ | ANNOUNCE/RECORD 推流DESCRIBE/PLAY 拉流 |
| HTTP-FLV | — | ✅ | HTTP 长连接 + FLV 实时流 |
| WebSocket-FLV | — | 🚧 | 框架已搭建 |
| HLS | — | 🚧 | 框架已搭建 |
## 编解码支持
- **视频**: H.264 (AnnexB + AVCC)、H.265/HEVC
- **音频**: AAC (ADTS + raw)、G.711 (A-law / μ-law)
- **容器**: FLV、MPEG-TS
## 快速开始
```bash
# 构建
cargo build --release
# 启动服务器
cargo run --release
# 可选:指定配置文件
cargo run --release -- rave.conf
```
## 推流与拉流
```bash
# RTMP 推流
ffmpeg -re -i video.mp4 -c copy -f flv rtmp://localhost:1935/live/test
# RTSP 推流TCP 传输)
ffmpeg -re -i video.mp4 -c copy -f rtsp -rtsp_transport tcp rtsp://localhost:5544/live/test
# RTMP 拉流
ffplay rtmp://localhost:1935/live/test
# HTTP-FLV 拉流
ffplay http://localhost:8080/live/test.flv
# RTSP 拉流
ffplay rtsp://localhost:5544/live/test
```
## 跨协议转发
推流端和拉流端可以使用不同协议,服务器自动进行协议转换:
| 推流 → 拉流 | RTMP | HTTP-FLV | RTSP |
|:-----------:|:----:|:--------:|:----:|
| **RTMP** | ✅ | ✅ | ✅ |
| **RTSP** | ✅ | ✅ | ✅ |
## HTTP API 接口
所有 HTTP 端点运行在 HTTP-FLV 服务器端口(默认 `8080`
| 端点 | 方法 | 说明 |
|------|------|------|
| `/api/stats` | GET | 服务器运行统计(带宽、帧率、连接数) |
| `/api/streams` | GET | 活跃流列表编解码器、订阅者数、GOP 缓存) |
| `/{app}/{stream}.flv` | GET | HTTP-FLV 实时拉流 |
详细接口文档见 [api.md](api.md)。
## 配置
默认端口和插件开关可在 `rave.conf` (TOML 格式) 中配置:
```toml
rtmp.port = 1935
httpflv.port = 8080
rtsp.port = 5544
log.level = "info"
# 插件开关(设为 false 禁用对应协议)
# rtmp.enabled = false
# rtsp.enabled = false
```
## 架构
```
src/
├── main.rs # 入口配置加载、插件注册、banner、优雅关闭
├── lib.rs # 模块根
├── config.rs # 手写 TOML 解析器
├── logger.rs # 最小化 stderr 日志
├── stats.rs # 服务器统计
├── core/ # 引擎内核
│ ├── buffer.rs # 无锁 SPMC 环形缓冲区
│ ├── dispatcher.rs # 单读广播分发器
│ ├── publisher.rs # 发布者(写入轨道)
│ ├── subscriber.rs # 订阅者(有界队列 + 背压)
│ ├── stream.rs # 流GOP 缓存 + 订阅者管理)
│ ├── group.rs # StreamManager流注册表
│ └── track.rs # 音视频轨道
├── sdk/ # 插件契约层
│ ├── types.rs # AVFrame、编解码器枚举、StreamPath
│ ├── traits.rs # PublisherApi、SubscriberApi、StreamManagerApi
│ ├── plugin.rs # Plugin / ProtocolPlugin trait
│ ├── context.rs # EngineContextIoC 容器)
│ └── registry.rs # PluginRegistry生命周期管理 + 配置开关)
├── codec/ # 编解码器
│ ├── h264.rs # H.264 NALU 解析、AVCC 编码
│ ├── h265.rs # H.265 NALU 类型
│ ├── aac.rs # AAC ADTS 解析
│ ├── flv.rs # FLV tag 编解码
│ └── ts.rs # MPEG-TS 打包
├── protocol/ # 协议实现
│ ├── mod.rs # all_plugins() 内置插件清单函数
│ ├── rtmp/ # RTMP 插件、握手、Chunk、AMF0、Session
│ ├── rtsp/ # RTSP 插件、信令、RTP、Depacketizer
│ ├── httpflv*.rs # HTTP-FLV 插件 + 服务端
│ ├── hls.rs # HLS 框架
│ └── wsflv.rs # WebSocket-FLV 框架
└── remux/ # 协议转换
├── rtmp2flv.rs # RTMP ↔ FLV
└── flv2ts.rs # FLV ↔ MPEG-TS
```
### 性能设计
- **无锁 SPMC 环形缓冲区**: Publisher 通过 `fetch_add` 原子操作写入Subscriber 各自维护读取游标
- **零拷贝**: 帧数据通过 `Arc<Vec<u8>>` 共享Subscriber 间不复制媒体负载
- **单读广播**: Dispatcher 每帧只读取一次,分发给所有 Subscriber
- **背压控制**: 每个 Subscriber 有独立有界队列1024 帧),慢消费者丢帧不阻塞发布者
### SDK 插件架构
插件仅依赖 `sdk/` 层的 trait 契约,不直接引用 `core/` 内部实现:
```
sdk/types.rs → sdk/traits.rs → sdk/plugin.rs → sdk/context.rs → sdk/registry.rs
core/ (实现 sdk traits) |
|
protocol/ (仅依赖 sdk:: traits + types) ───────────────────┘
```
**内置插件**通过 `protocol::all_plugins()` 自动注册,新增内置协议只需:
1.`protocol/<name>/plugin.rs` 实现 `Plugin` + `ProtocolPlugin` trait
2.`protocol/mod.rs``all_plugins()` 中添加一行
**外部插件**通过 `registry.register()` 手动注册。
## 测试
```bash
# 运行全部测试513 个)
cargo test
# 运行特定测试
cargo test test_rtmp_handshake
cargo test test_fu_a_reassembly
cargo test test_depacketize_aac
```
## 设计约束
- **零第三方依赖**(除 `tokio` 异步运行时):所有编解码、协议解析、并发原语均手写实现
- Edition 2024使用最新 Rust 惯用法
- 全部代码中文注释,技术术语保留英文原文
## 致谢
- [lal](https://github.com/q191201771/lal) — Group 模式、GOP 缓存、Remux 层架构参考
- [Monibuca v6](https://monibuca.com/) — SDK 插件解耦、零拷贝分发架构参考