FFMPEG 在我的特殊情况下减少输出文件大小

FFMPEG 在我的特殊情况下减少输出文件大小

我有一张图片 bg.jpg 和一个 20 秒长的 mp4 视频文件 (video.mp4)。

我想循环播放该图像 2 个小时,因为它将作为一长段音乐曲目的背景图像。

我创建了这个帧的 1 秒视频,以便我可以使用 -stream_loop -1 来达到我想要的时长。

ffmpeg -loop 1 -i bg.jpg -t 1 temp.mp4
ffmpeg -stream_loop -1 -i temp.mp4 -c copy -t 02:00:00 out.mp4 

但现在,我想将 video.mp4 叠加到 out.mp4 上。要做到这一点,需要重新编码整个 2 小时的视频,只是为了叠加其中的 20 秒。一定有更好的方法。

我尝试过的事情:

ffmpeg -loop 1 -i bg.jpg -t 20 temp.mp4
ffmpeg -i temp.mp4 -i video.mp4 -filter_complex "overlay" overlaid.mp4
ffmpeg -stream_loop -1 overlaid.mp4 -c copy -t 02:00:00 out.mp4

这很快,但问题是,我只希望覆盖发生一次,而不是在整个 2 小时内循环。

因此我尝试了以下操作:

循环播放 bg.jpg 20 秒并叠加 video.mp4。然后流式播放 1 秒的 bg.jpg 视频,播放时间为 01:59:40。将其与包含叠加的视频连接起来。

我也开始研究可变帧速率,因为将整个视频设置为 29.97 fps 实在是太浪费了,考虑到绝大多数时长都只是一个帧(除了前 20 秒,叠加的视频确实包含运动)。

有人能告诉我实现我所寻找的最佳方法吗?如果需要,我可以根据要求提供更多信息。

谢谢你!

答案1

创建循环

你可以省下全部循环播放视频的中间步骤:

ffmpeg -loop 1 -i bg.png -i video.mp4 -i audio.mp3 -t 02:00:00 -filter_complex "[0:v][1:v] overlay=0:0:enable='between(t,5,10)'" -c:a copy out.mp4

解释:

-loop 1将启用循环仅限下一期-i test.png输入文件。我们将使用参数将图像文件作为输入-loop-loop以布尔值作为参数。

我们-t hh:mm:ss指定输出视频的长度。

[0:v][1:v]将指定使用的视频流。

overlay=0:0:enable='between(t,5,10)告诉 ffmpeg 将第二个视频流叠加在输出视频的0:0第 5 秒和第 10 秒之间的坐标上( )。between(t,5,10)

-c:a copy告诉 ffmpeg 将音频复制到容器中,而无需重新编码。

减小文件大小

正如 Rotem 所指出的,可变帧率可能会导致某些播放器出现问题。它还可能导致音频漂移等其他问题。

我建议您改用像 h265 这样的好的视频编码器。

根据您的音频文件,如果您喜欢良好的质量,可以使用 FLAC 重新编码音频,如果您喜欢较小的文件大小,可以使用 mp3 重新编码音频。

H.265

使用 h265,我们可以使用可变比特率来降低文件大小,同时保持恒定的质量。为此,我们可以使用该-crf参数。您可以将其设置为 0 到 51 之间的任意值,其中较低的值表示质量较好,较高的值表示质量较差。默认值为 28。

我们可以进一步修改ffmpeg命令以添加h265编码:

ffmpeg -loop 1 -i bg.png -i video.mp4 -i audio.mp3 -t 02:00:00 -c:v libx265 -crf 28 -filter_complex "[0:v][1:v] overlay=0:0:enable='between(t,5,10)'" -c:a copy out.mp4

相关内容