广告
— 广告位 In-Article —

HLS 直播系统架构

一套完整的 HLS 直播链路包含四个环节:

  1. 推流端:OBS / FFmpeg 将摄像头或屏幕画面编码为 H.264+AAC,通过 RTMP 协议推送到流媒体服务器
  2. 流媒体服务器:接收 RTMP 推流,实时切割成 2-6 秒的 .ts 片段,并动态更新 M3U8 播放列表
  3. CDN 分发(可选):将 M3U8 和 TS 文件缓存到全球节点,降低源站压力
  4. 播放端:浏览器通过 HLS.js,或移动端通过 AVPlayer,拉取 M3U8 播放

OBS 推流设置

在 OBS 中配置推流:设置 → 串流 → 服务选择「自定义」,填入以下参数:

参数推荐值说明
服务器rtmp://your-server-ip/live流媒体服务器地址
推流码stream_key(自定义)区分不同推流来源
编码器x264 或 硬件编码有 GPU 用硬件编码节省 CPU
码率2500-6000 kbps720p 用 2500,1080p 用 4000-6000
关键帧间隔2 秒必须设置,影响切片精度

Nginx-rtmp 服务器配置

# nginx.conf
rtmp {
  server {
    listen 1935;
    chunk_size 4096;

    application live {
      live on;
      record off;

      # 开启 HLS 切片
      hls on;
      hls_path /tmp/hls;        # 切片文件存储路径
      hls_fragment 3s;          # 每个 TS 片段时长
      hls_playlist_length 12s;  # M3U8 列表保留时长

      # 允许任意来源推流(生产环境应限制 IP)
      allow publish all;
      allow play all;
    }
  }
}

http {
  server {
    listen 8080;

    location /hls {
      types {
        application/vnd.apple.mpegurl m3u8;
        video/mp2t ts;
      }
      root /tmp;
      add_header Cache-Control no-cache;
      add_header Access-Control-Allow-Origin *;
    }
  }
}

使用 SRS 替代方案

SRS(Simple Realtime Server)是另一个优秀的流媒体服务器,配置更简单,性能更好,支持 HTTP-FLV 和 WebRTC,推荐国内用户使用:

# SRS 最简 HLS 配置(conf/srs.conf)
listen              1935;
http_server {
  enabled on;
  listen 8080;
}
vhost __defaultVhost__ {
  hls {
    enabled on;
    hls_fragment 3;
    hls_window 12;
    hls_path ./objs/nginx/html;
  }
}

推流后,M3U8 地址为:http://server-ip:8080/live/stream_key.m3u8

StreamFlow 播放器 中输入该地址,即可验证直播流是否正常推送。

延迟优化:hls_fragment 设置为 2s(Nginx)或 2(SRS)可将端到端延迟降至 6-10 秒。进一步降低延迟(<4s)需要使用 LL-HLS,配置更复杂。

CDN 接入注意事项

接入 CDN 后,M3U8 文件和 TS 文件的缓存策略要分开处理。M3U8 文件内容每隔几秒就会更新,必须设置 Cache-Control: no-cache 或极短的 TTL(如 5 秒);TS 片段文件名唯一,内容不变,可以长期缓存(Cache-Control: max-age=86400),大幅减少源站回源压力。

💡 直播运维常见问题
  • 推流中断后 M3U8 列表仍可访问:Nginx-rtmp 默认不会立即清除旧的 M3U8,设置 hls_cleanup on 可在推流结束后自动删除切片
  • 播放器报"网络错误"但推流正常:99% 是 CORS 配置问题,检查 HTTP 响应头中是否有 Access-Control-Allow-Origin
  • 直播延迟越来越大:播放器累积了大量缓冲,检查 liveSyncDurationCount 配置,或让播放器跳到最新片段
  • OBS 推流绿屏/花屏:通常是关键帧间隔设置不对,确保设置为固定 2 秒,不要用"自动"
  • 多人同时观看时源站压力大:立即接入 CDN,不要让播放器直接连源站