Eu descobri que a melhor solução era substituir apenas a imagem localmente. Eu brinquei bastante com pipes e processos em Python, mas nada funcionava tão bem quanto apenas rodar o ffmpeg pela linha de comando e sobrescrever a imagem. Eu acabei fazendo isso no Linux, mas deve funcionar no Windows.
Comandoffmpeg:
ffmpeg -re -loop 1 -i out.jpg -re -f lavfi -i aevalsrc=0 -codec:v libx264 -video_size 1280x720 -f flv -strict experimental rtmp://...
O ffmpeg transmite para um URL rtmp, mas deve ser fácil alterá-lo para salvar localmente. Basta alterar o sinalizador -f para o formato desejado e a URL para o nome do arquivo.
Código 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()
O código Python não é o mais limpo do mundo, mas deve funcionar. Escreve para "temp.jpg" primeiro, então o ffmpeg não acaba lendo a imagem quando o Python a escreve.