我有一个 Python 程序,可以按不同的时间间隔生成图像。我希望能够创建每幅图像的流式视频。以前我使用 ffmpeg 命令,例如
ffmpg -re -loop 1 -i image.jpg -c:v libx264 -pix_fmt yuv420p out.mp4
每当创建新图像时,我都会让代码覆盖 image.jpg。但是,我希望能够直接通过管道传输到 ffmpeg 命令,这样我就不必保存文件了。
我知道我可以用类似的东西
ffmpeg -re -y -f image2pipe -vcodec mjpeg -r 24 -i - ...
接受恒定的输入流,但我希望能够获取一张图像并循环播放,直到另一张图像准备好。这可能吗?仅将循环标志放入上述代码似乎不起作用。
更多信息:我在 Windows 上通过 Python 的 subprocess 命令运行这一切,并通过 subprocess.PIPE 将图像发送到 stdin。我认为我的问题与正确使用 ffmpeg 命令有关,而不是与 Python 有关,这就是我在这里发布它的原因。
答案1
我发现最好的解决方案实际上是在本地覆盖图像。我在 Python 中尝试了很多管道和进程,但没有比从命令行运行 ffmpeg 并覆盖图像更好的方法了。我最终在 Linux 上这样做了,但它应该可以在 Windows 上工作。
ffmpeg 命令:
ffmpeg -re -loop 1 -i out.jpg -re -f lavfi -i aevalsrc=0 -codec:v libx264 -video_size 1280x720 -f flv -strict experimental rtmp://...
ffmpeg 流式传输到 rtmp URL,但应该很容易将其更改为本地保存。只需将 -f 标志更改为所需的格式,并将 URL 更改为文件名即可。
Python代码:
import cv2
import os
import threading
class ffmpegHelper(threading.Thread):
def __init__(self, queue):
threading.Thread.__init__(self)
self.image_queue = queue
self.timer = 1
def tick(self):
threading.Timer(self.timer,self.tick).start()
temp = None
if not self.image_queue.empty():
temp = self.image_queue.get()
try:
cv2.imwrite("temp.jpg",temp)
os.rename("temp.jpg","out.jpg")
except:
print "Temp didn't get fully written"
print "Skipping this frame"
def run(self):
self.tick()
Python 代码不是世界上最干净的,但它应该可以工作。它首先写入“temp.jpg”,因此当 Python 写入时,ffmpeg 不会从图像中读取。
答案2
当在创建 jpg 文件的程序中打开 out.jpg 文件时,必须将其设置为“共享”读/写访问权限,因为这两个进程(ffmpeg 和创建文件的程序)可以同时访问它。