使用OpenCV提取视频帧时遭遇grabFrame packet read max attempts exceeded报错
解决OpenCV提取视频帧时的“grabFrame packet read max attempts exceeded”报错
问题描述
使用OpenCV提取视频帧、运行分割AI模型并保存帧与掩码至文件夹时,处理一定帧数后触发报错,多环境下同一视频稳定复现。已尝试调高OPENCV_FFMPEG_READ_ATTEMPTS至10000,无明显改善。
报错信息
[ WARN:0@379.898] global cap_ffmpeg_impl.hpp:1541 grabFrame packet read max attempts exceeded, if your video have multiple streams (video, audio) try to increase attempt limit by setting environment variable OPENCV_FFMPEG_READ_ATTEMPTS (current value is 10000)
最小复现代码
import os import cv2 videofilename = "test.mp4" capture = cv2.VideoCapture(videofilename) frameNum = 0 createfolder = os.getcwd() + '/' + videofilename.split(".")[0] + '/' if not os.path.exists(createfolder): os.makedirs(createfolder) os.makedirs(createfolder + "/frames/") while True: success, frame = capture.read() if success is False: break frameNum += 1 framedownloadname = videofilename.split(".")[0] + '-fr' + str(frameNum) + '.jpg' framedownloadloc = createfolder + '/frames/' + framedownloadname print(framedownloadloc) cv2.imwrite(framedownloadloc, frame) img = cv2.imread(framedownloadloc) img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) capture.release()
解决方案
指定仅读取视频流:OpenCV默认会尝试读取所有流(视频+音频),若视频音频流存在损坏或索引异常,会导致读取卡住。初始化
VideoCapture时指定仅读取视频流:capture = cv2.VideoCapture(videofilename, cv2.CAP_FFMPEG) # 设置仅解码视频流 capture.set(cv2.CAP_PROP_STREAM_TYPE, cv2.CAP_STREAM_VIDEO)跳过异常帧继续处理:修改循环逻辑,在读取失败时尝试重新抓取帧,跳过无效帧后继续:
while True: success, frame = capture.read() if not success: # 尝试重新抓取帧 grab_success = capture.grab() if not grab_success: break # 提取抓取到的帧 success, frame = capture.retrieve() if not success: continue # 后续帧处理逻辑不变 frameNum += 1 framedownloadname = videofilename.split(".")[0] + '-fr' + str(frameNum) + '.jpg' framedownloadloc = createfolder + '/frames/' + framedownloadname print(framedownloadloc) cv2.imwrite(framedownloadloc, frame) img = cv2.imread(framedownloadloc) img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)修复视频文件索引:若视频本身存在编码或容器损坏,用FFmpeg工具修复视频索引后再处理:
ffmpeg -i test.mp4 -c:v copy -c:a copy -fix_sub_duration output_fixed.mp4调整FFmpeg读取参数:进一步调高读取尝试次数,并设置FFmpeg读取超时,在初始化
VideoCapture前配置环境变量:import os os.environ['OPENCV_FFMPEG_READ_ATTEMPTS'] = '50000' # 设置TCP传输及超时时间(单位微秒) os.environ['OPENCV_FFMPEG_CAPTURE_OPTIONS'] = 'rtsp_transport;tcp|timeout;5000000' capture = cv2.VideoCapture(videofilename, cv2.CAP_FFMPEG)
内容的提问来源于stack exchange,提问作者banjaxing
相关产品推荐
相关产品推荐

