Flask结合OpenCV录制10秒摄像头分段视频时长异常如何解决
问题根因
- 多录制线程共存:每次触发10秒分段时,没有停止上一轮的录制线程,所有存活的录制线程都会持续向自己绑定的视频文件写入帧,导致越早创建的视频积累的帧越多、时长越长,完全符合描述的时长占比异常现象。
- 视频文件未正常收尾:每段录制结束后没有调用
out.release()写入视频索引信息,系统无法正确计算视频时长。 - 帧率不匹配:录制逻辑中
sleep(0.05)对应每秒20帧,但视频写入器配置的是25帧率,实际生成的视频时长会和预期存在偏差。
修复后可运行代码
import cv2 import time import datetime import os import threading from threading import Thread from flask import Flask, render_template, request app = Flask(__name__) camera = cv2.VideoCapture(0) # 定义视频分辨率 size = (int(camera.get(cv2.CAP_PROP_FRAME_WIDTH)), int(camera.get(cv2.CAP_PROP_FRAME_HEIGHT))) rec = False img = None def gen_frames(): global img while True: success, frame = camera.read() if success: img = frame time.sleep(0.01) # 录制函数增加独立停止事件 def record(out, stop_event): global rec, img while rec and not stop_event.is_set(): if img is not None: out.write(img) # 匹配25帧率的写入间隔 time.sleep(0.04) @app.route('/requests',methods=['POST','GET']) def tasks(): global rec if request.form.get('rec') == 'Start/Stop Recording': rec = not rec class TimerClass(threading.Thread): def __init__(self): threading.Thread.__init__(self) self.event = threading.Event() def run(self): while rec and not self.event.is_set(): now=datetime.datetime.now() fourcc = cv2.VideoWriter_fourcc(*'XVID') p = os.path.sep.join(['clips', "vid_{}.avi".format(str(now).replace(":",''))]) out = cv2.VideoWriter(p, fourcc, 25.0, size) # 每轮录制的独立停止标志 rec_stop = threading.Event() thread = Thread(target = record, args=(out, rec_stop,)) thread.start() # 等待10秒分段 self.event.wait(10) # 停止当前轮录制线程 rec_stop.set() thread.join() # 释放当前视频文件 out.release() def stop(self): self.event.set() tmr = TimerClass() if rec: print("start recording") tmr.start() else: print("stop recording") tmr.stop() # 停止后等待线程收尾 tmr.join() elif request.method=='GET': return render_template('index.html') return render_template('index.html') if __name__ == '__main__': # 提前创建存储文件夹 if not os.path.exists('clips'): os.mkdir('clips') # 启动帧读取线程 Thread(target=gen_frames, daemon=True).start() app.run(host='0.0.0.0', threaded=True)
关键修改说明
- 为每轮录制线程增加独立停止事件,10秒时长到后先终止上一轮录制线程,再启动下一轮,避免多线程同时写入
- 每段录制结束后立即释放视频写入对象,保证视频元数据完整,时长计算正确
- 调整写入间隔匹配25帧率配置,视频时长精度误差小于0.1秒
- 补充了存储文件夹自动创建、帧读取线程启动等缺失逻辑,可直接运行
- 移除了不必要的全局变量,避免变量覆盖导致的异常
内容的提问来源于stack exchange,提问作者user14554230
相关产品推荐
相关产品推荐

