使用FFmpeg命令进行hls切片,得到的ts文件时长不准确,如何精确控制m3u8切片时长

一、问题描述:

我想将输入视频的关键帧间隔设置为5秒。只有这样我才能使用FFmpeg实现恒定的5秒HLS分割。如何使用FFmpeg将关键帧间隔设置为5秒?

使用如下FFmpeg命令进行hls切片

ffmpeg -i video2.mp4 -hls_time 1 -f hls out.m3u8

由于使用了参数“-hls_time 1”,所以预计生成的ts文件时长会是1秒左右。但结果却是最终生成的ts文件时长都远远大于1秒,如下图所示:

二、原因:

产生上述现象的原因是:ts文件的切割还跟视频的GOP大小(两个I帧之间的间隔)有关,并不是指定1秒切一个ts文件就能保证1秒切一个ts文件的。任何一个视频流在播放端要能获取到完整的GOP才能播放,所以一个ts文件所实际包含的时间是GOP的整数倍。

例如,

要切的视频帧率为24帧,希望切的片段时长为5秒,那么GOP就需要是1或5的倍数,例如 -g 24 -g120,不能是-g 48,这样GOP是2秒一个,就会导致切出来的片段是4秒和6秒的情况。

如果要切的片段时长为8秒,那GOP就可以设置为(帧率x2的倍数) -48 -96-120等等

三、解决方法:

方法一:

对于FFmpeg,您需要使用以下两个开关:

-g 120 将定义120帧的GOP,为24fps的视频创建一个5秒的GOP。

-x264opts no-scenecut 将强制按照FFmpeg使用的GOP值创建关键帧。 libx264的默认设置是在检测到场景更改时创建关键帧。

如果使用MediInfo检查输出文件而没有该选项,则会看到scenecut=40。如果做得恰当,那将是scenecut=0。如果未使用此选项,则ABR内容的关键帧将不对齐,并且分段大小将无法预测。

(参考文档:https://www.thinbug.com/q/30979714 应该是一个国外博主被采集翻译的文章)

方法二:

知道问题产生的原因就好办了,只要我们在FFmpeg命令中设置I帧间隔就可以了。我们将切片的命令修改为如下命令:

ffmpeg -i video2.mp4 -force_key_frames "expr:gte(t,n_forced*1)" -strict -2 -c:a aac -c:v libx264 -hls_time 1 -f hls out.m3u8
其中,参数-force_key_frames "expr:gte(t,n_forced*1)"表示强制每1秒一个关键帧

参数-strict -2是为了使用aac音频编码

执行完上述命令后,我们可以在生成的m3u8文件中看到生成的ts文件时长已经变为1秒了,如下图所示:

 

原文链接:https://blog.csdn.net/u014552102/article/details/103302731

版权声明:
作者:loyolife
链接:https://loyolife.com/730.html
来源:loyolife | 高效工作,轻松生活~ | 悠哉知识集
文章版权归作者所有,未经允许请勿转载。

THE END
分享
二维码
< <上一篇
下一篇>>
文章目录
关闭
目 录