Python+CV2生成MP4缩略图报错:找不到对应格式写入器
问题描述
最初尝试在内存中存储缩略图失败,改为在相邻目录创建临时缩略图文件。图片缩略图生成功能正常,但处理MP4视频时失败,报错信息如下:
'D:\\Stuff\\Pictures\\Transit\\20230729_020700.mp4' 'D:\\Stuff\\Pictures\\Transit\\thumbs\\20230729_020700.mp4' {'name': '20230729_020700', 'ext': 'mp4', 'name_ext': '20230729_020700.mp4', 'type': 'movie', 'dtime': '20230729_140700', 'width': 1920, 'height': 1080} Traceback (most recent call last): File "C:\stuff\Working\htdocs\PSSort\picsort\main.py", line 179, in <module> list_dest_dir() File "C:\stuff\Working\htdocs\PSSort\picsort\main.py", line 108, in list_dest_dir this_file = get_file_deets(file) ^^^^^^^^^^^^^^^^^^^^ File "C:\stuff\Working\htdocs\PSSort\picsort\main.py", line 71, in get_file_deets cv2.imwrite(thumb_path,frame) cv2.error: OpenCV(4.8.1) D:\a\opencv-python\opencv-python\opencv\modules\imgcodecs\src\loadsave.cpp:696: error: (-2:Unspecified error) could not find a writer for the specified extension in function 'cv::imwrite_'
已确认输入、输出文件路径及扩展名均正确,求扩展名无误时的解决办法。
相关代码:
#input a filename. Something.jpg, thisisamov.mp4, etc. #output adds an entry def get_file_deets(name): if settings['dest_dir'][-1] == '\\': full_path_filename = settings['dest_dir']+name thumb_path = settings['dest_dir']+'thumbs\\'+name else: full_path_filename = settings['dest_dir']+'\\'+name thumb_path = settings['dest_dir']+'\\thumbs\\'+name pre_r(full_path_filename) pre_r(thumb_path) temp = {} temp['name'], temp['ext'] = name.rsplit('.') # keep track of the whole name temp['name_ext'] = name if temp['ext'] != 'mp4': image = Image.open(full_path_filename) temp['type'] = 'image' # Grab it's "taken on" date exif = image.getexif(); temp['dtime'] = exif.get(306).replace(":","").replace(' ','_') temp['width'],temp['height'] = image.size # first make a thumbnail, then B64 THAT (not the whole image) image.thumbnail((100,100)) image.save(thumb_path) image.close() else: temp['type'] = 'movie' temp['dtime'] = datetime.fromtimestamp(os.path.getmtime(full_path_filename)).strftime("%Y%m%d %H%M%S").replace(' ','_') probe = ffmpeg.probe(full_path_filename) video_streams = [stream for stream in probe["streams"] if stream["codec_type"] == "video"][0] temp['width'], temp['height'] = video_streams['width'], video_streams['height'] pre_r(temp) # Time in seconds where you want to capture the thumbnail (e.g., 10 seconds) thumbnail_time = 10 cap = cv2.VideoCapture(full_path_filename) cap.set(cv2.CAP_PROP_POS_MSEC, thumbnail_time * 1000) ret, frame = cap.read() if ret: cv2.imwrite(thumb_path,frame) cap.release() temp['size'] = f"{os.path.getsize(full_path_filename)/1000000:.2f}MBs" return temp
额外需求:简化开头的if语句写法。
解决方案
视频缩略图写入失败的解决办法
报错核心原因是:OpenCV的imwrite仅支持写入静态图像格式(如JPG、PNG),不支持MP4这类视频容器格式,所以即使路径和扩展名正确,也找不到对应的写入器。
有两种可行解决方式:
修改缩略图为静态图像格式
将视频缩略图的扩展名替换为JPG或PNG,修改视频处理分支的代码:# 在视频处理分支中添加这一行,替换thumb_path的扩展名 thumb_path = thumb_path.rsplit('.', 1)[0] + '.jpg' # 再执行imwrite if ret: cv2.imwrite(thumb_path,frame)用FFmpeg直接生成缩略图
既然已经依赖ffmpeg-python,可以直接用它生成缩略图,避免OpenCV的格式限制:# 替换原OpenCV相关代码 ffmpeg.input(full_path_filename, ss=thumbnail_time).output(thumb_path.replace('.mp4','.jpg'), vframes=1).run()这种方式兼容性更强,还能避免OpenCV读取视频时的编码兼容问题。
开头if语句的简化写法
原代码的路径拼接逻辑可以用os.path.join完全替代,它会自动处理路径分隔符,无需手动判断末尾是否有斜杠:
import os def get_file_deets(name): # 自动处理路径分隔符,无需判断末尾斜杠 full_path_filename = os.path.join(settings['dest_dir'], name) thumb_path = os.path.join(settings['dest_dir'], 'thumbs', name) # 后续代码保持不变...
如果不想引入os模块,也可以用字符串操作统一处理:
def get_file_deets(name): # 统一给dest_dir末尾添加斜杠,再拼接路径 dest_dir = settings['dest_dir'].rstrip('\\') + '\\' full_path_filename = dest_dir + name thumb_path = dest_dir + 'thumbs\\' + name # 后续代码保持不变...
内容的提问来源于stack exchange,提问作者not_a_generic_user
相关产品推荐
相关产品推荐

