一、問題描述
??最近在用ffmpeg+Python opencv 的方法實(shí)現(xiàn)采集攝像頭實(shí)時視頻并完成推流。實(shí)現(xiàn)思路是:cv2先獲取攝像頭視頻數(shù)據(jù),然后建立一個subprocess.popen管道去推流,然后將視頻幀處理完后寫入管道中完成圖像處理并推流的工作。在windows下調(diào)試可以正常實(shí)現(xiàn),代碼如下(這個網(wǎng)上很多,我把我調(diào)試成功的代碼也貼出來)。但是我想要在樹莓派上實(shí)現(xiàn),將該部分代碼移植到樹莓派上后就出現(xiàn)報錯:pipe.stdin.write(img.tostring()) BrokenPipeError: [Errno 32] Broken pipe?,F(xiàn)象是:代碼剛跑起來,剛顯示一兩幀畫面就中斷了。
import cv2
import subprocess
# 視頻讀取對象
cap = cv2.VideoCapture(0,cv2.CAP_DSHOW)
# 推流地址
rtsp = "rtsp://192.168.1.100:554/live/test1"# 推流的服務(wù)器地址
# 設(shè)置推流的參數(shù)
command = ['ffmpeg',
'-y',
'-f', 'rawvideo',
'-vcodec', 'rawvideo',
'-pix_fmt', 'bgr24',
'-s', '640*480', # 根據(jù)輸入視頻尺寸填寫
'-r', '30',
'-i', '-',
'-c:v', 'h264',
'-pix_fmt', 'yuv420p',
'-preset', 'ultrafast',
'-f', 'rtsp',
rtsp]
# 創(chuàng)建、管理子進(jìn)程
pipe = subprocess.Popen(command,shell=True, stdin=subprocess.PIPE)
size = (int(cap.get(cv2.CAP_PROP_FRAME_WIDTH)), int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT)))
# 循環(huán)讀取
num = 0
while cap.isOpened():
num = num + 1
print(num)
# 讀取一幀
ret, frame = cap.read()
if frame is None:
print('read frame err!')
continue
# 顯示一幀
fps = int(cap.get(cv2.CAP_PROP_FPS))
cv2.imshow("frame", frame)
print("fps:",fps)
# 按鍵退出
if cv2.waitKey(1) & 0xFF == ord('q'):
break
# 讀取尺寸、推流
img = cv2.resize(frame, size)
pipe.stdin.write(img.tobytes())
# 關(guān)閉窗口
cv2.destroyAllWindows()
# 停止讀取
cap.release()
二、問題解決
1.找到問題
??從別人的帖子里發(fā)現(xiàn)可以用pipe.poll()來檢查當(dāng)前popen的工作狀態(tài),如果然后0,表示進(jìn)程正常結(jié)束,返回1表示進(jìn)程sleep掛起,返回2,表示子進(jìn)程不存在,返回-15表示進(jìn)程被kill,返回None,表示進(jìn)程正在在運(yùn)行。我print之后發(fā)現(xiàn),返回了1,所以預(yù)估應(yīng)該是,在樹莓派上和windows上的popen創(chuàng)建方法有差別,在樹莓派這里popen剛開始工作就被掛起了,終于找到解決辦法。
2.解決辦法
??嘗試了一下,將創(chuàng)建popen的shell = True 改為 shell = False就可以了。
將如下代碼,
pipe = subprocess.Popen(command,shell=True, stdin=subprocess.PIPE)
??改為文章來源:http://www.zghlxwxcb.cn/news/detail-608111.html
pipe = subprocess.Popen(command,shell=False, stdin=subprocess.PIPE)
??即可文章來源地址http://www.zghlxwxcb.cn/news/detail-608111.html
到了這里,關(guān)于樹莓派Python+ffmpeg+opencv實(shí)現(xiàn)推流 并 解決報錯:BrokenPipeError: [Errno 32] Broken pipe的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!