golang解析和生成Apple HLS M3U8播放列表插件库m3u8的使用
Golang解析和生成Apple HLS M3U8播放列表插件库m3u8的使用
关于m3u8库
这是一个用于解析和生成HTTP Live Streaming(Apple HLS)互联网视频传输中使用的M3U8播放列表的最完整的开源库。
主要特性包括:
- 支持HLS协议版本5的规范
- 解析和生成主播放列表(master-playlists)和媒体播放列表(media-playlists)
- 自动检测输入流是主播放列表还是媒体播放列表
- 提供保存播放列表元数据的结构
- 支持与Verimatrix等DRM系统一起使用的加密密钥
- 支持Google Widevine的非标准标签
安装
使用以下命令安装:
go get github.com/grafov/m3u8
示例代码
解析播放列表
f, err := os.Open("playlist.m3u8")
if err != nil {
panic(err)
}
p, listType, err := m3u8.DecodeFrom(bufio.NewReader(f), true)
if err != nil {
panic(err)
}
switch listType {
case m3u8.MEDIA:
mediapl := p.(*m3u8.MediaPlaylist)
fmt.Printf("%+v\n", mediapl)
case m3u8.MASTER:
masterpl := p.(*m3u8.MasterPlaylist)
fmt.Printf("%+v\n", masterpl)
}
解析后你会得到填充了数据的结构体。对于主播放列表,你会得到包含指向Variant结构体指针切片的Master结构体(表示每个比特率的播放列表)。对于媒体播放列表,解析器返回包含Segments切片的MediaPlaylist结构体。
生成媒体播放列表
p, e := m3u8.NewMediaPlaylist(3, 10) // 窗口大小为3,容量为10
if e != nil {
panic(fmt.Sprintf("创建媒体播放列表失败: %s", e))
}
for i := 0; i < 5; i++ {
e = p.Append(fmt.Sprintf("test%d.ts", i), 6.0, "")
if e != nil {
panic(fmt.Sprintf("添加第%d段到媒体播放列表失败: %s", i, e))
}
}
fmt.Println(p.Encode().String())
自定义标签
m3u8支持解析和写入自定义标签。你需要为播放列表中可能遇到的每个自定义标签实现CustomTag
和CustomDecoder
接口。可以参考example/template/
中的模板文件来了解如何解析自定义播放列表和段标签。
库结构
该库代码紧凑,包含三个主要文件:
structure.go
- 声明与播放列表及其属性相关的所有结构reader.go
- 播放列表解析器方法writer.go
- 播放列表生成器方法
每个文件都有相应的测试文件*_test.go
。
项目状态
该项目支持已暂停,代码已移至只读存档。不过它仍然是一个功能完整的M3U8解析和生成库。
替代方案
在2013年项目开始时,Go中还没有其他m3u8库。后来出现了一些替代方案,其中一些可能更适合当前标准:
如果你知道其他相关项目,可以在issue中提供链接。
其他语言的M3U8解析/生成实现
如果你需要其他语言的实现,可以参考:
- Python: https://github.com/globocom/m3u8
- Ruby: https://github.com/zencoder/m3uzi
- Objective C: https://github.com/Jeanvf/M3U8Paser
- Javascript: https://github.com/tedconf/node-m3u8
- Java: http://sourceforge.net/projects/m3u8parser/
- Erlang: https://github.com/karlll/erlm3u8
更多关于golang解析和生成Apple HLS M3U8播放列表插件库m3u8的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html
更多关于golang解析和生成Apple HLS M3U8播放列表插件库m3u8的使用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
使用golang解析和生成Apple HLS M3U8播放列表
在Go语言中处理HLS (HTTP Live Streaming) M3U8播放列表,可以使用第三方库github.com/grafov/m3u8
。这个库提供了完整的M3U8解析和生成功能,支持HLS协议的各种特性。
安装
首先安装m3u8库:
go get github.com/grafov/m3u8
解析M3U8播放列表
解析主播放列表(Master Playlist)
package main
import (
"fmt"
"os"
"github.com/grafov/m3u8"
)
func main() {
// 读取M3U8文件
file, err := os.Open("master.m3u8")
if err != nil {
panic(err)
}
defer file.Close()
// 解析播放列表
p, listType, err := m3u8.DecodeFrom(file, true)
if err != nil {
panic(err)
}
switch listType {
case m3u8.MASTER:
masterpl := p.(*m3u8.MasterPlaylist)
fmt.Printf("Master Playlist with %d variants:\n", len(masterpl.Variants))
for _, variant := range masterpl.Variants {
fmt.Printf("URI: %s, Bandwidth: %d, Resolution: %s\n",
variant.URI, variant.Bandwidth, variant.Resolution)
}
case m3u8.MEDIA:
mediapl := p.(*m3u8.MediaPlaylist)
fmt.Printf("Media Playlist with %d segments, target duration %.2f\n",
mediapl.Count(), mediapl.TargetDuration)
default:
fmt.Println("Unknown playlist type")
}
}
解析媒体播放列表(Media Playlist)
func parseMediaPlaylist() {
file, err := os.Open("media.m3u8")
if err != nil {
panic(err)
}
defer file.Close()
p, _, err := m3u8.DecodeFrom(file, true)
if err != nil {
panic(err)
}
mediapl := p.(*m3u8.MediaPlaylist)
fmt.Printf("Playlist is %s\n", mediapl.ListType)
fmt.Printf("Target duration: %.2f seconds\n", mediapl.TargetDuration)
fmt.Printf("Sequence starts at: %d\n", mediapl.SeqNo)
fmt.Printf("Segment count: %d\n", mediapl.Count())
for i, seg := range mediapl.Segments {
if seg != nil {
fmt.Printf("Segment %d: %s (%.2f sec)\n", i, seg.URI, seg.Duration)
}
}
}
生成M3U8播放列表
创建主播放列表
func createMasterPlaylist() {
// 创建主播放列表
masterpl := m3u8.NewMasterPlaylist()
// 添加变体流
variant := &m3u8.Variant{
URI: "video_800k.m3u8",
Bandwidth: 800000,
Resolution: "640x360",
}
masterpl.Append("video_800k.m3u8", variant, "")
variant = &m3u8.Variant{
URI: "video_1200k.m3u8",
Bandwidth: 1200000,
Resolution: "854x480",
}
masterpl.Append("video_1200k.m3u8", variant, "")
// 输出播放列表
fmt.Println(masterpl.String())
}
创建媒体播放列表
func createMediaPlaylist() {
// 创建媒体播放列表,容量为10个片段
mediapl, err := m3u8.NewMediaPlaylist(10, 10)
if err != nil {
panic(err)
}
// 设置播放列表属性
mediapl.TargetDuration = 6.0
mediapl.SeqNo = 1
mediapl.Live = false
// 添加媒体片段
mediapl.Append("segment1.ts", 5.0, "")
mediapl.Append("segment2.ts", 5.5, "")
mediapl.Append("segment3.ts", 6.0, "")
// 关闭播放列表(对于VOD很重要)
mediapl.Close()
// 输出播放列表
fmt.Println(mediapl.String())
}
高级功能
添加EXT-X-KEY加密信息
func addEncryption(mediapl *m3u8.MediaPlaylist) {
key := &m3u8.Key{
Method: "AES-128",
URI: "https://example.com/key.bin",
IV: "0x1234567890ABCDEF1234567890ABCDEF",
Keyformat: "identity",
Keyformatversions: "1",
}
mediapl.Key = key
}
添加EXT-X-DISCONTINUITY标记
func addDiscontinuity(mediapl *m3u8.MediaPlaylist) {
mediapl.Append("segment_new.ts", 5.0, "")
mediapl.Discontinuity()
mediapl.Append("segment_after_discontinuity.ts", 5.0, "")
}
添加EXT-X-MAP初始化段
func addMap(mediapl *m3u8.MediaPlaylist) {
mapTag := &m3u8.Map{
URI: "init.mp4",
Limit: 1024,
Offset: 0,
}
mediapl.Map = mapTag
}
注意事项
- 对于直播流,需要定期更新播放列表并设置
Live = true
- 点播流(VOD)需要调用
Close()
方法 - 确保
TargetDuration
大于或等于所有片段的最大持续时间 - 处理加密内容时,确保密钥服务器可访问
这个库提供了完整的HLS M3U8处理能力,可以满足大多数流媒体应用的需求。更多高级用法可以参考库的文档和HLS协议规范。