ffmpeg 忽略 -hls_time 参数

ffmpeg 忽略 -hls_time 参数

我正在尝试让 ffmpeg 将实时视频流(通过 stdin 提供)转换为 HLS。

ffmpeg -nostdin -i pipe:0 -map i:0x66 -map i:0x67 -f hls -hls_init_time 5 -hls_time 5 -hls_list_size 5 -hls_flags delete_segments -hls_allow_cache 0 -vf yadif -codec libx264 -preset veryfast -tune zerolatency -x264-params keyint=150 -acodec aac -b:a 128k ../output/index.m3u8

它大部分情况下都能正常工作,但 -hls_time 参数似乎被完全忽略了,因为生成的许多片段长度不到 3 秒。(在一个案例中,一个片段的长度刚好超过 1 秒)

我最初在 ffmpeg 3.4.4(Ubuntu Bionic Beaver 发布的最高版本)上遇到了这个问题,但我现在已经从源代码构建了 ffmpeg,但仍然遇到同样的问题。

$ ffmpeg -version
ffmpeg version N-93335-ga8c5ae4 Copyright (c) 2000-2019 the FFmpeg developers
built with gcc 7 (Ubuntu 7.3.0-27ubuntu1~18.04)
configuration: --enable-gpl --enable-libass --enable-libfreetype --enable-libmp3lame --enable-libopus --enable-libtheora --enable-libvorbis --enable-libx264 --enable-nonfree --arch=x86_64 --cpu=znver1
libavutil      56. 26.100 / 56. 26.100
libavcodec     58. 47.103 / 58. 47.103
libavformat    58. 26.101 / 58. 26.101
libavdevice    58.  6.101 / 58.  6.101
libavfilter     7. 48.100 /  7. 48.100
libswscale      5.  4.100 /  5.  4.100
libswresample   3.  4.100 /  3.  4.100
libpostproc    55.  4.100 / 55.  4.100

我究竟做错了什么?

答案1

我需要查看您的播放列表才能 100% 确定,但您看到这种行为的原因很可能是因为 ffmpeg 试图在关键帧边界上分割您的视频。这是使用 ffmpeg 准备 HLS 流时常见的问题。

即使你告诉 ffmpeg 有一个关键帧最多每 150 帧,ffmpeg 还会在场景变化时插入关键帧(这可以提高视频质量)。

Gyan 在评论中提出的建议是合理的,因为使keyint等于keyint_min应该会导致视频具有固定的 GOP 长度 - 从而强制以相等的间隔进行分段。然而,在 libx264 中, 的值keyint_min被限制为keyint / 2 + 1

h->param.i_keyint_min = x264_clip3( h->param.i_keyint_min, 1, h->param.i_keyint_max/2+1 );

另一个问题是您的 GOP 长度为 150 帧。对于 25 fps 的视频,每 6 秒一个关键帧。如果没有场景检测关键帧,您将无法满足hls_time仅出于这个原因而指定的片段长度。

根据我的经验,该参数的工作方式hls_time是尝试保持“平均”片段长度 - 如果它无法以精确的hls_time秒数对视频进行分段,它将尝试进行补偿,从而产生比指定的持续时间更短和更长的片段。

解决方案

最好的办法是降低 GOP 长度,以便它能够适合hls_time。甚至更好的是,确保hls_time是 GOP 长度的倍数(这样就不会依赖场景剪切关键帧)。

除此之外,我建议通过添加来修复关键帧

-force_key_frames "expr:if(isnan(prev_forced_n),1,eq(n,prev_forced_n+$GOP))"

ffmpeg 的参数(其中$GOP是一个包含您选择的 GOP 长度的 shell 变量)。

我曾在一篇文章中描述了其中的一些问题如何为 HLS 流媒体准备媒体,您可能需要查看它以更深入地了解 HLS 流式传输所需的内容。

相关内容