使用FFmpeg推流笔记本摄像头视频时出现Broken pipe/连接拒绝报错如何解决
FFmpeg推流摄像头帧到RTSP报错修复方案
报错原因分析
两个阶段的报错对应不同问题:
- 第一次
*Protocol not found*报错:
初始命令中将输出格式-f设置为了flv,但推流目标是RTSP协议地址,FLV封装格式不支持RTSP协议输出,协议和封装不匹配导致FFmpeg执行失败,管道断开触发BrokenPipeError。另外你代码里的变量名rstp_url是RTSP的拼写错误,注意不要写错推流地址字符串。 - 第二次
*Connection refused*报错:
修改命令适配RTSP协议后,本地没有启动任何RTSP服务端在31415端口监听,FFmpeg无法连接到接收推流的服务端,所以上报连接拒绝错误。
修复步骤
步骤1:启动本地RTSP服务端
可以用mediamtx(原rtsp-simple-server)快速搭建本地RTSP服务,操作如下:
- 下载对应系统版本的mediamtx,解压后直接运行
- 默认RTSP监听端口是8554,你可以修改配置文件里的端口为31415,或者直接把代码里的推流地址端口改成8554
步骤2:使用优化后的推流代码
剔除调试代码,补充异常处理后的完整代码如下:
import subprocess import cv2 # 若使用mediamtx默认端口,这里改为rtsp://localhost:8554/stream rtsp_url = "rtsp://localhost:31415/stream" path = 0 cap = cv2.VideoCapture(path) if not cap.isOpened(): print("摄像头打开失败") exit() fps = int(cap.get(cv2.CAP_PROP_FPS)) # 兼容部分摄像头读取fps为0的异常 if fps <= 0: fps = 25 width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH)) height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT)) command = ['ffmpeg', '-y', '-f', 'rawvideo', '-vcodec', 'rawvideo', '-pix_fmt', 'bgr24', '-s', f"{width}x{height}", '-r', str(fps), '-i', '-', '-c:v', 'libx264', '-pix_fmt', 'yuv420p', '-preset', 'ultrafast', '-tune', 'zerolatency', '-rtsp_transport', 'tcp', '-f', 'rtsp', rtsp_url] p = subprocess.Popen(command, stdin=subprocess.PIPE, stderr=subprocess.DEVNULL) try: while cap.isOpened(): ret, frame = cap.read() if not ret: print("帧读取失败") break p.stdin.write(frame.tobytes()) p.stdin.flush() cv2.imshow('推流画面', frame) key = cv2.waitKey(int(1000/fps)) if key == 27: break except BrokenPipeError: print("推流管道断开,请检查RTSP服务是否正常") finally: cap.release() if p.stdin: p.stdin.close() p.wait() cv2.destroyAllWindows()
验证流程
- 先启动mediamtx服务,确认对应端口正常监听
- 运行上述推流代码
- 可以用VLC打开对应的RTSP地址,验证流是否正常播放
注意:如果是macOS系统,需要给终端开启摄像头权限,否则cv2无法读取摄像头帧。
内容的提问来源于stack exchange,提问作者Xiuyi Yang
相关产品推荐
相关产品推荐

