Documentation
¶
Overview ¶
Package hls 提供一个直播/点播 HLS origin:管理滚动分片窗口、生成 m3u8 播放列表, 并作为 http.Handler 挂在任意 mux(如 pkg/service/webserver)上分发。
边界(和框架"薄机制"一致):本包**不做编解码/转码/切片**。分片(.ts / .m4s)由上游 产出后 Append 进来——上游可以是 ffmpeg,或 pkg/media/rtmp 采集后的 remux。纯 Go、 零 cgo,只负责"存分片窗口 + 出播放列表 + HTTP 分发"这三件苦活。
用法:
s := hls.NewStream(hls.WithWindow(6), hls.WithTargetDuration(2*time.Second))
mux.Handle("/live/", http.StripPrefix("/live", s)) // s 实现 http.Handler
// 上游每产出一个分片:
s.Append(segBytes, 1980*time.Millisecond)
// 直播结束转点播:
s.Finish()
播放端拉 /live/index.m3u8 → 得到 media playlist,再按其中的 seg{N}.ts 拉分片。
Index ¶
- type DiskStore
- type Master
- type MemoryStore
- type Option
- type Store
- type Stream
- func (s *Stream) Append(data []byte, dur time.Duration) (uint64, error)
- func (s *Stream) AppendPart(data []byte, dur time.Duration, independent bool)
- func (s *Stream) CompleteSegment() error
- func (s *Stream) Finish()
- func (s *Stream) MediaPlaylist() []byte
- func (s *Stream) SegmentData(seq uint64) ([]byte, bool)
- func (s *Stream) ServeHTTP(w http.ResponseWriter, r *http.Request)
- func (s *Stream) SetInitSegment(data []byte)
- type Variant
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type DiskStore ¶
type DiskStore struct {
// contains filtered or unexported fields
}
DiskStore 把分片写到目录下的文件(seg{seq}.dat),重启后仍在(可做简单持久化/大窗口)。 淘汰即删文件。文件名与播放列表 URL 无关(HTTP 侧按 seq 经 Store 取,不直接暴露路径)。
func NewDiskStore ¶
NewDiskStore 创建磁盘 Store,分片落在 dir(不存在则创建)。
type Master ¶
type Master struct {
// contains filtered or unexported fields
}
Master 把多路码率变体组合成一个 ABR 主清单,并按变体名路由到各自 Handler。
type MemoryStore ¶
type MemoryStore struct {
// contains filtered or unexported fields
}
MemoryStore 把分片存在内存 map 里,进程退出即丢。适合直播滚动窗口(总量有界)。
func (*MemoryStore) Remove ¶
func (m *MemoryStore) Remove(seq uint64) error
type Option ¶
type Option func(*config)
Option 配置 Stream。
func WithPartTarget ¶
WithPartTarget 开启 LL-HLS(低延迟)并设置部分分片(part)目标时长(如 333ms)。 开启后用 AppendPart/CompleteSegment 驱动(而非 Append),播放列表带 EXT-X-PART 等指令 并支持阻塞式刷新。
func WithSegmentExt ¶
WithSegmentExt 设置分片扩展名(默认 ".ts";fMP4 用 ".m4s",此时通常需配 SetInitSegment)。
func WithTargetDuration ¶
WithTargetDuration 设置 #EXT-X-TARGETDURATION(默认从分片时长推断,取上界并向上取整)。
type Store ¶
type Store interface {
Put(seq uint64, data []byte) error // 写入一个分片
Get(seq uint64) ([]byte, bool, error) // 读取;不存在返回 (nil,false,nil)
Remove(seq uint64) error // 淘汰(不存在也不报错)
}
Store 是分片字节的可插拔存储后端。Stream 只在内存里维护播放列表元数据(序号+时长), 分片内容的存/取/淘汰交给 Store——从而支持内存、磁盘、对象存储等不同落地。
实现须并发安全(Append 来自采集 goroutine,Get 来自多个 HTTP 请求)。
type Stream ¶
type Stream struct {
// contains filtered or unexported fields
}
Stream 是一路 HLS 流。零值不可用,用 NewStream 构造。并发安全。
func (*Stream) Append ¶
Append 追加一个分片,返回其序号。分片字节写入 Store;直播模式下超出窗口会淘汰最旧 分片(从 Store 删除并推进 media-sequence)。Finish 之后调用无效果,返回 (0, nil)。 Store 写入失败时返回错误(此时不改动播放列表)。
func (*Stream) AppendPart ¶
AppendPart 追加一个部分分片到"当前正在构建的分片"(LL-HLS)。independent 表示该 part 是否可独立解码(通常本分片首个 part 为 true)。仅在 WithPartTarget 开启时有意义。
func (*Stream) CompleteSegment ¶
CompleteSegment 把当前构建中的各 part 合并成一个完整分片(序号 nextSeq)收官,进入滚动 窗口;随后开始累积下一个分片。LL-HLS 专用(与 Append 互斥使用)。
func (*Stream) Finish ¶
func (s *Stream) Finish()
Finish 标记流结束:播放列表加 #EXT-X-ENDLIST 变为点播,且不再淘汰当前窗口内分片。
func (*Stream) MediaPlaylist ¶
MediaPlaylist 生成当前的 media playlist(m3u8)。
func (*Stream) SegmentData ¶
SegmentData 按序号取分片数据(仍在窗口内才有)。
func (*Stream) ServeHTTP ¶
func (s *Stream) ServeHTTP(w http.ResponseWriter, r *http.Request)
ServeHTTP 实现 http.Handler:分发播放列表、init 分片与各媒体分片。 路由(去掉挂载前缀后):
- *.m3u8 → media playlist
- init.mp4 → fMP4 初始化分片(若已 SetInitSegment)
- seg{N}.ext → 序号 N 的分片
func (*Stream) SetInitSegment ¶
SetInitSegment 设置 fMP4 的初始化分片(EXT-X-MAP,URI 为 init.mp4)。TS 分片无需调用。
type Variant ¶
type Variant struct {
Name string // URL 路径段,如 "720p"(master 里引用为 720p/index.m3u8)
Bandwidth int // 峰值码率 bits/s(BANDWIDTH,必填)
Resolution string // 如 "1280x720"(RESOLUTION,可空)
Codecs string // 如 "avc1.64001f,mp4a.40.2"(CODECS,可空)
Playlist string // 变体 media playlist 的文件名(默认 "index.m3u8")
Handler http.Handler // 分发该变体 media playlist + 分片
}
Variant 是 ABR(自适应码率)里的一路码率变体。Handler 负责分发这一路的 media playlist 与分片——既可是本包的 *Stream(进程内 remux/copy),也可是 http.FileServer (指向 ffmpeg 转码写出的目录),因此 Master 能同时适配"进程内"与"ffmpeg 外部转码"两种产源。