使用OpenCV视频写入器时遇GStreamer缓冲区推送错误求助
解决OpenCV VideoWriter结合GStreamer推RTSP时的缓冲区推送错误
核心问题分析及修复步骤
- 帧尺寸不匹配
你代码里用imutils.resize(image, width=800)修改了输出帧的尺寸,但初始化VideoWriter时用的是原视频的宽高,导致写入的帧尺寸和VideoWriter预期的不一致,这是触发缓冲区推送错误的最常见原因。
修复:先获取resize后的帧尺寸,用这个尺寸初始化VideoWriter。
GStreamer管道格式协商失败
OpenCV的appsrc需要明确指定输出格式,避免和后续元素格式不兼容。建议在appsrc后添加caps参数,明确BGR格式、分辨率和帧率。RTSP推流同步与编码优化
rtspclientsink默认的时钟同步可能导致缓冲区阻塞,加上sync=false可解决;x264enc添加tune=zerolatency更适配实时推流场景。
修改后的完整代码
import imutils import cv2 import numpy as np import time face_cascade = cv2.CascadeClassifier('haarcascade_frontalface_default.xml') cap = cv2.VideoCapture("video.mp4") # 先读取一帧获取resize后的尺寸 ret, image = cap.read() if not ret: print("无法读取视频") exit() image = imutils.resize(image, width=800) resize_h, resize_w = image.shape[:2] # 重置视频读取指针到开头 cap.set(cv2.CAP_PROP_POS_FRAMES, 0) # 构建修正后的GStreamer管道 gst_pipeline = ( f'appsrc caps="video/x-raw,format=BGR,width={resize_w},height={resize_h},framerate={int(cap.get(cv2.CAP_PROP_FPS))}/1" ! ' 'videoconvert ! ' 'x264enc speed-preset=ultrafast bitrate=600 key-int-max=40 tune=zerolatency ! ' 'rtspclientsink location=rtsp://192.168.1.18:8554/mystream sync=false' ) out = cv2.VideoWriter( gst_pipeline, cv2.CAP_GSTREAMER, 0, int(cap.get(cv2.CAP_PROP_FPS)), (resize_w, resize_h), True ) if not out.isOpened(): print("无法打开VideoWriter") exit() while True: ret, image = cap.read() if not ret: print("视频播放完毕,循环播放") cap.set(cv2.CAP_PROP_POS_FRAMES, 0) continue image = imutils.resize(image, width=800) gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) faces = face_cascade.detectMultiScale3( gray, scaleFactor=1.3, minNeighbors=5, minSize=(30, 30), flags=cv2.CASCADE_SCALE_IMAGE, outputRejectLevels=True ) rects = faces[0] weights = faces[2] for idx, (x, y, w, h) in enumerate(rects): cv2.rectangle(image, (x, y), (x + w, y + h), (255, 0, 0), 2) # 修正:取对应索引的权重值,避免显示整个数组 cv2.putText(image, str(round(weights[idx][0], 2)), (x, y), cv2.FONT_HERSHEY_COMPLEX_SMALL, 1, (0, 0, 255), 1) out.write(image) cv2.imshow("Frame", image) key = cv2.waitKey(1) & 0xFF if key == ord("q"): break # 释放资源 cap.release() out.release() cv2.destroyAllWindows()
额外检查项
- 确认RTSP服务器(如rtsp-simple-server)已正常启动,地址端口与代码一致;
- 检查防火墙是否放行8554端口流量;
- 用GStreamer命令行测试管道有效性:
gst-launch-1.0 videotestsrc ! videoconvert ! x264enc speed-preset=ultrafast tune=zerolatency ! rtspclientsink location=rtsp://192.168.1.18:8554/mystream sync=false
如果命令行能正常推流,说明服务器和网络无问题,问题集中在OpenCV代码参数上。
内容的提问来源于stack exchange,提问作者S Andrew
相关产品推荐
相关产品推荐

