Bootstrap

音视频文件提供流式传输之HTTP Live Streaming (HLS)

HTTP Live Streaming (HLS) 是由 Apple 推出的基于 HTTP 的流媒体协议,它通过将音视频文件切分成一系列较小的分段文件,并通过 M3U8 播放列表进行索引,使得音视频可以实现流式传输,支持动态适应不同带宽的自适应流媒体传输。

HLS 是广泛使用的流媒体协议,特别适用于视频点播和直播服务。在音视频文件的流式传输中,HLS 的优点包括:无需专门的流媒体服务器,支持设备和平台的广泛兼容,以及通过分段传输来实现内容的快速加载。

1. HLS 工作原理

HLS 将音视频内容分割为多个小的 .ts (MPEG-TS) 文件(通常几秒钟的时长),并通过一个 .m3u8 播放列表文件索引这些分段。客户端根据网络带宽选择不同质量的分段进行播放,从而实现自适应比特率流。

HLS 主要组件:

  • 视频分段文件 (.ts):音视频流被切割为多个短小的文件(通常是 5 到 10 秒),每个文件包含音视频数据的一部分。
  • 播放列表文件 (.m3u8):是一个索引文件,列出所有的分段文件的位置。播放列表文件可以是主播放列表(包含不同分辨率、比特率的流),也可以是媒体播放列表(指向具体的 .ts 文件)。
流程
  1. 视频编码:视频内容首先进行编码(如 H.264 视频编码,AAC 音频编码),然后将其分段成多个 .ts 文件。
  2. 生成播放列表 (M3U8):每个分段的 .ts 文件会被列出在一个 .m3u8 播放列表文件中。可以有多个 .m3u8 播放列表文件,分别对应不同的码率(低、中、高质量等)。
  3. 客户端请求播放:客户端(如浏览器、移动设备)请求 .m3u8 文件,解析该文件后获取音视频分段,并开始请求对应的 .ts 分段进行播放。

2. HLS 播放列表示例

主播放列表(master.m3u8

#EXTM3U
#EXT-X-VERSION:3
#EXT-X-STREAM-INF:BANDWIDTH=800000,RESOLUTION=640x360
low/index.m3u8
#EXT-X-STREAM-INF:BANDWIDTH=1400000,RESOLUTION=1280x720
mid/index.m3u8
#EXT-X-STREAM-INF:BANDWIDTH=2500000,RESOLUTION=1920x1080
high/index.m3u8

在主播放列表中,包含了多个不同质量的视频流(如低、中、高质量)。每个视频流有一个子播放列表文件(如 low/index.m3u8mid/index.m3u8),该文件列出了具体的 .ts 文件。

子播放列表(low/index.m3u8

#EXTM3U
#EXT-X-VERSION:3
#EXT-X-TARGETDURATION:10
#EXT-X-MEDIA-SEQUENCE:0
#EXTINF:10.0,
low/00001.ts
#EXTINF:10.0,
low/00002.ts
#EXTINF:10.0,
low/00003.ts
#EXT-X-ENDLIST

每个子播放列表列出了对应质量的视频分段,EXTINF 标签表示每个分段的时长。

3. HLS 工作流程

  1. 编码和分段:原始视频文件被编码为多个不同质量的流(比如 480p、720p、1080p),然后将每个流分割成小的 .ts 文件,每个 .ts 文件通常是几秒钟的内容。
  2. 生成播放列表文件:主播放列表 .m3u8 文件会列出所有可用的流以及它们的码率和分辨率。每个流的播放列表会列出其对应的 .ts 文件。
  3. 客户端请求:客户端请求 .m3u8 播放列表文件后,会根据当前网络状况选择合适的分辨率和码率,逐个请求对应的 .ts 文件进行播放。
  4. 自适应流:客户端会根据带宽动态切换不同的 .ts 分段,保证视频播放的流畅性。例如,当网络带宽变差时,客户端会切换到低分辨率的视频流;带宽恢复时,客户端会切换回高分辨率流。

4. HLS 的优势

  • 适应性强:HLS 支持根据客户端的带宽自动切换不同质量的视频流,保证了用户的观看体验。
  • 广泛兼容:HLS 被许多设备和浏览器原生支持,包括 iOS 设备、Android 设备、Safari 浏览器等。
  • 简单部署:HLS 使用普通的 HTTP 协议进行传输,无需额外的专用流媒体服务器。
  • 支持直播:HLS 可以用于直播流传输,客户端可以实时获取最新的 .ts 文件进行播放。

5. 如何实现 HLS 流式传输

1. 编码和分段

首先,您需要将音视频文件进行编码,并分段。您可以使用工具如 FFmpeg 来执行此操作。

使用 FFmpeg 生成 HLS 流

假设您有一个名为 input.mp4 的视频文件,您想将其转换为 HLS 流并生成对应的 .m3u8 播放列表和 .ts 分段文件。

ffmpeg -i input.mp4 -profile:v baseline -level 3.0 -s 640x360 -start_number 0 -hls_time 10 -hls_list_size 0 -f hls stream.m3u8
  • -i input.mp4:输入视频文件。
  • -profile:v baseline -level 3.0 -s 640x360:设置视频编码器参数,指定分辨率。
  • -hls_time 10:每个 .ts 文件的时长(单位:秒)。
  • -hls_list_size 0:生成无限制长度的播放列表,适合直播。
  • -f hls:指定输出格式为 HLS。

运行后,FFmpeg 会生成一个 stream.m3u8 播放列表文件以及多个 .ts 文件。

2. 部署 HLS 内容

将生成的 .m3u8 播放列表文件和 .ts 分段文件上传到 Web 服务器。您可以使用任何支持 HTTP 的服务器(如 Apache、Nginx 等)来提供这些文件。

配置服务器支持 .m3u8 和 .ts 文件的正确 MIME 类型:

  • .m3u8application/vnd.apple.mpegurl
  • .tsvideo/MP2T

在 Nginx 配置文件中添加如下内容:

server {
    location /hls/ {
        add_header Access-Control-Allow-Origin *;
        add_header Content-Type application/vnd.apple.mpegurl;
        add_header Cache-Control no-cache;
        # 映射 HLS 播放列表和 ts 文件
        root /path/to/hls/files;
    }
}
3. 播放 HLS 流

前端使用 <video> 标签或 HLS 播放器来播放 .m3u8 文件。大多数现代浏览器(如 Safari、Chrome、Firefox 等)都支持 HLS 流媒体播放。您也可以使用像 Video.jshls.js(基于 JavaScript)等播放器来播放 HLS 流。

使用 <video> 标签播放:
<video controls>
    <source src="https://example.com/hls/stream.m3u8" type="application/x-mpegURL">
</video>
使用 HLS.js(适用于不支持 HLS 的浏览器):
<script src="https://cdn.jsdelivr.net/npm/hls.js@latest"></script>
<video id="video" controls></video>

<script>
    var video = document.getElementById('video');
    if(Hls.isSupported()) {
        var hls = new Hls();
        hls.loadSource('https://example.com/hls/stream.m3u8');
        hls.attachMedia(video);
    }
    // HLS.js 不支持时使用 native HTML5 <video> 播放
    else if (video.canPlayType('application/vnd.apple.mpegurl')) {
        video.src = 'https://example.com/hls/stream.m3u8';
    }
</script>

6. 总结

HLS 是一个强大的流媒体协议,适用于音视频文件的流式传输。它通过将音视频内容切割成多个小

;