基于 HLS 创建 Golang 视频流服务器
优点
-
应用广泛
-
首先,刚才已经提到过,HLS 是应用最惯犯的实时视频协议。虽然最初苹果是为了自己的生态设计的,例如 IOS,Safari 浏览器等,但是背靠苹果,有强大的生态和研发能力,现在它几乎在所有浏览器上实现了。虽然现在的主流浏览器都支持一个类似的标准,称为 MPEG DASH,但是由于苹果 Safari 浏览器和 IOS 设备不支持它,个人认为 HLS 是一个更好的选择。
-
自适应比特率
-
HLS 另一个巨大的优势是,它允许客户端根据可用带宽,从各种质量流中选出合适的。HLS 分解成一个个大约 10 秒的文件小段,通过分解,客户端应用程序只需要提前缓冲 10 秒。为用户节约了大量潜在带宽。
缺点
-
糟糕的延迟
-
虽然 HLS 设计出来是为了高效的处理多质量的流,但它并不是为了快速传输视频设计的。实际上,HLS 在流中引入流相当长的延迟,一般 20 秒左右,甚至更久。
-
说到这里,你可能想问为什么?HLS 需要三个片段在队列中才允许回放,片段被视频中的关键帧分割。用 HLS 创建超低延迟流的唯一方法就是每 250 毫秒出现一个关键帧的视频进行编码,HLS 播放列表窗口将是四项长度,增加正在发生的 HTTP 调用频率,并给服务器增加额外的压力。
-
未发布
-
HLS 是一个仅供用户使用的协议。不像 WebRTC 有从浏览器发布的规范,HLS 仅支持播放流,如果你想发布一个设备的实时视频流,你只需要寻找其他的 SDK ,国外的例如 Red5 Pro(场景较为单一,巨贵), 来创建使用 RTP 的发布应用程序,然后通过 HLS 中继这些流,让人们在浏览器中查看。
-
国内有几个较为成熟的音视频 SDK,例如声网等平台,提供很多场景的音视频解决方案。
HLS 简单介绍完了,接下来演示一个小 Demo, 使用 FFmpeg,可以很轻易的将 mp3 文件转换为 HLS 格式,它由多个文件组成,其中一个包含元数据(.m3u8),元数据告诉客户端从哪里获取每个数据文件,以及数据文件中包含什么内容。数据文件拓展名是.ts,通常包含 10 秒的音频。
首先准备一个 mp3 文件。然后安装 FFmpeg,在 Mac 上安装 FFmpeg,如果速度很慢可以尝试切换镜像。
1 brew install ffmpeg 2
成功安装后,进入 mp3 所在文件夹,执行以下指令。
1 ffmpeg -i 江南.mp3 -c:a libmp3lame -b:a 128k -map 0:0 -f segment -segment_time 10 -segment_list outputlist.m3u8 -segment_format mpegts output%03d.ts 2
执行完毕后应该会看到一些结果,大致内容如下.
1 output000.ts output008.ts output016.ts output024.ts 2 output001.ts output009.ts output017.ts output025.ts 3 output002.ts output010.ts output018.ts output026.ts 4 output003.ts output011.ts output019.ts outputlist.m3u8 5 output004.ts output012.ts output020.ts 江南.mp3 6 output005.ts output013.ts output021.ts 7 output006.ts output014.ts output022.ts 8 output007.ts output015.ts output023.ts 9
到这一步你已经完成了文件格式转换,接下来进入 Coding 阶段。
项目结构
代码如下
1 package main 2 3 import ( 4 "fmt" 5 "log" 6 "net/http" 7 ) 8 9 func main() { 10 // 设置文件目录 11 const songsDir = "song" 12 const port = 8888 13 14 http.Handle("/", http.FileServer(http.Dir(songsDir))) 15 log.Printf("Serving %s on HTTP port: %v\n", songsDir, port) 16 17 log.Fatal(http.ListenAndServe(fmt.Sprintf(":%v", port), nil)) 18 } 19
运行代码
1 go run main.go 2
打开浏览器地址
1 http://127.0.0.1:8888/outputlist.m3u8 2
恭喜你,你可以听到这段 mp3 动人的旋律了。但是如果你想进一步进行商业开发,或者个人开发,推荐使用比较成熟的解决方案,一是音视频不分家,音频需求往往伴随着视频需求,音视频往往是开发过程中的某一个子需求,如果在上面耗费大量时间,往往会耽误项目进度,而且处理起多个平台时往往有一些细节上的坑。使用市面上的 SDK,能够很大程度上节约开发成本。我个人在使用的声网,能够支持跨平台,最最最关键,每个月能够白嫖一定的额度,对于个人开发者来说十分友好。当然了,费用其实是一方面,还有相当重要的一点就是能够几行代码即可接入,大大较少了踩坑量!
总结