在本教程中,我们将学习使用 FFmeg 进行 HLS 打包。使用 FFmpeg 的最大好处是您可以摄取视频、调整其大小、转码、打包和流式传输,而无需离开命令行!
我们将首先查看为 VOD 创建 HLS 打包的所有步骤,然后查看 HLS Live Streaming 的打包。
使用 FFmpeg 进行 HLS 打包的基本步骤
好的,让我们看看使用 HLS 打包 VOD 文件的基本步骤是什么?
- 从磁盘读取输入视频。
- 将视频缩放/调整为所需的多种分辨率。
- 将每个缩放后的视频转码为所需的比特率
- 将音频转码为所需的比特率。
- 组合视频和音频,打包每个组合,并创建单独的 TS 片段和播放列表。
- 创建指向每个变体的主播放列表。
现在,让我们逐步解决这个问题,好吗?
使用 FFmpeg 将视频调整为多种分辨率
好的,第 1 步和第 2 步涉及从磁盘读取视频并将其缩放为多种分辨率。这可以在一个命令中完成,如下所示 –
ffmpeg -i brooklynsfinest_clip_1080p.mp4 \
-filter_complex \
"[0:v]split=3[v1][v2][v3];\
[v1]copy[v1out];\
[v2]scale=w=1280:h=720[v2out];\
[v3]scale=w=640:h=360[v3out]"
[0:v]
指的是输入文件的第一个视频流。在我们的例子中,只有一个视频流,它被分成 3 个输出[v1], [v2], [v3]
。这些中的每一个都被作为 FFmpeg 中接受高度和宽度数字的缩放函数的输入。
在这里,我们将输入视频缩放为 1080p、720p 和 360p。
并且 , ,[v1out]
是包含缩放过程输出的变量。请注意,这里我们假设缩放过程将保持纵横比。否则,您可以强制执行并在必要时应用信箱。
使用 FFmpeg 将视频转码为多个比特率以进行 HLS 打包
接下来,我们继续进行第 3 步和第 4 步——我们必须将视频转码为多种比特率,就像 ABR 视频流通常所做的那样。
请记住,我们已经以所需的分辨率缩放视频并将输出存储在[v1out]
、[v2out]
和[v3out]
中。让我们直接将它们用作转码步骤的输入。
-map [v1out] -c:v:0 libx264 -x264-params "nal-hrd=cbr:force-cfr=1" -b:v:0 5M -maxrate:v:0 5M -minrate:v:0 5M -bufsize:v:0 10M -preset slow -g 48 -sc_threshold 0 -keyint_min 48 \
-map [v2out] -c:v:1 libx264 -x264-params "nal-hrd=cbr:force-cfr=1" -b:v:1 3M -maxrate:v:1 3M -minrate:v:1 3M -bufsize:v:1 3M -preset slow -g 48 -sc_threshold 0 -keyint_min 48 \
-map [v3out] -c:v:2 libx264 -x264-params "nal-hrd=cbr:force-cfr=1" -b:v:2 1M -maxrate:v:2 1M -minrate:v:2 1M -bufsize:v:2 1M -preset slow -g 48 -sc_threshold 0 -keyint_min 48 \
-map a:0 -c:a:0 aac -b:a:0 96k -ac 2 \
-map a:0 -c:a:1 aac -b:a:1 96k -ac 2 \
-map a:0 -c:a:2 aac -b:a:2 48k -ac 2 \
你能看到这里做了什么吗?我们已将三个变量[v1out]
,[v2out]
和[v3out]
作为我们的输入,并使用libx264
的slow
预设以所需的比特率对每个输入进行转码。
注意:您也可以选择自己的编码参数并根据自己的喜好和要求进行修改。在此示例中,我使用了一些简单的参数来模拟 CBR 编码。可能有无数种使用 FFmpeg 对视频进行转码的方法。您可以在预设、crf 值、CBR 设置等的组合之间进行选择。
重要的是,我们设置了周期性强制关键帧的-keyint_min
值,48
因为这在 ABR 流中非常重要。
现在,我们继续下一步,即为m3u8
每个演绎版/变体创建一个 HLS 播放列表文件。
使用 FFmpeg 创建 HLS 播放列表 (m3u8)
现在我们有了将视频转码为多种比特率变体的命令,让我们开始创建 HLS VOD 播放列表 FFmpeg。
HLS 打包所需的一些重要设置是 –
hls_playlist_type=vod
:通过设置此值,FFmpeg 创建一个 VOD 播放列表,将 #EXT-X-PLAYLIST-TYPE:VOD 插入 m3u8 标头并强制 hls_list_size 为 0。hls_time seconds
:我们需要用它来设置目标段长度(以秒为单位)。- 默认值为 2 秒,段将在该时间过后的下一个关键帧处被剪切。
- 这就是为什么我们必须确保每个比特流变体在每 N 秒结束时都有一个关键帧,以便它们相互对齐。
hls_segment_type
:这有两个值——mpegts 或 fmp4,并创建 TS 段或 fmp4 (CMAF) 段,这对于为 HLS 和 DASH 创建一组流很有用。-hls_flags independent_segments
:#EXT-X-INDEPENDENT-SEGMENTS
当播放列表的所有片段都保证以关键帧开始时,将 添加到播放列表。hls_segment_filename filename
:这用于命名在打包过程中创建的段。
这是为单个视频文件创建播放列表的示例:
-f hls \
-hls_time 2 \
-hls_playlist_type vod \
-hls_flags independent_segments \
-hls_segment_type mpegts \
-hls_segment_filename stream_%v/data%02d.ts \
-var_stream_map “v:0,a:0 v:1,a:1 v:2,a:2” stream_%v/stream.m3u8
如果您看到最后一行,您会注意到一个名为var_stream_map
. 这是做什么的?
var_stream_map
是一个 FFmpeg 函数,可帮助我们组合各种视频和音频转码以创建不同的 HLS 播放列表。如果您有两个使用相同视频但不同音频的演绎版,那么您可以选择不同的视频和音频版本并将它们连接在一起,而不是为了创建不同的播放列表而创建多个编码。
例如,表示由表示的音频流用于所有三个视频再现。-var_stream_map "v:0,a:0 v:1,a:0 v:2,a:0"
a:0
FFmpeg 获取这些视频-音频组合并使用名称创建各个变体的.m3u8
文件stream_%v.m3u8
where%v
是一个从被打包的流编号中获取其值的迭代器。
使用 FFmpeg 创建 HLS 主播放列表 (m3u8)
如果您了解如何使用 FFmpeg 创建 HLS 播放列表,那么使用 FFmpeg 创建主播放列表就非常简单。如果您不知道什么是主播放列表,它只是一个文件,其中列出了使用 HLS 打包的各个变体的播放列表。
要使用 FFmpeg 创建主播放列表,只需将关键字添加-master_pl_name
到 FFmpeg 命令并提供要分配给主播放列表的名称。例如,如果我想将主播放列表称为“master.m3u8”,那么我所要做的就是
-master_pl_name master.m3u8
而已。在 FFmpeg 使用命令行完成后,您将拥有一个 HLS 主播放列表,其中列出了其他播放列表的名称。
使用 FFmpeg 进行 HLS 打包的最终脚本 – VOD
ffmpeg -i brooklynsfinest_clip_1080p.mp4 \
-filter_complex \
"[0:v]split=3[v1][v2][v3]; \
[v1]copy[v1out]; [v2]scale=w=1280:h=720[v2out]; [v3]scale=w=640:h=360[v3out]" \
-map [v1out] -c:v:0 libx264 -x264-params "nal-hrd=cbr:force-cfr=1" -b:v:0 5M -maxrate:v:0 5M -minrate:v:0 5M -bufsize:v:0 10M -preset slow -g 48 -sc_threshold 0 -keyint_min 48 \
-map [v2out] -c:v:1 libx264 -x264-params "nal-hrd=cbr:force-cfr=1" -b:v:1 3M -maxrate:v:1 3M -minrate:v:1 3M -bufsize:v:1 3M -preset slow -g 48 -sc_threshold 0 -keyint_min 48 \
-map [v3out] -c:v:2 libx264 -x264-params "nal-hrd=cbr:force-cfr=1" -b:v:2 1M -maxrate:v:2 1M -minrate:v:2 1M -bufsize:v:2 1M -preset slow -g 48 -sc_threshold 0 -keyint_min 48 \
-map a:0 -c:a:0 aac -b:a:0 96k -ac 2 \
-map a:0 -c:a:1 aac -b:a:1 96k -ac 2 \
-map a:0 -c:a:2 aac -b:a:2 48k -ac 2 \
-f hls \
-hls_time 2 \
-hls_playlist_type vod \
-hls_flags independent_segments \
-hls_segment_type mpegts \
-hls_segment_filename stream_%v/data%02d.ts \
-master_pl_name master.m3u8 \
-var_stream_map "v:0,a:0 v:1,a:1 v:2,a:2" stream_%v.m3u8
让我们看看这个脚本的输出。
它首先生成一个主播放列表、三个包含各个片段的文件夹以及变体的播放列表。
这是master.m3u8
文件的样子 –
#EXTM3U
#EXT-X-VERSION:6
#EXT-X-STREAM-INF:BANDWIDTH=5605600,RESOLUTION=1920x1080,CODECS="avc1.640032,mp4a.40.2"
stream_0.m3u8
#EXT-X-STREAM-INF:BANDWIDTH=3405600,RESOLUTION=1280x720,CODECS="avc1.64001f,mp4a.40.2"
stream_1.m3u8
#EXT-X-STREAM-INF:BANDWIDTH=1205600,RESOLUTION=640x360,CODECS="avc1.64001e,mp4a.40.2"
stream_2.m3u8
您可以看到主播放列表引用了 1080p、720p 和 360p HLS 变体的各个播放列表。
现在,让我们看看 1080p HLS 变体是什么样的。它明确表示这是一个 VOD 播放列表,片段是独立的,每个片段的长度为 2 秒(根据我们的设置)。
#EXTM3U
#EXT-X-VERSION:6
#EXT-X-TARGETDURATION:2
#EXT-X-MEDIA-SEQUENCE:0
#EXT-X-PLAYLIST-TYPE:VOD
#EXT-X-INDEPENDENT-SEGMENTS
#EXTINF:2.002000,
data00.ts
#EXTINF:2.002000,
data01.ts
#EXTINF:2.002011,
data02.ts
#EXTINF:2.002000,
data03.ts
#EXTINF:2.002000,
data04.ts
#EXTINF:2.002000,
data05.ts
#EXTINF:2.002000,
data06.ts
#EXTINF:2.002000,
data07.ts
#EXTINF:2.002011,
data08.ts
#EXTINF:2.002000,
data09.ts
#EXTINF:0.041711,
data10.ts
#EXT-X-ENDLIST
使用 FFmpeg 直播 HLS 打包
如果您想使用 FFmpeg 创建实时 HLS 播放列表,那么该过程与我们刚刚介绍的 VOD 步骤没有太大区别。以下是您需要进行的一些更改。
- 消除
-hls_playlist_type vod
- 添加
-hls_list_size
并将其设置为一个数字,该数字表示您希望在各个变体的播放列表中包含的片段数。
例如,如果我们设置-hls_list_size
为2
,那么播放列表将只包含两个片段,FFmpeg 将通过添加新片段并移出旧片段来重写该播放列表。
这是一个例子——
#EXTM3U
#EXT-X-VERSION:6
#EXT-X-TARGETDURATION:2
#EXT-X-MEDIA-SEQUENCE:1
#EXT-X-INDEPENDENT-SEGMENTS
#EXTINF:2.002000,
data01.ts
#EXTINF:2.002011,
data02.ts
几秒钟后, segmentdata01.ts
被丢弃并被 segment 取代data03.ts
。
#EXTM3U
#EXT-X-VERSION:6
#EXT-X-TARGETDURATION:2
#EXT-X-MEDIA-SEQUENCE:2
#EXT-X-INDEPENDENT-SEGMENTS
#EXTINF:2.002011,
data02.ts
#EXTINF:2.002000,
data03.ts
FFmpeg 中其他有用的 HLS 打包选项
最后,让我们快速浏览一下 FFmpeg 提供的一些有趣的选项,用于 HLS Packaging for VOD 和 Live Streaming。
hls_base_url baseurl
:这可用于将baseurl表示的值附加 到播放列表中的每个条目。hls_fmp4_init_filename filename
: 将文件名设置为片段文件头文件,默认文件名是 初始化.mp4. 当您将段类型设置为fmp4
而不是时使用mpegts
。hls_fmp4_init_resend
: 每次m3u8文件刷新后重新发送init文件,默认为 .iframes_only
:添加#EXT-X-I-FRAMES-ONLY
到有视频片段且只能播放I帧#EXT-X-BYTERANGE
模式的播放列表。
结论
到目前为止,我希望您已经很好地了解了如何使用 FFmpeg 对使用 HLS 流协议的视频进行转码和打包。有关使用 FFmpeg 进行 HLS 打包的完整选项列表,请查看 FFmpeg 文档。在以后的文章中,我们将介绍使用带加密的 FFmpeg 进行 HLS 打包。
作者简介:Krishna Rao Vijayanagar 博士,OTTVerse 的创始人。
版权声明:本文内容转自互联网,本文观点仅代表作者本人。本站仅提供信息存储空间服务,所有权归原作者所有。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至1393616908@qq.com 举报,一经查实,本站将立刻删除。