Go 流媒体开发工具包 — 协议接入、编解码与流编排;生产交付请以 stable 能力为边界,实验/占位能力见下文说明。
| 类别 | 支持项 |
|---|---|
| 传输协议 | RTSP, RTSPS(RegisterAllExtended), RTMP, SRT, RIST, HLS(本地输出), WebRTC (WHIP/WHEP), GB/T 28181, NDI(需外部SDK), DVR-IP |
| 容器格式 | MP4, fMP4, FLV, MPEG-TS, MKV(以 demux 为主), HLS, AAC, MSE, RAW |
| 视频编码 | H.264, H.265/HEVC, AVS2, VP9, AV1, VVC/H.266, MJPEG |
| 音频编码 | AAC, Opus, MP3, FLAC, AC-3/E-AC-3, G.726, PCM (μ-law/A-law) |
| 图片编码 | WebP, AVIF, HEIF |
| 硬件加速 | NVENC, QSV, AMF, VAAPI, VideoToolbox, V4L2M2M, RKMPP(依赖 CGO/FFmpeg 环境) |
| 高级功能 | 字幕 (SRT/ASS/WebVTT/CEA-608/708), OpenTelemetry 追踪, Prometheus 指标;ABR/录制多云后端/集群多后端详见“能力边界说明” |
format.RegisterAll() 稳定协议集(mp4/ts/rtmp/rtsp/flv/aac/srt/hls 本地输出)stream / pkg/manager / pkg/streammgr 的单进程流会话治理pkg/recording.LocalStorage 与本地 ts/mp4/flv 分段录制pkg/cluster.StaticDiscoverystream.Transcode / Builder.Transcode() 在非 CGO 模式下调用系统 ffmpeg 可执行文件;cgo/pipeline / cgo/sdk 提供帧级 FFmpeg 绑定,pkg/abr 提供 HLS 多档位执行链。pkg/abr):HLS 多档位输出已落地,依赖系统 ffmpeg;DASH 仍按 fail-fast 边界处理。pkg/recording):S3/MinIO/GCS XML API 对象存储已落地最小真实 I/O,依赖对象存储凭证与网络。pkg/cluster):Consul Agent HTTP API、etcd v3 JSON gateway、Kubernetes ConfigMap 后端已落地最小真实实现,依赖可达后端、Token/RBAC 与 TTL 策略。pkg/abr 当前仅承诺 HLS 多档位输出,DASH 仍 fail-fast。ffmpeg、对象存储凭证、服务发现后端与 RBAC。format.RegisterAll()。cmd/vdk serve 适合单进程、单节点、边车式交付;不承诺分布式控制面、高可用选主、持久化会话恢复。HLSDir / 录制目录应挂载到持久卷;不要将临时目录直接视为生产持久层。gofmt / go vet / go test ./... / go test -race ./... / ffmpeg7 build-tag / CLI 本地媒体 E2E / coverage smoke / govulncheck。cmd/vdk serve 已补齐 logging.level / logging.format / metrics / livez|readyz 接缝;生产环境仍应统一接入外部日志、指标与追踪系统。仓库内置 Go CI(见 .github/workflows/go-ci.yml),默认执行:
gofmt -l:格式一致性go vet ./...:静态分析go test ./...:全模块回归go test -race ./...:并发数据竞争扫描go test -tags ffmpeg7 ./...:CGO/FFmpeg 条件路径验证scripts/e2e_cli_local.sh:本地媒体 probe/transcode/HLS CLI E2Ego test -cover ./...:覆盖率 smokegovulncheck ./...:依赖与标准库漏洞扫描建议将上述门禁视为所有变更合并前的最低门槛。
go get cnb.cool/svn/vdk@latest
| 场景 | 导入路径 | 构建条件 | 预期行为 |
|---|---|---|---|
| 默认协议/容器与流编排 | stream, format/*, pkg/manager, pkg/recording | 默认构建无需本机 FFmpeg headers;root module 仍包含 CGO 子包依赖元数据 | 可直接 go get;离线/极简下游需缓存 module graph |
| 系统 FFmpeg 转码 | stream.Transcode, Builder.Transcode, pkg/abr | 默认构建无需 CGO;运行机需可执行文件 ffmpeg 或设置 VDK_FFMPEG_PATH | 非 CGO 场景补齐常见转码、缩放、滤镜、HLS 输出 |
| CGO 转码与 WebRTC AAC→Opus | cgo/pipeline, cgo/sdk, format/webrtc AAC 转码, pkg/streammgr WHEP AAC 转码 | CGO_ENABLED=1,安装 FFmpeg 7/8 dev headers 与 pkg-config,使用 -tags ffmpeg7 或 -tags ffmpeg8 | 帧级控制、硬件上下文与内存生命周期由 CGO 层处理 |
| CGO SDK | cnb.cool/svn/vdk/cgo/{codec,filter,pipeline,sdk} | 同上 | 下游模块直接导入可构建;当前固定 github.com/asticode/go-astiav v0.39.0,不依赖本仓库 replace |
常用环境准备:
# Ubuntu/Debian
sudo apt-get install -y pkg-config libavcodec-dev libavformat-dev libavutil-dev libswresample-dev libswscale-dev
# macOS
brew install ffmpeg pkg-config
# 条件路径验证
CGO_ENABLED=1 go test -tags ffmpeg7 ./...
go install cnb.cool/svn/vdk/cmd/vdk@latest
# 探测流信息
vdk probe rtsp://example.com/live/stream
# 封装转换/复制(不重编码)
vdk transcode -i input.mp4 -o output.flv
# 启动流媒体服务
vdk serve -c config.yaml
# 性能基准测试
vdk benchmark
package main
import (
"context"
"time"
"cnb.cool/svn/vdk/format"
"cnb.cool/svn/vdk/stream"
)
func main() {
format.RegisterAll()
s, err := stream.New().
Name("cam-01").
Input("rtsp://admin:pass@192.168.1.100/live").
WithTimeout(10 * time.Second).
LowLatency().
Output("rtmp://cdn.example.com/live/cam-01").
WithTimeout(5 * time.Second).
Done().
Output("srt://backup.example.com:9000").
SRTConfig(120*time.Millisecond, "", "live/cam-01").
Done().
Build()
if err != nil {
panic(err)
}
s.OnEvent(func(e stream.EventData) {
switch e.Event {
case stream.EventReconnecting:
println("重连中...")
case stream.EventError:
println("错误:", e.Error.Error())
}
})
if err := s.Run(context.Background()); err != nil {
panic(err)
}
}
stream.Transcode / TranscodeWithConfig / QuickTranscode.Run 与 Builder.Transcode() 已重构为系统 ffmpeg 执行层,默认不依赖 CGO;通过 TranscodeConfig.FFmpegPath、TranscodeBuilder.FFmpegPath() 或环境变量 VDK_FFMPEG_PATH 指定可执行文件。需要帧级内存控制、深度硬件上下文或自定义 pipeline 时使用 cnb.cool/svn/vdk/cgo/sdk / cgo/pipeline,ABR 多档位 HLS 使用 pkg/abr。
package main
import (
"cnb.cool/svn/vdk/av/avutil"
"cnb.cool/svn/vdk/format"
)
func main() {
format.RegisterAll()
demuxer, err := avutil.Open("rtsp://example.com/live")
if err != nil {
panic(err)
}
defer demuxer.Close()
muxer, err := avutil.Create("output.mp4")
if err != nil {
panic(err)
}
defer muxer.Close()
streams, _ := demuxer.Streams()
muxer.WriteHeader(streams)
avutil.CopyPackets(muxer, demuxer)
muxer.WriteTrailer()
}
av/event 包提供协议传输层的通用事件机制,14 种事件类型覆盖连接全生命周期。
package main
import (
"fmt"
"cnb.cool/svn/vdk/av/event"
"cnb.cool/svn/vdk/format/srt"
)
func main() {
conn, err := srt.Dial("srt://relay.example.com:9000?streamid=live/test")
if err != nil {
panic(err)
}
defer conn.Close()
// 通过 EventBus 监听事件
conn.EventBus = event.NewBus()
conn.EventBus.On(event.Connected, func(d event.Data) {
fmt.Printf("[%s] 已连接: %s\n", d.Protocol, d.URL)
})
conn.EventBus.On(event.StreamReady, func(d event.Data) {
fmt.Printf("流就绪, codec 数量: %d\n", len(d.Codec))
})
conn.EventBus.On(event.Stats, func(d event.Data) {
if stats, ok := d.Stats.(srt.Stats); ok {
fmt.Printf("RTT: %dms, 丢包率: %.2f%%\n",
stats.RTT.Milliseconds(), stats.PacketLossRate*100)
}
})
conn.EventBus.On(event.Error, func(d event.Data) {
fmt.Printf("错误: %v\n", d.Error)
})
// OnAll 接收所有事件
conn.EventBus.OnAll(func(d event.Data) {
fmt.Printf("[%s] %s @ %s\n", d.Protocol, d.Event, d.Time.Format("15:04:05"))
})
}
import "cnb.cool/svn/vdk/av/event"
// 将任意 DemuxCloser 包装为带事件的 HookDemuxer
hooked := event.WrapDemuxer(demuxer,
event.WithProtocol("rtsp"),
event.WithURL("rtsp://example.com/live"),
event.WithDirection("subscribe"),
)
hooked.On(event.StreamReady, func(d event.Data) {
fmt.Println("codec 就绪:", d.Codec)
})
streams, err := hooked.Streams() // 自动发射 StreamReady
| 事件 | 说明 |
|---|---|
Connecting | 正在连接 |
Connected | 连接成功 |
Handshaking | 正在握手 |
Handshaked | 握手完成 |
StreamReady | 流就绪 (codec 已获取) |
PacketRead | 读取数据包 |
PacketWrite | 写入数据包 |
CodecChange | 编码变更 |
Error | 错误 |
Disconnecting | 正在断开 |
Disconnected | 已断开 |
Reconnecting | 正在重连 |
Reconnected | 重连成功 |
Stats | 统计信息更新 |
vdk/
├── av/ # 核心抽象层
│ ├── av.go # Muxer, Demuxer, CodecData, Packet 接口
│ ├── event/ # 事件系统 (Bus, HookDemuxer, HookMuxer)
│ ├── pktque/ # 包队列与 Filter (WaitKeyFrame, FixTime)
│ ├── pubsub/ # 发布/订阅 Queue (fan-out)
│ ├── avutil/ # Handler 注册, Open/Create 辅助函数
│ ├── avconv/ # 格式转换辅助
│ └── transcode/ # 转码器包装
├── codec/ # 编解码器
│ ├── h264parser/ # H.264 解析 (SplitNALUs, SPS, CodecData)
│ ├── h265parser/ # H.265/HEVC 解析
│ ├── aacparser/ # AAC 解析
│ ├── opusparser/ # Opus 解析
│ ├── vp9parser/ # VP9 解析
│ ├── av1parser/ # AV1 解析
│ ├── vvc/ # VVC/H.266
│ ├── flac/ # FLAC
│ ├── mp3/ # MP3
│ ├── ac3/ # AC-3
│ ├── mjpeg/ # MJPEG
│ ├── webp/, avif/, heif/ # 图片格式
│ └── fake/ # 测试用假编码器
├── format/ # 协议与容器
│ ├── rtmp/ # RTMP (Dial, Server, Conn + EventBus)
│ ├── rtsp/ # RTSP Client + EventBus
│ ├── rtspv2/ # RTSPv2 Client, ProxyConn/Server 轻量骨架 + EventBus
│ ├── srt/ # SRT (Dial/DialContext/DialConfig, Config, Stats + EventBus)
│ ├── rist/ # RIST (Sender, FEC, Stats, BridgeEvents)
│ ├── webrtc/ # WebRTC Muxer, WebRTCPusher (WHIP/BatchV2), WHEPPuller
│ ├── webrtcv3/ # WebRTC v3 兼容导入路径(后端使用 Pion v4)
│ ├── gb28181/ # GB/T 28181 SIP + PS 解封装
│ ├── ndi/ # NDI 协议框架
│ ├── dvrip/ # DVR-IP Client + EventBus
│ ├── hls/ # HLS Muxer
│ ├── flv/ # FLV Muxer, Demuxer, Prober
│ ├── mp4/ # MP4 Muxer, Demuxer
│ ├── mp4f/ # fMP4 Muxer (fragmented)
│ ├── mp4m/ # MP4 Muxer, Demuxer (扩展)
│ ├── fmp4/ # fMP4 MovieFragmenter
│ ├── mkv/ # MKV Demuxer
│ ├── ts/ # MPEG-TS Muxer, Demuxer
│ ├── nvr/ # NVR/MP4 分片录像 Muxer(demux 占位)
│ ├── aac/ # AAC 文件
│ ├── raw/ # RAW 裸流
│ └── mse/ # Media Source Extensions
├── stream/ # 高级 Builder API
│ ├── builder.go # New(), Input(), Output(), Build(), Transcode()
│ ├── stream.go # Stream (Start/Stop/Pause/Resume/Run/Wait)
│ ├── ffmpeg_exec.go # 非 CGO 系统 FFmpeg 转码执行层
│ └── enums.go # Protocol, VideoCodec, AudioCodec, Container, Preset...
├── pkg/ # 功能模块
│ ├── manager/ # 流生命周期 Manager (状态机, 健康检查, 资源限制)
│ ├── streammgr/ # 批量会话 Manager (熔断, 健康监控, 集群)
│ ├── abr/ # ABR HLS 多档位 FFmpeg 转码
│ ├── ai/ # AI 增强接口与简化处理器(外部模型后端需自行接入)
│ ├── audio/ # 音频处理 (响度标准化, 混音, 声道映射)
│ ├── subtitle/ # 字幕 (SRT/ASS/WebVTT/CEA-608/708)
│ ├── recording/ # 分段录制框架(Local/S3/MinIO/GCS XML API)
│ ├── cluster/ # 集群(Static/Consul/Etcd/K8s 服务发现)
│ ├── tracing/ # OpenTelemetry 分布式追踪
│ ├── config/ # 配置管理
│ └── scene/ # 场景检测 (内容类型识别, 编码建议)
├── cgo/ # FFmpeg CGO 绑定
│ ├── codec/ # 编解码 (H264/H265/VP9/AV1, 硬件加速)
│ ├── filter/ # 滤镜 (构建器, 水印, 色调映射)
│ ├── pipeline/ # 转码管道 (批量管理, 健康检查)
│ └── sdk/ # 高级转码 SDK (引擎, 任务, 预设)
├── cmd/vdk/ # CLI 工具 (probe, remux/transcode(copy), serve, benchmark)
├── example/ # 示例程序
└── utils/ # 通用工具 (位流读写, 字节序转换)
| 模块 | 路径 | 说明 |
|---|---|---|
| 核心接口 | av/ | Muxer, Demuxer, CodecData, Packet |
| 事件系统 | av/event/ | Bus, HookDemuxer, HookMuxer |
| 包队列 | av/pktque/ | Filter, WaitKeyFrame, FixTime |
| 发布订阅 | av/pubsub/ | Queue fan-out |
| 工具函数 | av/avutil/ | Open, Create, CopyPackets |
| 格式转换 | av/avconv/ | 音频编码自动转换 |
| 转码器 | av/transcode/ | 音频转码包装 |
| 编解码器 | codec/ | H.264/H.265/AAC/Opus/VP9/AV1/VVC 等解析 |
| RTMP | format/rtmp/ | Dial, Server, Conn + EventBus |
| RTSP | format/rtsp/ | Client + EventBus |
| RTSPv2 | format/rtspv2/ | RTSPClient(主路径), ProxyConn/Server(轻量骨架) |
| SRT | format/srt/ | Dial, Config, Stats + EventBus |
| RIST | format/rist/ | Sender, FEC, Config + EventBus |
| WebRTC | format/webrtc/ | Muxer, WHIP/WHEP Pusher/Puller |
| GB/T 28181 | format/gb28181/ | SIP 注册/鉴权, PS 解封装 |
| DVRIP | format/dvrip/ | DVR/NVR 设备客户端 + EventBus |
| NDI | format/ndi/ | NDI 协议框架 (需外部 SDK) |
| FLV | format/flv/ | Muxer, Demuxer, Prober |
| MP4 | format/mp4/ | Muxer, Demuxer |
| fMP4 | format/fmp4/ | Fragmented MP4 |
| HLS | format/hls/ | M3U8 + TS 分片 |
| MPEG-TS | format/ts/ | Muxer, Demuxer |
| MKV | format/mkv/ | Demuxer (扩展) |
| MSE | format/mse/ | Media Source Extensions |
| RAW | format/raw/ | H.264/H.265 裸流 |
| NVR | format/nvr/ | NVR/MP4 分片录像 Muxer;demux 读取占位 |
| Builder API | stream/ | New, Build, Stream, 系统 FFmpeg 转码 |
| 流管理器 | pkg/manager/ | 生命周期管理 |
| 会话管理 | pkg/streammgr/ | 批量会话, 熔断, 健康监控 |
| ABR | pkg/abr/ | HLS 码率阶梯与 FFmpeg 多档位转码 |
| AI 增强 | pkg/ai/ | 增强器接口、管理器、流水线与简化处理器 |
| 字幕 | pkg/subtitle/ | SRT/ASS/WebVTT/CEA-608/708 |
| 音频处理 | pkg/audio/ | 响度标准化, 混音, 声道映射 |
| 录制 | pkg/recording/ | 录制框架;Local/S3/MinIO/GCS XML API 可用 |
| 集群 | pkg/cluster/ | 负载均衡/路由 + Static/Consul/Etcd/K8s 服务发现 |
| 指标 | pkg/metrics/ | Prometheus Collector |
| 追踪 | pkg/tracing/ | OpenTelemetry |
| 配置管理 | pkg/config/ | 统一配置加载 |
| 场景检测 | pkg/scene/ | 内容类型识别, 编码建议 |
| CGO 编解码 | cgo/codec/ | FFmpeg 编解码, 硬件加速 |
| CGO 滤镜 | cgo/filter/ | 滤镜构建器, 水印 |
| CGO 管道 | cgo/pipeline/ | 转码管道, 批量管理 |
| CGO SDK | cgo/sdk/ | 高级转码引擎 |
| CLI | cmd/vdk/ | probe, remux/transcode(copy), serve, benchmark |
| 示例 | example/ | 示例程序索引与能力边界 |
| 版本 | 状态 | 重点 |
|---|---|---|
| v2.1 | 当前 | Builder API, 事件系统, SRT/RIST/WebRTC, GB/T 28181, AI 增强框架;ABR HLS、录制/集群部分后端按能力边界交付 |
| v2.2 | 规划中 | DASH 输出, SRT Bonding, RIST Main Profile 完善, CMAF |
| v3.0 | 规划中 | 全链路 zero-copy, io_uring 传输, QUIC 协议, WebTransport |
| 依赖 | 用途 |
|---|---|
| pion/webrtc v4 | WebRTC (WHIP/WHEP);format/webrtcv3 仅保留兼容导入路径,底层同样使用 v4 |
| pion/rtp | RTP 包处理 |
| gobwas/ws | WebSocket |
| go-astiav | FFmpeg CGO 绑定 |
| gopsutil | 系统资源监控 |
| OpenTelemetry | 分布式追踪 |
| google/uuid | UUID 生成 |
| x/crypto | 加密 |
| x/image | 图片处理 |
本项目基于 joy4 演进,感谢原作者的开创性工作。
MIT License
最后更新:2026-02-26