关于视频:使用ffmpeg生成单个MPEG-Dash段

Generate single MPEG-Dash segment with ffmpeg

我一直在尝试实现一种类似Plex的视频播放器,该视频播放器可以按需对任意视频文件进行转码,并使用MPEG-Dash在网页上播放。我能够使用dash.js参考实现来实现客户端播放器,因此它将动态地从服务器请求片段(使用mpd文件中的SegmentTemplate)。

但是我在实时生成这些块时遇到了一些问题。 Ffmpeg让我设置-ss-t来定义所需片段的边界,但是它们在播放器中无法正常播放,因为它们是"完整"的视频文件,而不是Dash片段。铅>

那么我如何调整ffmpeg命令以仅将我需要的部分转码为Dash片段,而不必事先为整个视频文件生成片段?

输入视频文件可以是任何格式,因此不能假定它在mp4 /破折号兼容的编解码器中。因此,需要使用ffmpeg或类似工具进行转码。

我当前的ffmpeg命令如下所示(经过多次尝试):

1
ffmpeg -ss 10 -t 5 -i video.mkv -f mp4 -c:a aac -c:v h264 -copyts -movflags empty_moov+frag_keyframe temp/segment.mp4

客户端播放器应该能够缓冲下一个X段,并且用户应该能够在持续时间栏上查看当前位置并寻找其他位置。因此,将其视为实时流是不可行的。


听起来您所描述的是实时流而不是VOD-实时流是连续的,通常是实时视频流,而VOD通常是在用户请求时提供的视频文件。

在较大的解决方案中完成VOD的通常方法是先分割视频,然后按需将其打包到所需的流协议中,此时通常为HLS或DASH。这使操作员可以最小化他们需要维护的不同格式。

新兴的CMAF标准通过为HLS和DASH的段使用相同的格式来帮助支持这一点。如果您搜索" CMAF",您会看到许多有关历史的解释,官方页面也在这里:https://www.iso.org/standard/71975.html

存在开源工具来帮助您将MP4文件直接转换为DASH-MP4Box是最常见的工具之一:https://gpac.wp.imt.fr/mp4box/dash/

ffmpeg在文档中还包含支持VOD的信息:https://www.ffmpeg.org/ffmpeg-formats.html#dash-2(包括示例):

1
2
3
4
5
6
ffmpeg -re -i <input> -map 0 -map 0 -c:a libfdk_aac -c:v libx264 \\
-b:v:0 800k -b:v:1 300k -s:v:1 320x170 -profile:v:1 baseline \\
-profile:v:0 main -bf 1 -keyint_min 120 -g 120 -sc_threshold 0 \\
-b_strategy 0 -ar:a:1 22050 -use_timeline 1 -use_template 1 \\
-window_size 5 -adaptation_sets"id=0,streams=v id=1,streams=a" \\
-f dash /path/to/out.mpd

如果您实际上正在查看的是实时流,则输入通常不是MP4文件,而是某种格式的流,例如HLS,RTMP,MPEG-TS等。

以这种格式输入并提供实时配置文件DASH输出更加复杂。通常,使用专用package机来执行此操作。开源的Shaka Packager(https://github.com/google/shaka-player)将是一个不错的选择,它包括产生DASH实时输出的示例:

  • https://google.github.io/shaka-packager/html/tutorials/live.html

假设您要允许用户在生成视频文件时观看,那么一种方法是使视频流看起来像实时流,即" VOD to Live"的情况。

您可以在Ffmpeg中使用重新流传输来转码并传输到UDP,然后将其馈送到打包程序中。

ffmpeg文档包含以下注释:

-re (input)
Read input at native frame rate. Mainly used to simulate a grab device, or live input stream (e.g. when reading from a file). Should not be used with actual grab devices or live input streams (where it can cause packet loss). By default ffmpeg attempts to read the input(s) as fast as possible. This option will slow down the reading of the input(s) to the native frame rate of the input(s). It is useful for real-time output (e.g. live streaming).

这将为您提供如下流程:

mp4文件-> ffmpeg->打包程序->实时DASH流->客户端

使用打包程序执行此操作意味着您不必担心在新段可用或旧段不可用时更新清单。

在Wowza打包器网站上(在撰写本文时)有一个示例,您可以查看并进行试验,替换您现在的文件或使用它们的文件-输出应与任何可以接受UDP输入的打包器一起使用流:https://www.wowza.com/docs/how-to-restream-using-ffmpeg-with-wowza-streaming-engine