HTTP Live Streaming (HLS) — 是由Apple公司开发的自适应媒体数据传输协议。HLS通过HTTP连接传输视频和音频,将内容分割成一系列小文件片段,并通过M3U8格式的文本播放列表管理播放。根据Sandvine Internet Phenomena Report(2025),HLS处理全球超过65%的自适应视频流媒体流量。该协议在所有Apple平台上得到支持,并通过第三方库在Android、Windows和Smart TV上可用。
要点
HTTP Live Streaming (HLS) — 是由Apple于2009年开发的媒体流协议,首次在iOS 3.0和Safari中推出。2017年,该协议通过RFC 8216被提出作为互联网标准,确认了其作为开放规范的地位,可在任何平台上实现。
HLS的主要思想是分割连续的媒体流为2-10秒的短片段。每个片段是一个独立的文件,可以通过普通的HTTP请求下载。流的管理通过M3U8格式的文本播放列表进行,这些播放列表包含片段的链接和正确播放所需的元数据。
自适应性 — 是HLS的关键优势。服务器准备同一内容的多个版本,具有不同的比特率——从弱连接的200 Kbps到4K视频的20+ Mbps。客户端根据当前信道带宽自动选择合适的比特率。根据Apple的研究(WWDC 2024),LL-HLS将比特率之间的切换时间减少到500毫秒,确保质量的无缝切换而不会出现明显停顿。
第一版 HLS(2009)仅支持带有AAC音频编解码器和H.264视频编解码器的MPEG-2 TS片段。在iOS 8(2014)中增加了对fMP4(分片MP4)片段的支持,使得HLS可以使用更现代的编解码器,包括HEVC(H.265)。iOS 11(2017)引入了HDR10和Dolby Vision支持。iOS 13(2019)引入了Low-Latency HLS,将延迟从传统的6-30秒降低到2-6秒。
2023年,Apple扩展了HLS对AV1和EVC(Essential Video Coding)编解码器的支持,并实施了Content Steering——一种在CDN服务器之间动态重定向客户端以优化加载的机制。Content Steering允许服务器实时更改片段的URL,将客户端重定向到最近或负载最少的CDN节点,而不会中断播放。
HLS架构由三个主要组件组成:服务器部分(源服务器+编码器)、分发网络(CDN)和客户端部分(支持HLS的播放器)。整个过程——从视频采集到用户设备上的播放——包括多个连续的阶段,每个阶段对流媒体质量都至关重要。
源视频首先被编码为具有不同比特率和分辨率的多个变体。专业编码器如FFmpeg或AWS Elemental MediaConvert同时创建4-12个流变体:从240p(400 Kbps)到4K(40 Mbps)。每个变体被切割成相同持续时间的片段,通常LL-HLS为2-6秒,传统HLS为6-10秒。
为每个变体创建一个媒体播放列表(variant playlist),其中包含所有片段的URL及其持续时间。此外,还创建一个主播放列表(master playlist),它结合了所有变体并包含每个变体的信息:分辨率、比特率、编解码器和音轨。客户端首先下载主播放列表,然后根据连接速度分析选择合适的变体。
片段和播放列表缓存在地理上靠近用户的CDN服务器上。使用标准HTTP协议进行传输为HLS带来了关键优势:任何支持HTTP的CDN、负载均衡器或代理服务器都可以无需额外配置地与HLS配合工作。这使HLS与需要专用服务器的RTMP或WebRTC等实时协议区别开来。
import subprocess
subprocess.run([
"ffmpeg",
"-i", "input.mp4",
"-codec:v", "libx264",
"-codec:a", "aac",
"-hls_time", "6",
"-hls_list_size", "0",
"-var_stream_map", "v:0,a:0 v:1,a:1",
"-map", "v:0", "-b:v:0", "5000k",
"-map", "v:1", "-b:v:1", "1000k",
"-f", "hls",
"stream/output.m3u8"
])
客户端侧使用比特率选择算法(ABR — Adaptive Bitrate)。HLS播放器下载主播放列表,分析可用变体,并以最合适的比特率开始播放。在播放过程中,播放器持续监控片段的下载速度和缓冲填充情况,决定切换到更高或更低的比特率。现代ABR算法不仅考虑网络速度,还考虑缓冲区大小、内容类型,甚至设备的功耗。
理解HLS流的结构对于正确配置编码、分发和调试播放问题至关重要。每个HLS流由两个级别的播放列表和众多媒体片段组成,这些片段按照严格的层次结构组织。
Master playlist — 是HLS播放器的入口点。扩展名为.m3u8的文件包含所有流变体(variant streams)的链接及其特征。播放器首先下载此文件,并根据比特率和分辨率的信息做出变体选择的初始决定。主播放列表还可以包含替代音轨、字幕和用于快速快进的I-Frame播放列表的链接。
#EXTM3U
#EXT-X-STREAM-INF:BANDWIDTH=5000000,RESOLUTION=1920x1080
1080p/video.m3u8
#EXT-X-STREAM-INF:BANDWIDTH=1000000,RESOLUTION=640x360
360p/video.m3u8
Media playlist 直接包含一个流变体的片段列表。每个片段都指定了持续时间和URI。媒体播放列表可以是静态的(用于VOD——所有片段的完整列表)或动态更新的(用于直播——旧片段被删除,新片段被添加)。
#EXTM3U
#EXT-X-TARGETDURATION:6
#EXTINF:6.000,
segment001.ts
#EXTINF:6.000,
segment002.ts
#EXT-X-ENDLIST
HLS支持两种主要的媒体片段格式:MPEG-2 Transport Stream(.ts)和Fragmented MP4(.m4s或.mp4)。MPEG-2 TS——原始的HLS格式,提供最大的兼容性。fMP4——更现代的格式,支持HDR、HEVC和更高效的压缩。Apple建议从iOS 10和macOS Sierra开始的所有新项目使用fMP4。
HLS流的其他元素包括用于快速快进的I-Frame播放列表、用于同步字幕和广告标记的ID3元数据,以及用于将观看信息传输到分析服务器的Session Data。所有这些元素都是可选的,但它们的使用可以提高用户体验的质量。
HLS凭借一系列架构优势在视频流媒体市场占据主导地位,但在为特定项目选择协议时也存在需要考虑的限制。让我们将HLS与替代视频传输协议进行比较。
| 特性 | HLS | DASH | RTMP |
|---|---|---|---|
| 传输 | HTTP (80/443) | HTTP (80/443) | TCP (1935) |
| 自适应性 | 是 (ABR) | 是 (ABR) | 否 |
| 低延迟 | 2-6秒 (LL-HLS) | 3-8秒 (LL-DASH) | 0.5-2秒 |
| HDR支持 | 是 (iOS 11+) | 是 | 有限 |
| 原生iOS | 是 (Safari, AVPlayer) | 通过第三方播放器 | 否 |
| CDN简便性 | 最大 (HTTP) | 最大 (HTTP) | 专用服务器 |
HLS的主要优势 — 通过内置的AVPlayer在所有Apple设备(iPhone、iPad、Apple TV、Mac)上获得原生支持。这使得HLS成为iOS/macOS应用程序的事实标准。此外,使用标准HTTP进行传输允许在任何CDN和代理服务器上无需额外配置即可缓存内容,这大大简化了传输基础设施。
HLS的缺点包括直播时与RTMP或WebRTC相比更高的延迟。即使使用LL-HLS,最小延迟也有2-6秒,这对于实时交互场景是不可接受的。此外,HLS在服务器上生成更多文件(每个片段是一个单独的文件),在大量同时直播时可能会对文件系统造成负载。
HLS在移动应用中的集成因平台而异。在iOS和macOS上,HLS通过AVFoundation和AVPlayer在操作系统级别得到支持,提供硬件加速解码和最小功耗。在Android上,HLS不受内置MediaPlayer支持,但可通过Google的官方媒体播放器ExoPlayer使用。
在Apple平台上,HLS播放由于AVPlayer的内置支持而极为简单。只需创建一个带有主播放列表URL的AVPlayer,系统将自动处理自适应比特率切换、音轨选择和处理字幕。同时,开发人员可以通过AVPlayerItem和AVAssetResourceLoader完全控制播放。
import AVFoundation
let url = URL(string: "https://example.com/stream.m3u8")!
let player = AVPlayer(url: url)
let controller = AVPlayerViewController()
controller.player = player
present(controller, animated: true) {
player.play()
}
对于Android,使用ExoPlayer,它通过单独的扩展模块支持HLS。ExoPlayer提供对HLS流更精细的控制:可以管理比特率选择、配置缓冲和单独处理片段加载错误。LL-HLS需要ExoPlayer 2.14.0及更高版本。
val player = ExoPlayer.Builder(this).build()
val uri = Uri.parse("https://example.com/stream.m3u8")
val mediaItem = MediaItem.fromUri(uri)
player.setMediaItem(mediaItem)
player.prepare()
player.play()
由于蜂窝网络的不稳定性和流量限制,移动应用需要特殊的HLS配置方法。主要建议包括:根据网络类型(Wi-Fi或蜂窝)设置初始比特率,使用较短的片段持续时间(2-4秒)以实现更快的适应,切换到Wi-Fi时预加载缓冲,以及在信号弱时优先处理音轨。
Apple在HLS Authoring Specification for Apple Devices(2024)文档中建议移动设备的片段大小不超过6秒,并且至少提供4个比特率变体。为了节省移动网络的流量,服务器应使用Cache-Control HTTP标头提供片段,允许在电信运营商的中间代理服务器上缓存内容。
常见问题
MP4 — 是存储整个视频文件的容器,必须在开始播放前完全下载。HLS将视频分割成小片段,允许在下载第一个片段后2-6秒内开始观看,并自动根据互联网速度调整质量。
是的,HLS不需要Apple服务器软件。任何HTTP服务器(Nginx、Apache、CDN)都可以分发HLS内容。将视频编码为HLS使用FFmpeg或专业编码器。唯一的要求是为.m3u8文件正确配置MIME类型。
是的,HLS最初是为直播设计的。在直播中,媒体播放列表会动态更新:服务器添加新片段并删除旧片段。Low-Latency HLS(LL-HLS)将延迟减少到2-6秒,使HLS适用于体育直播和新闻广播。
Master playlist 将同一内容的所有变体与不同比特率和分辨率组合在一起。播放器首先下载它,分析每个变体的特性(比特率、分辨率、编解码器),并为当前网络条件选择最优的变体。没有主播放列表,就无法实现自适应质量切换。
HLS支持片段的AES-128加密以及与DRM系统的集成:FairPlay Streaming(Apple)、Widevine(Google)和PlayReady(Microsoft)。加密密钥通过单独的安全通道传输。为了额外保护,使用令牌认证来访问播放列表。
总结
我们将开发一款交钥匙移动应用程序
IT Sectr自2017年以来为初创企业和企业打造iOS和Android应用程序。我们将为您提供咨询并提出最佳解决方案。