You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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这类视频容器格式,所以即使路径和扩展名正确,也找不到对应的写入器。

有两种可行解决方式:

  1. 修改缩略图为静态图像格式
    将视频缩略图的扩展名替换为JPG或PNG,修改视频处理分支的代码:

    # 在视频处理分支中添加这一行,替换thumb_path的扩展名
    thumb_path = thumb_path.rsplit('.', 1)[0] + '.jpg'
    # 再执行imwrite
    if ret:
        cv2.imwrite(thumb_path,frame)
    
  2. 用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.09 14:44:57