Jetson Xavier上OpenCV VideoWriter保存的视频无法打开求助
在Jetson Xavier上正确保存可播放视频的解决方案
针对你遇到的视频保存后无法打开的问题,核心原因大概率是帧尺寸不匹配或CPU编码兼容性问题,结合Jetson平台的硬件特性,以下是具体解决方法:
一、先排查基础问题:帧尺寸匹配
直接使用/dev/video0时,摄像头实际输出的帧尺寸可能和你手动设置的640x480不符,导致视频文件头信息错误,无法被播放器识别。
修改代码,先获取摄像头实际输出的分辨率,再初始化视频写入器:
import numpy as np import cv2 source = "/dev/video0" cap = cv2.VideoCapture(source) # 获取摄像头实际输出的帧尺寸 width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH)) height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT)) print(f"摄像头实际帧尺寸: {width}x{height}") # 用实际尺寸初始化VideoWriter fourcc = cv2.VideoWriter_fourcc(*'XVID') out = cv2.VideoWriter('./output.avi', fourcc, 30.0, (width, height)) count = 0 while(cap.isOpened()): ret, frame = cap.read() if ret==True: out.write(frame) print(count) try: cv2.imshow('frame',frame) except: pass if cv2.waitKey(1) & 0xFF == ord('q') or count >100: break count +=1 else: break cap.release() out.release() cv2.destroyAllWindows()
二、推荐方案:使用GStreamer硬件加速读写视频
Jetson平台对GStreamer硬件加速支持完善,用硬件编码替代CPU编码,既能提升效率,也能避免兼容性问题。
完整代码(读写均用GStreamer硬件加速)
import numpy as np import cv2 # GStreamer硬件加速读取管道(匹配你的摄像头格式) gstr_in = "v4l2src device=/dev/video0 ! video/x-raw,format=YUY2,width=640,height=480,framerate=30/1 ! nvvidconv ! video/x-raw(memory:NVMM) ! nvvidconv ! video/x-raw, format=BGRx ! videoconvert ! video/x-raw, format=BGR ! appsink drop=1 " cap = cv2.VideoCapture(gstr_in, cv2.CAP_GSTREAMER) if not cap.isOpened(): print("无法打开摄像头") exit() width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH)) height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT)) print(f"帧尺寸: {width}x{height}") # GStreamer硬件编码写MP4(JetPack 4.6+用nvv4l2h264enc,旧版本用omxh264enc) gstr_out = f"appsrc ! video/x-raw,format=BGR,width={width},height={height},framerate=30/1 ! videoconvert ! video/x-raw,format=NV12 ! nvv4l2h264enc bitrate=5000000 ! h264parse ! mp4mux ! filesink location=output.mp4 sync=false" out = cv2.VideoWriter(gstr_out, cv2.CAP_GSTREAMER, 0, 30.0, (width, height)) if not out.isOpened(): print("无法初始化视频写入器") cap.release() exit() count = 0 while cap.isOpened(): ret, frame = cap.read() if not ret: break out.write(frame) print(count) try: cv2.imshow('frame', frame) except: pass if cv2.waitKey(1) & 0xFF == ord('q') or count > 100: break count += 1 # 必须先释放写入器,确保文件头正确写入 out.release() cap.release() cv2.destroyAllWindows()
关键注意事项
- GStreamer插件完整性:确保Jetson已安装必要的GStreamer插件,缺失则执行:
sudo apt-get install gstreamer1.0-plugins-good gstreamer1.0-plugins-bad gstreamer1.0-plugins-ugly - 正确释放资源:必须先调用
out.release()再释放摄像头,否则视频文件无法完成收尾,导致播放器无法识别。 - 编码格式选择:优先用MP4格式搭配H.264编码,兼容性远优于AVI格式。
内容的提问来源于stack exchange,提问作者M.Akyuzlu
相关产品推荐
相关产品推荐

