This commit is contained in:
邓智航
2026-02-07 22:03:29 +08:00
parent 6eec265aae
commit 17d0fd920a

View File

@@ -248,38 +248,49 @@ def video_stream_thread():
server.start()
fourcc = cv2.VideoWriter_fourcc(*'avc1')
# jetson-nvenc 编码器
# -----------------------------------------------------------
# 1. 定义参数
filename = 'output.mp4'
fps = 30.0
width = 1280
height = 720
fps = 30
bitrate = 2000000 # 建议设为 2Mbps (2000000) 或 4Mbps1Mbps 对 720p 来说有点糊
filename = "output.mp4"
# 2. 构建 GStreamer 软编码管道
# 核心思路BGR (OpenCV) -> I420 (YUV) -> x264enc (CPU编码) -> MP4
gst_pipeline = (
f"appsrc ! "
f"video/x-raw, format=BGR, width={width}, height={height}, framerate={fps}/1 ! " # 1. 明确声明输入参数
f"video/x-raw, format=BGR, width={width}, height={height}, framerate={int(fps)}/1 ! "
f"queue ! "
f"videoconvert ! " # 2. CPU转换 (BGR -> BGRx)
f"video/x-raw, format=BGRx ! " # nvvidconv 对 BGRx 支持比 BGR 好
f"nvvidconv ! " # 3. 硬件转换 (搬运到 NVMM)
f"video/x-raw(memory:NVMM), format=NV12 ! " # 编码器只吃 NV12 格式的 NVMM 数据
f"nvv4l2h264enc bitrate={bitrate} control-rate=1 profile=High ! "
f"videoconvert ! "
f"video/x-raw, format=I420 ! " # 转换颜色空间给编码器
f"x264enc speed-preset=ultrafast tune=zerolatency bitrate=2000 ! " # bitrate=2000 即 2Mbps体积很小
f"h264parse ! "
f"qtmux ! "
f"filesink location={filename} "
)
# 注意cv2.CAP_GSTREAMER 是必须的
out = cv2.VideoWriter(gst_pipeline, cv2.CAP_GSTREAMER, 0, float(fps), (width, height))
print(f"[Video] 尝试启动管道: {gst_pipeline}")
# 3. 初始化 VideoWriter (必须使用 CAP_GSTREAMER)
out = cv2.VideoWriter(gst_pipeline, cv2.CAP_GSTREAMER, 0, fps, (width, height))
# 4. 严检查
if not out.isOpened():
print("❌ [Fatal Error] 视频录制启动失败!")
print("可能原因:")
print("1. 你的 OpenCV 没有开启 GStreamer 支持 (cv2.getBuildInformation() 查看)")
print("2. 系统缺少插件 (尝试 sudo apt install gstreamer1.0-plugins-ugly)")
# --- 最后的保底:如果上面都挂了,用 MPEG-4 ---
print("⚠️ 正在回退到 mp4v (MPEG-4) 编码...")
fourcc = cv2.VideoWriter_fourcc(*'mp4v')
out = cv2.VideoWriter(filename, fourcc, fps, (width, height))
else:
print("✅ [Video] H.264 软编码启动成功!视频将保存为 MP4。")
# -----------------------------------------------------------
# out1 = cv2.VideoWriter('output1.mp4', fourcc, 30.0, (1280, 720))
# out2 = cv2.VideoWriter('output2.mp4', fourcc, 30.0, (1280, 720))
if not out.isOpened():
print("❌ [Error] 视频录制启动失败!")
print("请检查:")
print("1. 分辨率是否严格匹配?(Pipeline写了1280x720但摄像头是这个吗)")
print("2. 是否安装了 GStreamer 插件?")
print(f"当前使用的 Pipeline: {gst_pipeline}")
else:
print("✅ [Video] 视频录制已启动,正在写入...")
while not stop_event.is_set():
try:
frame = video_queue.get(timeout=1)