web-dev-qa-db-ja.com

FFMPEGでimage2pipeをループする

さまざまな間隔で画像を生成する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 - ...

一定の入力ストリームを取得しますが、1つの画像を取得して、別の画像の準備ができるまでループできるようにしたいと思います。それは可能ですか?上記にループフラグを投げるだけではうまくいかないようです。

もう少し情報:これはすべてWindowsでPythonのsubprocessコマンドを介して実行し、subprocess.PIPEを介してstdinに画像を送信しています。私の問題は、Pythonではなくffmpegコマンドを正しく取得することに関係していると思います。そのため、ここに投稿します。

3
Ric

最善の解決策は、実際には画像をローカルで上書きすることであることがわかりました。 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はrtmpURLにストリーミングしますが、ローカルに保存するように簡単に変更できるはずです。 -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
Ric

out.jpgファイルをjpgファイルを作成するプログラムで開く場合、2つのプロセス(ffmpegとファイルを作成するプログラム)の両方が同時にアクセスできるため、「共有」読み取り/書き込みアクセスに設定する必要があります。

0
fpgalabguy