我看到大量有關將raspivid流直接傳遞給FFMPEG以進行編碼,複用和重新定向的信息,但這些用例大部分來自bash;類似於:如何使用子流程(Python)將Picamera視頻轉換爲FFMPEG
raspivid -n -w 480 -h 320 -b 300000 -fps 15 -t 0 -o - | ffmpeg -i - -f mpegts udp://192.168.1.2:8090ffmpeg
我希望能夠利用Picamera庫的功能,所以我可以使用OpenCV和類似的方法進行併發處理,同時仍然使用FFMPEG進行流式處理。但我不知道如何正確打開FFMPEG作爲子流程和管道視頻數據。我看到很多嘗試,unanswered posts和人claiming to have done it,但它似乎沒有在我的Pi上工作。
我應該用Picamera創建一個視頻緩衝區,並將原始視頻傳輸到FFMPEG?我可以使用camera.capture_continuous()並傳遞FFMPEG我用於OpenCV計算的bgr24圖像嗎?
我試過各種各樣的變化,我不知道如果我只是誤解如何使用子進程模塊,FFMPEG,或者我只是缺少一些設置。我知道原始流不會有任何元數據,但我不完全確定我需要給FFMPEG什麼設置以瞭解我給它的內容。
我有一個Wowza服務器,我最終會流到,但我目前正在通過流式傳輸到筆記本電腦上的VLC服務器進行測試。目前我已經試過這樣:
import subprocess as sp
import picamera
import picamera.array
import numpy as np
npimage = np.empty(
(480, 640, 3),
dtype=np.uint8)
with picamera.PiCamera() as camera:
camera.resolution = (640, 480)
camera.framerate = 24
camera.start_recording('/dev/null', format='h264')
command = [
'ffmpeg',
'-y',
'-f', 'rawvideo',
'-video_size', '640x480',
'-pix_fmt', 'bgr24',
'-framerate', '24',
'-an',
'-i', '-',
'-f', 'mpegts', 'udp://192.168.1.54:1234']
pipe = sp.Popen(command, stdin=sp.PIPE,
stdout=sp.PIPE, stderr=sp.PIPE, bufsize=10**8)
if pipe.returncode != 0:
output, error = pipe.communicate()
print('Pipe failed: %d %s %s' % (pipe.returncode, output, error))
raise sp.CalledProcessError(pipe.returncode, command)
while True:
camera.wait_recording(0)
for i, image in enumerate(
camera.capture_continuous(
npimage,
format='bgr24',
use_video_port=True)):
pipe.stdout.write(npimage.tostring())
camera.stop_recording()
我也試過流寫入,簡單地創建ffmpeg的子進程,並寫入到它的標準輸入一個類文件對象(camera.start_recording()可以給出一個對象像這樣,當你初始化picam):
class PipeClass():
"""Start pipes and load ffmpeg."""
def __init__(self):
"""Create FFMPEG subprocess."""
self.size = 0
command = [
'ffmpeg',
'-f', 'rawvideo',
'-s', '640x480',
'-r', '24',
'-i', '-',
'-an',
'-f', 'mpegts', 'udp://192.168.1.54:1234']
self.pipe = sp.Popen(command, stdin=sp.PIPE,
stdout=sp.PIPE, stderr=sp.PIPE)
if self.pipe.returncode != 0:
raise sp.CalledProcessError(self.pipe.returncode, command)
def write(self, s):
"""Write to the pipe."""
self.pipe.stdin.write(s)
def flush(self):
"""Flush pipe."""
print("Flushed")
usage:
(...)
with picamera.PiCamera() as camera:
p = PipeClass()
camera.start_recording(p, format='h264')
(...)
任何這幫助將是驚人的!
這可能是一個更容易:)雖然把AVC視頻的MPEG-1 PS容器是怪異叫 - 不,即使是工作?在任何情況下,OP都作爲TS流傳輸到UDP,以便部分受到控制。 – hobbs
似乎爲我工作!輸出可以在omplayer中播放。但我願意提出改進建議! –
這正是我需要的!我清楚地誤用了子流程的管道,但它幫助我意識到我在FFMPEG中嘗試使用的一些設置也給我帶來了問題。謝謝! – VeniVidiReliqui