本文详解如何基于 opencv 实现实时视频录制功能,包括初始化 videowriter、逐帧写入、资源释放等关键步骤,并适配 flask web 应用场景。
本文详解如何基于 opencv 实现实时视频录制功能,包括初始化 videowriter、逐帧写入、资源释放等关键步骤,并适配 flask web 应用场景。
在 Python 中使用 OpenCV 录制视频,核心在于结合 cv2.VideoCapture(捕获帧)与 cv2.VideoWriter(写入帧)协同工作。不同于仅显示视频流的场景,录制需持续接收每一帧并写入磁盘文件,最终生成标准视频格式(如 AVI、MP4)。以下为完整、可落地的实现方案。
cv2.VideoWriter 需要四个关键参数:输出文件路径、编码器(FourCC)、帧率(FPS)和帧尺寸(宽×高)。注意:帧尺寸必须与实际采集帧一致,否则写入失败且无报错。常见编码器如下:
| 编码器 | 说明 | 兼容性 |
|---|---|---|
| 'XVID' | 跨平台通用,生成 .avi 文件 | ✅ Windows/Linux/macOS |
| 'mp4v' | MP4 容器推荐,生成 .mp4 文件 | ✅(需 OpenCV ≥ 3.0,部分系统需 FFmpeg 支持) |
| 'avc1' | H.264 编码(需系统支持) | ⚠️ 依赖底层编解码器 |
示例初始化(假设摄像头分辨率为 640×480):
self.fourcc = cv2.VideoWriter_fourcc(*'XVID')self.out = cv2.VideoWriter('output.avi', self.fourcc, 20.0, (640, 480))
? 提示:可通过 self.video.get(cv2.CAP_PROP_FRAME_WIDTH) 和 self.video.get(cv2.CAP_PROP_FRAME_HEIGHT) 动态获取实际分辨率,增强健壮性。
立即学习“Python免费学习笔记(深入)”;
每帧读取后,先写入视频文件,再编码为 JPEG 供 Web 流传输:
def get_frame(self): ret, frame = self.video.read() if ret: # 确保尺寸匹配(关键!) if frame.shape[1] != 640 or frame.shape[0] != 480: frame = cv2.resize(frame, (640, 480)) # 统一分辨率 self.out.write(frame) # 写入视频文件 ret, jpeg = cv2.imencode('.jpg', frame) return jpeg.tobytes() return None
务必在对象销毁时调用 release(),否则视频文件可能不完整或无法播放:
def __del__(self): self.video.release() self.out.release() # 必须显式调用!
import datetimetimestamp = datetime.datetime.now().strftime("%Y%m%d_%H%M%S")self.out = cv2.VideoWriter(f'output_{timestamp}.avi', self.fourcc, 20.0, (640, 480))
完成以上修改后,重启 Flask 应用,访问 /video_feed 即可实时预览并同步录制至本地 output.avi。录制结束后,该文件可直接用 VLC、PotPlayer 或系统默认播放器打开验证。