2017-08-29 83 views
0

我想什麼做的是這樣的:如何將一個程序(ffmpeg)的輸出傳遞給python腳本?

ffmpeg -i udp://224.10.10.10:15004 -qscale:v 2 sttest%04d.jpg 

再經過這個輸出圖像路徑到Python腳本,其分別發生在圖像和操縱他們,因爲ffmpeg運行(最終我會使用ffmpy來調用ffmpeg而不是使用命令行工具,但是爲了測試目的,我從這裏開始)。

我想要做到這一點的方法是每次處理圖像時查看ffmpeg輸出的目錄以查看是否有新圖像,然後將其加載到python中(使用OpenCV) - - 如果沒有新圖像要處理,則等待一定的時間間隔。

但是有沒有更好的方法來做到這一點,比如直接發送圖像的路徑到某種類型的隊列,python腳本可以逐一處理?

回答

0

對於任何人都好奇,這裏是我的解決方案。它使用OpenCV。當我問這個問題時,我並沒有意識到這一點,但OpenCV具有在幕後使用ffmpeg的某些功能。由於我的程序已經在使用OpenCV,我只是在提到的問題中提到了這個問題(因爲我認爲它不重要),使用OpenCV內置的功能來執行我想要的功能並不是很困難。下面是代碼:

cap = cv2.VideoCapture("video.mpg") 
count = 0 
frame_q = queue.Queue() 

while cap.grab(): 
    success, frame = cap.read() 

    if count % 5 == 0 and success: 
      frame_alpha = np.insert(frame, 3, 255, axis=2) 
      frame_q.put(frame_alpha) 

    count += 1 

正如你所看到的,我只是把每五幀到幀的Queue。這樣做的核心是以下三行:

cap = cv2.VideoCapture("video.mpg") 
while cap.grab(): 
    success, frame = cap.read() 

第一行打開捕捉,而子句檢查是否存在使用cap.grab()任何一個以上幀(返回True如果存在下一個幀),然後我讀使用cap.read()將幀編碼爲numpy陣列。success是一個布爾值,指示操作是否成功。後來,我加入一個alpha通道frame,並把它放入frame_q

然後,程序get小號幀的另一個線程的是Queue的。這樣,我根本不必處理文件系統 - 就像Marcus說的那樣,我將它們直接加入到程序中。

注:cv2.VideoCapture()上班opencv_ffmpeg.dll需要在系統路徑或者您正在使用哪個的Python安裝的根目錄。你可能有其中XYZ是OpenCV版本號減去小數點將其重命名爲opencv_ffmpegXYZ.dll。所以對我來說,這是opencv_ffmpeg330.dll因爲我有版本3.3.0。它也可能在x64系統上被稱爲opencv_ffmpeg330_64.dll

opencv_ffmpeg.dll位置取決於你如何安裝OpenCV,我只想在OpenCV目錄搜索opencv_ffmpeg,看看它出現。在你把它複製到Python目錄,一定要檢查,如果它已經存在。這可能是,取決於你如何安裝OpenCV

1

由於FFmpeg沒有輸出「我已生成的文件名」的流,所以您唯一的選擇是使用您擁有的文件系統。

根據您的操作系統,在目錄中接觸到新文件時可能會收到通知。我不知道這是否適用於linux,windows,os x,但它值得研究。

事實上,這看起來很簡單,你不會做到這一點通過外部調用ffmpeg。 ffmpeg基本上是用於libavcodec的用戶前端,該庫用於對視頻,音頻等進行解碼和編碼。

因此,您可能只是想在應用程序中使用libavcodec。我實際上認爲,如果使用實際的媒體流體系結構,你想要做的事會容易得多。 GStreamer可能是您的首選工具,您可以直接從python使用它,但我沒有經驗,這是多麼容易。

您的目標應該是直接在您的python程序中獲取框架,而不必繞行寫入磁盤。

一個簡單的MJPEG(Motion JPEG格式)轉換器,簡單管道輸送到你的程序的stdin可能是最簡單的方法,如果你不希望使用任何libav*gstreamer

相關問題