wou*_*buc 7 video ffmpeg transcoding mpeg-dash
我一直在尝试实现一个类似 Plex 的视频播放器,可以按需转码任意视频文件,并在网页上使用 MPEG-Dash 播放它。我能够使用dash.js参考实现来实现客户端播放器,因此它将动态地从服务器请求片段(SegmentTemplate在 mpd 文件中使用)。
但我在实时生成这些块时遇到一些问题。Ffmpeg 允许我设置-ss和-t定义所需片段的边界,但它们无法在播放器中正常播放,因为它们是“完整”视频文件而不是 Dash 片段。
那么,如何调整 ffmpeg 命令以将我需要的部分转码为 Dash 片段,而无需提前生成整个视频文件的片段?
输入视频文件可以是任何格式,因此不能假设它采用 mp4/dash 兼容的编解码器。因此需要转码(使用ffmpeg或类似工具)。
我当前的 ffmpeg 命令如下所示(经过多次尝试):
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
Run Code Online (Sandbox Code Playgroud)
客户端播放器应该能够缓冲接下来的 X 段,并且用户应该能够查看持续时间栏上的当前位置并寻找不同的位置。因此,将其视为直播并不是一个选择。
我知道这是一个相对较老的问题,但我认为我成功地实现了您所描述的解决方案。总而言之,我们的想法是向客户提供仪表板清单,但仅在客户要求时才转换这些段。
实现这一目标的步骤是:
步骤 1 的命令如下所示(对于流 0 的第三段):
ffmpeg -y -ss 30 -t 11 -threads 8 -copyts -start_at_zero -i "/path/to/original.mp4" -map 0:1 -c copy /tmp/output_segment.mp4
Run Code Online (Sandbox Code Playgroud)
“-ss 30”告诉 ffmpeg 在文件开始后 30 秒启动。“-t 11”在此之后保留曲目的 11 秒(重叠避免了播放中的间隙)。“-copyts”保持时间戳不变,因此提取的分段将从 30 秒开始,而不是 0。“-c copy”复制原始流,并将被替换为“-g 30 -c:v libx264 -crf” 22 -profile:v high -level 3.1" 如果必须转码。
重新打包工作流的第二个命令是:
MP4Box -dash 10000 -frag 500 -rap -single-file -segment-name segment_base_name_ -tfdt $TFDT_OFFSET /tmp/output_segment.mp4 -out /tmp/unused_ouput.mp4
Run Code Online (Sandbox Code Playgroud)
输出可以被丢弃,但它还会创建一个名为segment_base_name_init.mp4的文件,该文件就是您需要的实际段。这里的 -tfdt 参数是最重要的,因为它在时间轴中正确地偏移了片段。为了获得正确的值,我使用以下命令(因为关键帧并不完全位于 10 秒标记处,因此片段的开头可能不是我们期望的位置):
ffprobe -print_format json -show_streams /tmp/output_segment.mp4
Run Code Online (Sandbox Code Playgroud)
正确的值为 start_time * 1000 (-tfdt 使用毫秒)
我希望这会有所帮助,我花了一段时间才使其工作,并且我偶然发现了这个问题,因为自上次更新以来 MP4Box 突然停止工作。另请注意,您也可以使用 VP9 和 Vorbis 来实现这一点,然后您无需重新打包流。
编辑
对于任何对此感兴趣的人,我上面描述的方法存在一些问题,因为 MP4Box 自 1.0 版(?)以来没有正确更新 tfdt 记录。
当独立于其他片段创建片段时,该片段必须符合 Dash 标准(MP4Box 在之前的解决方案中做到了这一点,但 FFMpeg 也可以使用 -f dash 作为输出来做到这一点)。选项还必须确保段的边界与 RAP(我认为是 SAP 或 i 框架)保持一致。该命令如下所示:
ffmpeg -y -ss 390 -to 400 -threads 6 -copyts -start_at_zero -noaccurate_seek -i input.mkv -map 0:1 -c copy -movflags frag_keyframe -single_file_name segment_39.mp4 -global_sidx 1 -min_frag_duration 500 -f dash unused.mpd
Run Code Online (Sandbox Code Playgroud)
那么问题就是要确保每个片段都会被 MSE 正确地放置在时间轴上。在碎片 MP4 文件中,有三个位置影响时间线中的位置:
FFMpeg 的问题在于它会正确创建前两个,但 tfdt 时间从零开始。由于我未能找到一种方法来做到这一点,我编写了这些简单的函数来纠正这个问题。请注意,它会删除第一个编辑,因为它可以被 Firefox 识别,但不能被 Chrome 识别,因此视频与两者兼容。
ffmpeg -y -ss 30 -t 11 -threads 8 -copyts -start_at_zero -i "/path/to/original.mp4" -map 0:1 -c copy /tmp/output_segment.mp4
Run Code Online (Sandbox Code Playgroud)
听起来您所描述的是实时流媒体而不是 VOD - 实时流是连续的,通常是实时视频流,而 VOD 通常是在用户请求时提供的视频文件。
大型解决方案中完成 VOD 的常用方式是先对视频进行分段,然后按需将其打包成所需的流媒体协议,此时通常是 HLS 或 DASH。这使得操作员可以最大限度地减少他们需要维护的不同格式。
新兴的 CMAF 标准通过对 HLS 和 DASH 的段使用相同的格式来帮助支持这一点。如果您搜索“CMAF”,您会看到许多历史解释,官方页面也在这里: https: //www.iso.org/standard/71975.html
开源工具可帮助您将 MP4 文件直接转换为 DASH - MP4Box 是最常见的工具之一:https://github.com/gpac/gpac/wiki/DASH-Support-in-MP4Box
ffmpeg 还在文档中包含支持 VOD 的信息:https://www.ffmpeg.org/ffmpeg-formats.html#dash-2包括示例:
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
Run Code Online (Sandbox Code Playgroud)
如果您正在查看的实际上是直播流,那么输入通常不是 MP4 文件,而是某种格式的流,例如 HLS、RTMP、MPEG-TS 等。
采用这种格式的输入并提供实时配置文件 DASH 输出更加复杂。通常使用专用的打包机来执行此操作。开源 Shaka Packager ( https://github.com/google/shaka-player ) 是一个不错的选择,它包含生成 DASH 实时输出的示例:
假设您希望在生成视频文件时允许用户观看,那么实现此目的的一种方法是使流看起来像直播流,即“VOD to Live”情况。
您可以使用 Ffmpeg 中的重新流式传输来转码并流式传输到 UDP,然后将其输入打包程序。
ffmpeg 文档包含以下注释:
-re(输入)以本机帧速率读取输入。主要用于模拟抓取设备或实时输入流(例如从文件读取时)。不应与实际的抓取设备或实时输入流一起使用(可能会导致数据包丢失)。默认情况下,ffmpeg 会尝试尽快读取输入。此选项会将输入的读取速度减慢至输入的本机帧速率。它对于实时输出(例如直播)很有用。
这会给你一个看起来像这样的流程:
mp4 文件 -> ffmpeg -> 打包程序 -> 实时 DASH 流 -> 客户端
使用打包程序来执行此操作意味着您不必担心在新段可用或旧段不可用时更新清单。
Wowza 打包器网站上有一个示例(在撰写本文时),您可以查看并尝试一下,替换您现在的文件或使用它们的文件 - 输出应该适用于任何可以接受 UDP 输入流的打包器:https ://www.wowza.com/docs/how-to-restream-using-ffmpeg-with-wowza-streaming-engine
| 归档时间: |
|
| 查看次数: |
16231 次 |
| 最近记录: |