Looping no image2pipe com o FFMPEG

3

Eu tenho um programa em Python que gera imagens em vários intervalos. Eu gostaria de poder criar um fluxo de vídeo de cada imagem como ela aparece. Anteriormente eu estava usando um comando ffmpeg como

ffmpg -re -loop 1 -i image.jpg -c:v libx264 -pix_fmt yuv420p out.mp4

Gostaria apenas que meu código substituísse image.jpg sempre que ele criasse uma nova imagem. No entanto, eu gostaria de poder apenas canalizar diretamente para o comando ffmpeg, então não tenho que lidar com o salvamento do arquivo.

Eu sei que posso usar algo como

ffmpeg -re -y -f image2pipe -vcodec mjpeg -r 24 -i - ...

para obter um fluxo de entrada constante, mas gostaria de poder tirar uma imagem e passar por ela até que outra esteja pronta. Isso é possível? Apenas jogando a bandeira de loop para o acima não parece funcionar.

Um pouco mais de informação: Estou rodando tudo isso no Windows via subprocesso do Python e enviando as imagens via subprocess.PIPE para stdin. Eu acho que o meu problema tem a ver com o comando ffmpeg correto e não com o Python, e é por isso que estou postando aqui.

    
por Ric 17.04.2014 / 02:31

2 respostas

2

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.

Comando

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://...

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.

    
por 10.04.2015 / 19:07
0

quando o arquivo out.jpg é aberto no programa que cria os arquivos jpg, ele deve ser configurado para acesso de leitura / gravação "compartilhado", já que os dois processos (ffmpeg e o programa que cria o arquivo) podem acessá-lo simultaneamente.

    
por 24.08.2017 / 07:50