我如何设置 ffmpeg 以从管道 jpg 连续制作 1 秒的视频?

我如何设置 ffmpeg 以从管道 jpg 连续制作 1 秒的视频?

我在 Ubuntu 22.04 上使用 ffmpeg 从管道传输的 jpg 创建 1 秒的 mp4 视频。我遇到的唯一问题是,在第一组 jpg 被管道传输后,ffmpeg 停止执行。我需要 ffmpeg 持续接收 jpg,以便它可以继续创建更多 mp4。

这是最接近我想要的命令行:

ffmpeg -framerate 5 -i /tmp/ffmpeg_pipe -c:v libx264 -vf "fps=5" -f segment -segment_time 1 "output_%d.mp4"

当我输入 10 张图像时cat image_*.jpg > /tmp/ffmpeg_pipe,我得到了 2 个预期的输出文件,但 ffmpeg 随后停止执行。

我该怎么做才能在第一组之后传输更多 jpg 而不必重新启动 ffmpeg?我想要这个是因为我有另一个程序在不断创建我想转换成视频的新 jpg。

答案1

我们必须通过添加-g 5参数将 GOP 大小设置为 1 秒(5 帧代表 5fps 下的 1 秒):

ffmpeg -framerate 5 -i /tmp/ffmpeg_pipe -c:v libx264 -g 5 -f segment -segment_time 1 "output_%04d.mp4"


段解复用器只能使用关键帧.
添加-g 5参数强制每 5 帧设置一个关键帧。


测试:

创建 100 张 JPEG 图像:
ffmpeg -f lavfi -i testsrc=s=192x108:r=1:d=100 image_%03d.jpg

将 JPEG 图像写入 FFmpeg 标准输入管道:
cat *.jpg | ffmpeg -framerate 5 -f image2pipe -i pipe: -c:v libx264 -g 5 -f segment -segment_time 1 "output_%04d.mp4"

输出是20个MP4视频文件。


更新:

如果我们想多次写入 FFmpeg,我们可以使用以下解决方案(见评论)。

  • 创建命名管道:
    mkfifo /tmp/ffmpeg_pipe

  • 将命名管道重定向到 FFmpeg(添加 & 符号以便 FFmpeg 在后台运行):
    ffmpeg -framerate 5 -f image2pipe -i pipe: -c:v libx264 -g 5 -f segment -segment_time 1 "output_%04d.mp4" < /tmp/ffmpeg_pipe &

重要的:打开第二个终端窗口.
从另一个终端:

  • 打开文件描述符 3 写入(和读取)管道:
    exec 3<>/tmp/ffmpeg_pipe

  • cat >&3 将输出重定向到文件描述符 3:
    cat *.jpg >&3
    写入更多图像(仅作为示例):
    cat *.jpg >&3

  • 关闭文件描述符3:
    exec 3>&-

找到一种方法来关闭 FFmpeg 进程(我只是按下了 Ctrl-break)。

答案2

要使 FFmpeg 连续从流或管道读取而不中断,可以使用 -re 选项。-re 选项允许无限次重新读取输入流。这对于流式传输实时媒体或处理正在连续更新的媒体文件非常有用。

例如,要使用 FFmpeg 将实时 RTSP 流传输到互联网,您可以使用以下命令:

ffmpeg -i rtsp://example.com/live.sdp -re -f flv rtmp://example.com/live

此命令将连续读取 RTSP 流并将其流式传输到 rtmp://example.com/live 的 RTMP 服务器。

要处理不断更新的媒体文件(例如实时录制的视频文件),您可以使用以下命令:

ffmpeg -i pipe:0 -re -c:v copy -c:a 复制输出.mp4

此命令将连续读取输入管道并将视频和音频流复制到输出文件 output.mp4。-c:v copy 和 -c:a copy 选项告诉 FFmpeg 复制视频和音频流而不对其进行重新编码。

-re 选项是一个非常强大的工具,可用于实现多种任务。但需要注意的是,-re 选项可能会导致 FFmpeg 使用大量内存,因此务必谨慎使用。

相关内容