HLS Media

之前我一直有一个误区,以为HLS是一个服务,可以把视频文件转换成媒体流。

但其实不是这样的,它是一种媒体格式,和日常使用的mp4,mov 是差不多的,但是又不一样。

HLS 首先会有一种特定的结构(m3u8),接着 再通过网络请求(HTTP),最后 客户端播放的时候,只需把这些结构拼装起来 即可播放。

m3u8

m3u8 是一个播放列表, 一个播放列表可视为一个完整的视频,播放列表内 记录着一个个小视频。

这是一个 例子 output.m3u8

#EXTM3U
#EXT-X-VERSION:3
#EXT-X-TARGETDURATION:10
#EXT-X-MEDIA-SEQUENCE:0
#EXTINF:10.133333,
output0.ts
#EXTINF:10.133333,
output1.ts
#EXTINF:10.133333,
output2.ts
#EXTINF:10.133333,
output3.ts
#EXTINF:10.133333,
output4.ts
#EXTINF:9.333333,
output5.ts
#EXT-X-ENDLIST

这个视频 分为了 6 段,每段10秒。

m3u8 不关心具体的媒体编码,事实上 ts(MPEG-2 TS) 也不关心。

HTTP Live Streaming

获取到播放列表之后,则可以拿到分成多段的TS名称。

接下来就是用 HTTP 协议 获取到这些媒体了。

最后再由 HLS player 播放出来。

基本原理就是这样。

其实可以发现 在做 HLS 这么个服务的时候,关注点应该在于 怎么生成 m3u8 和 分割并封装文件,

传输,播放 解码 这些并不需要关心太多。(对于 服务端来讲)

converter to HLS Media

mkdir output
ffmpeg -i video.mp4 -codec: copy -start_number 0 -hls_time 10 -hls_list_size 0 -f hls output/output.m3u8

这里借助 ffmpeg 来对 一个 mp4 视频 封装成 HLS 格式。

  • -start_number 起始 index
  • -hls_time 分段时长
  • -hls_list_size 播放列表最大条目

Deploy

有了上面生成的HLS,那么 就只需要随便找个 HTTP Server 就可以了。

例如:

  • Caddy
  • nginx

这里使用 Caddy 来做演示

media.domain.com {
        encode zstd gzip
        root * /usr/share/caddy/hls
        file_server
}

然后把 上面的 output 文件夹 放到 /usr/share/caddy/hls 下,

接着 用 Safari 通过 https://media.domain.com/output/output.m3u8 可以愉快的看到 HLS Media 了。