使用 FFmpeg 进行 HLS 打包的分步教程

在本教程中,我们将学习使用 FFmeg 进行 HLS 打包。使用 FFmpeg 的最大好处是您可以摄取视频、调整其大小、转码、打包和流式传输,而无需离开命令行!

我们将首先查看为 VOD 创建 HLS 打包的所有步骤,然后查看 HLS Live Streaming 的打包。

使用 FFmpeg 进行 HLS 打包的基本步骤

好的,让我们看看使用 HLS 打包 VOD 文件的基本步骤是什么?

  1. 从磁盘读取输入视频。
  2. 将视频缩放/调整为所需的多种分辨率。
  3. 将每个缩放后的视频转码为所需的比特率
  4. 将音频转码为所需的比特率。
  5. 组合视频和音频,打包每个组合,并创建单独的 TS 片段和播放列表。
  6. 创建指向每个变体的主播放列表。

现在,让我们逐步解决这个问题,好吗?

使用 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]作为我们的输入,并使用libx264slow预设以所需的比特率对每个输入进行转码。

注意:您也可以选择自己的编码参数并根据自己的喜好和要求进行修改。在此示例中,我使用了一些简单的参数来模拟 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.m3u8where%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

让我们看看这个脚本的输出。

它首先生成一个主播放列表、三个包含各个片段的文件夹以及变体的播放列表。

使用FFmpeg的HLS打包

这是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 步骤没有太大区别。以下是您需要进行的一些更改。

  1. 消除-hls_playlist_type vod
  2. 添加-hls_list_size并将其设置为一个数字,该数字表示您希望在各个变体的播放列表中包含的片段数。

例如,如果我们设置-hls_list_size2,那么播放列表将只包含两个片段,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。

  1. hls_base_url baseurl:这可用于将baseurl表示的值附加 到播放列表中的每个条目。
  2. hls_fmp4_init_filename filename: 将文件名设置为片段文件头文件,默认文件名是 初始化.mp4. 当您将段类型设置为fmp4而不是时使用mpegts
  3. hls_fmp4_init_resend: 每次m3u8文件刷新后重新发送init文件,默认为 .
  4. 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 举报,一经查实,本站将立刻删除。

(0)

相关推荐

发表回复

登录后才能评论