さまざまな間隔で画像を生成する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コマンドを正しく取得することに関係していると思います。そのため、ここに投稿します。
最善の解決策は、実際には画像をローカルで上書きすることであることがわかりました。 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が画像から読み取ることはありません。
out.jpgファイルをjpgファイルを作成するプログラムで開く場合、2つのプロセス(ffmpegとファイルを作成するプログラム)の両方が同時にアクセスできるため、「共有」読み取り/書き込みアクセスに設定する必要があります。