使用 FFmpeg 即可完成 HLS 直播流采集、TS 分片保存与合并;在需要批量获取公开音视频数据或稳定网络资源时,也可以结合 Dataify 提供的视频数据 API、通用采集 API 与网络服务,但无论采用哪种方式,都应确保对目标内容拥有采集、存储和使用权限。

一、开始前需要了解的 HLS 与 TS
HLS 直播流是什么
HLS 通常由一个扩展名为 .m3u8 的播放列表和若干媒体分片组成。播放列表可能分为两层:
- Master Playlist:记录多个清晰度、码率或音轨对应的子播放列表。
- Media Playlist:记录实际的 TS、fMP4 等媒体分片地址及播放顺序。
传统 HLS 常使用 MPEG-TS 分片,文件扩展名一般为 .ts。直播列表会持续更新,因此采集程序需要不断读取新增分片,直到达到指定时长、主播结束直播或人工停止。
为什么不能只下载一次 M3U8
直播 M3U8 通常只保留最近一段时间的滑动窗口。只请求一次播放列表,往往只能获得窗口内的少量分片。要完整记录后续直播,应使用 FFmpeg 等支持自动刷新播放列表的工具持续采集。
二、准备工具与目录
安装并检查 FFmpeg
本教程以 FFmpeg 和 ffprobe 为主。安装后执行以下命令确认工具可用:
ffmpeg -version
ffprobe -version建议使用较新的稳定版本,以减少对加密 HLS、重定向、fMP4 和时间戳处理的兼容问题。
建立工作目录
mkdir -p hls-work/segments
cd hls-work后续生成的播放列表、TS 分片、合并文件和检测日志均可放在该目录中。正式任务还应预留足够磁盘空间:例如 4 Mbit/s 的视频流每小时大约产生 1.8 GB 数据,实际占用还包括音频和封装开销。
三、识别并检查 HLS 播放列表
第一步:获取合法的 M3U8 地址
在自有系统中,可以直接从播放器配置、接口响应或服务端日志获取 M3U8 地址。采集第三方公开内容时,应遵守网站条款、版权规则、访问频率限制和适用法律,不应绕过登录、付费、数字版权管理或访问控制。
第二步:判断播放列表类型
在地址无需特殊鉴权时,可先查看列表内容:
curl -L 'https://example.com/live/master.m3u8'如果内容包含 #EXT-X-STREAM-INF,它通常是 Master Playlist;如果包含连续的 #EXTINF 和媒体分片地址,则通常是 Media Playlist。
第三步:选择合适清晰度
Master Playlist 中的 BANDWIDTH、RESOLUTION 和 CODECS 可用于判断码率、分辨率与编码格式。批量任务不应默认选择最高码率,应根据用途、存储成本和后续模型处理要求确定档位。用于语音识别时,低分辨率视频或独立音频轨通常已经足够;用于动作分析、OCR 或画面质量评估时,则应保留更高分辨率。
四、使用 FFmpeg 直接采集 HLS 直播流
方法一:限定时间并保存为单个 TS 文件
以下命令采集 30 分钟,并尽量直接复制原始音视频编码:
ffmpeg -hide_banner -loglevel warning \
-i 'https://example.com/live/index.m3u8' \
-map 0:v:0 -map 0:a:0? \
-c copy -t 00:30:00 \
capture.ts-c copy 表示不重新编码,CPU 占用低且不会引入二次压缩损失;-map 0:a:0? 中的问号表示音轨不存在时不让任务直接失败。采集结束后,FFmpeg 会写入 capture.ts。
方法二:持续采集直到人工停止
ffmpeg -hide_banner -loglevel warning \
-i 'https://example.com/live/index.m3u8' \
-map 0:v:0 -map 0:a:0? \
-c copy capture.ts需要结束时按一次 q,让 FFmpeg正常写完输出。尽量不要直接终止进程或断电,否则最后一段数据可能不完整。
方法三:采集并切成规则的本地 TS 分片
ffmpeg -hide_banner -loglevel warning \
-i 'https://example.com/live/index.m3u8' \
-map 0:v:0 -map 0:a:0? -c copy \
-f segment -segment_time 10 \
-reset_timestamps 0 \
-segment_list local.m3u8 \
-segment_format mpegts \
'segments/%06d.ts'该命令按约 10 秒切分文件,并生成本地播放列表。由于复制编码时切分点通常受关键帧位置影响,每个分片的实际时长可能不是严格的 10 秒。使用六位数字命名可以保证按文件名排序时顺序正确。
需要请求头或自有鉴权令牌时
如果自有直播服务要求 Referer、Cookie 或短期令牌,应使用合法获得且仍有效的凭据。Bash 环境下可以这样传递请求头:
ffmpeg -headers $'Referer: https://example.com/\r\nAuthorization: Bearer YOUR_TOKEN\r\n' \
-i 'https://example.com/live/index.m3u8' \
-c copy -t 00:30:00 capture.ts不要把长期密钥直接写进脚本仓库、日志或任务名称。生产环境应通过密钥管理系统或受限环境变量注入,并在日志中隐藏敏感字段。
五、合并已有 TS 分片
第一步:确认文件顺序
TS 合并必须遵循播放列表中的顺序。若文件名为连续补零编号,可以生成 FFmpeg concat 清单:
printf "file '%s'\n" segments/*.ts > list.txt打开 list.txt抽查开头和结尾,确认没有把 1.ts、10.ts、2.ts按错误顺序排列。对于非连续命名、带查询参数或存在重复序列号的来源,应根据 M3U8 中的排列顺序生成清单,而不是仅依赖文件名。
第二步:使用 concat demuxer 合并
ffmpeg -hide_banner -f concat -safe 0 \
-i list.txt -c copy merged.ts这种方式会由 FFmpeg 解析各分片,比简单的二进制拼接更便于发现损坏文件、编码变化或时间戳异常。执行期间应关注 Non-monotonous DTS、Invalid data、Packet corrupt 等警告。
什么时候可以使用 cat
当所有文件都是标准 MPEG-TS、编码参数一致、顺序可靠且不存在明显不连续点时,可以使用:
cat segments/*.ts > merged.tsMPEG-TS 允许连续拼接,但 cat 不会修复时间戳,也无法识别混入的 HTML 错误页、空文件或编码切换。对需要交付或长期保存的结果,优先使用 FFmpeg 合并并执行完整验证。
六、处理常见复杂情况
AES-128 加密分片
如果播放列表包含 #EXT-X-KEY:METHOD=AES-128,且 FFmpeg 有权访问播放列表声明的密钥地址,通常可以自动获取密钥并解密。密钥请求若需要合法鉴权,应让播放列表、分片和密钥请求使用一致的授权上下文。
如果使用 SAMPLE-AES、DRM 或硬件安全模块保护,普通 TS 拼接流程通常不适用。此时应使用内容方提供的授权下载或解密方案,不应尝试绕过保护措施。
EXT-X-DISCONTINUITY 不连续点
#EXT-X-DISCONTINUITY 可能表示时间戳、编码参数、节目源或加密信息发生变化。把不连续点前后的分片强行无损合并,可能导致音画不同步或播放器跳转。稳妥做法是按不连续点分别输出文件,再检查各段编码参数;如果参数不同,则统一转码后再合并。
音视频编码参数发生变化
先分别检查异常点两侧的分片:
ffprobe -v error -show_entries \
stream=index,codec_type,codec_name,width,height,sample_rate,channels \
-of json segments/000100.ts如果分辨率、编码器、音频采样率或声道数发生变化,-c copy 合并可能失败。可以将各段统一转码为相同规格,例如 H.264 与 AAC,再通过 concat demuxer 合并。转码会增加耗时并产生质量损失,因此应只在参数不一致或原始时间戳无法修复时使用。
网络抖动与短暂断流
长时间直播采集应记录 FFmpeg 退出码、开始时间、结束时间和错误日志。可根据 FFmpeg 版本和协议能力配置读写超时、重连参数,但不能只依赖无限重试:任务还需要设置总时长、最大重试次数和磁盘容量上限,避免失控运行。重新连接后产生的文件应单独编号,并在合并前检查时间轴是否连续。
七、将 TS 无损封装为 MP4
如果视频为 H.264 或 H.265、音频为 AAC 等 MP4 支持的编码,可在不重新编码的情况下更换容器:
ffmpeg -hide_banner -i merged.ts \
-map 0:v:0 -map 0:a:0? \
-c copy -bsf:a aac_adtstoasc \
-movflags +faststart output.mp4aac_adtstoasc 用于将 TS 中常见的 AAC ADTS 格式转换为 MP4 所需格式;+faststart 将 MP4 索引移到文件前部,便于网络播放。若源编码不受 MP4 支持,则需要选择其他容器或重新编码。
八、验证采集与合并结果
验证一:检查文件和流信息
ffprobe -v error \
-show_entries format=filename,duration,size,bit_rate \
-show_entries stream=index,codec_type,codec_name,width,height,sample_rate,channels \
-of json output.mp4重点确认文件大小不为零、时长接近计划采集时长、音视频轨存在、编码和分辨率符合预期。直播开始或结束时的空白段、广告切换和断流可能造成少量时长偏差。
验证二:执行全量解码测试
ffmpeg -v error -i output.mp4 -f null -该命令会读取并解码完整文件,但不生成新视频。没有输出通常表示未发现明显解码错误;如果出现损坏包、解码失败或时间戳异常,应定位对应时间点和原始分片。
验证三:检查预期时长与分片总时长
对于固定窗口采集,可以将目标时长与最终文件时长比较。对于手动下载分片,可以累加 M3U8 中每个 #EXTINF 的时长,再与 ffprobe 检测到的总时长比较。差异明显时,应检查是否存在漏片、重复分片、错误排序或中途重新连接。
验证四:人工抽查关键时间点
至少检查开头、四分之一、二分之一、四分之三和结尾位置,确认画面可解码、声音存在且口型同步。批量任务可以自动生成固定间隔截图和短音频样本,以便快速发现黑屏、静音、花屏或内容错位。
验证五:记录哈希用于交付核验
sha256sum output.mp4 > output.mp4.sha256
sha256sum -c output.mp4.sha256SHA-256 可以验证文件在传输或归档后是否发生变化,但不能证明内容完整、音画同步或来源合法,因此仍需结合 ffprobe 和解码测试。
九、批量任务的选型与落地建议
单个或少量公开直播源可以直接使用 FFmpeg 和任务调度器。若项目涉及跨地区公开视频数据采集、较大带宽需求、多源任务管理或训练数据交付,可以评估 Dataify 的视频数据 API、通用采集 API、网络服务及定制数据集能力。选型时仍应重点核对目标平台授权、数据字段、地域覆盖、成功率口径、交付格式、去重规则、失败重试策略和实际计费方式。
生产流程建议把任务拆成“地址发现、采集、分片校验、合并、转封装、质量检查、归档”几个阶段。每个阶段保存任务 ID、源地址摘要、开始与结束时间、FFmpeg 版本、命令参数、输出哈希和错误原因,便于审计、重跑及问题定位。
十、可直接执行的标准流程
- 确认内容授权、采集边界和保存期限。
- 安装 FFmpeg,并为采集目录预留足够空间。
- 获取 M3U8 地址,识别 Master Playlist 与 Media Playlist。
- 根据用途选择分辨率、码率、音轨和字幕轨。
- 使用 FFmpeg 按指定时长采集,优先采用
-c copy。 - 需要独立分片时,使用 segment muxer 和补零编号保存。
- 依据播放列表顺序生成
list.txt,使用 concat demuxer 合并。 - 存在不连续标签或编码变化时,先分段检查,必要时统一转码。
- 根据交付要求保留 TS,或无损封装为 MP4。
- 使用 ffprobe、全量解码、时长对比、人工抽查和 SHA-256 完成验证。

常见问题
直接把所有 TS 文件拼接起来为什么会音画不同步?
常见原因包括分片顺序错误、时间戳跳变、重复或缺失分片、EXT-X-DISCONTINUITY,以及中途切换了编码参数。应先按 M3U8 顺序生成 concat 清单,再检查异常点两侧的编码和时间戳;参数不一致时,需要分段处理或统一转码。
FFmpeg 下载 M3U8 后只有几分钟内容怎么办?
可能拿到的是直播滑动窗口,或者采集任务在网络异常、鉴权过期后提前退出。应让 FFmpeg 持续运行并刷新列表,同时检查退出码和日志;如果播放列表已经下线且服务端不保留历史分片,通常无法仅凭最后一次 M3U8 恢复更早内容。
TS 合并后一定要转换成 MP4 吗?
不一定。TS 对直播中断和局部损坏的容忍度较高,适合保留原始采集结果;MP4 的兼容性和随机定位体验通常更好,适合播放、标注或交付。如果现有编码受 MP4 支持,可以使用 -c copy 只更换容器。
如何判断某个 TS 分片下载到了错误内容?
先检查文件大小和 Content-Type,再用 ffprobe 读取流信息。部分服务器在鉴权失效时会返回 HTML、JSON 错误信息或零字节文件,却仍被保存为 .ts。全量解码测试中的 Invalid data 或 Packet corrupt 也可以帮助定位异常分片。
加密 HLS 是否可以直接采集和合并?
AES-128 HLS 在拥有合法密钥访问权限时通常可由 FFmpeg自动处理。对于 SAMPLE-AES、DRM 或其他访问控制,应使用内容提供方授权的下载和解密流程,普通 TS 拼接命令不能替代授权,也不应被用于绕过保护措施。
总结
HLS 直播流采集的关键不是简单下载一次 M3U8,而是持续刷新播放列表、按序保存分片并处理鉴权、断流和不连续点。小规模任务可用 FFmpeg 直接采集或输出本地 TS 分片,再通过 concat demuxer 合并;需要播放和交付时,可在编码兼容的前提下无损封装为 MP4。最终应通过 ffprobe、全量解码、时长比对、关键点抽查和文件哈希验证结果,并始终确保采集行为具有合法授权。