安装相关库:
pip uninstall opencv-python
pip install opencv-python -i https://pypi.tuna.tsinghua.edu.cn/simple
如果报错可以使用:
pip install opencv-python --trusted-host pypi.tuna.tsinghua.edu.cn --trusted-host files.pythonhosted.org --trusted-host pypi.org --no-cache-dir --disable-pip-version-check -i http://pypi.tuna.tsinghua.edu.cn/simple/
相关脚本:
import cv2
import os
import sys
def extract_video_first_frame(video_dir, output_img_format="jpg"):
"""
提取指定目录下所有视频文件的第一帧作为封面图(修复中文文件名乱码问题)
:param video_dir: 视频文件所在目录(绝对路径/相对路径均可,支持中文)
:param output_img_format: 输出封面图的格式,支持jpg、png等
"""
# 定义常见的视频文件后缀(可根据需要补充)
supported_video_formats = ('.mp4', '.avi', '.mov', '.mkv', '.flv', '.wmv', '.webm', '.mpeg', '.mpg')
# 校验目标目录是否存在
if not os.path.exists(video_dir):
print(f"错误:目录 {video_dir} 不存在!")
return
# 适配系统编码,解决中文路径问题
if sys.platform == "win32":
# Windows系统默认编码为gbk,适配中文路径
os.environ["OPENCV_IO_ENABLE_JASPER"] = "1"
def get_correct_path(path):
return path.encode('utf-8').decode('gbk', errors='ignore')
else:
# Linux/Mac系统默认编码为utf-8,直接使用
def get_correct_path(path):
return path
# 遍历目录下的所有文件
for file_name in os.listdir(video_dir):
# 过滤非支持的视频格式(保留中文文件名,不转码)
if not file_name.lower().endswith(supported_video_formats):
continue
# 拼接完整的视频路径和输出图片路径(原生中文,不转码)
video_file_path = os.path.join(video_dir, file_name)
img_file_name = os.path.splitext(file_name)[0] + f".{output_img_format}"
img_file_path = os.path.join(video_dir, img_file_name)
# 跳过目录,只处理文件
if not os.path.isfile(video_file_path):
continue
# 关键修复:通过cv2的CAP_FFMPEG后端,兼容中文视频路径(需确保安装的opencv包含ffmpeg)
cap = cv2.VideoCapture(video_file_path, cv2.CAP_FFMPEG)
if not cap.isOpened():
print(f"警告:无法打开视频文件 {file_name},跳过该文件")
continue
# 读取第一帧
ret, frame = cap.read()
if ret:
# 关键修复:避免cv2.imwrite直接处理中文路径,先将帧数据写入内存,再通过Python原生文件操作保存
# 步骤1:将帧编码为指定格式的二进制数据
encode_param = [cv2.IMWRITE_JPEG_QUALITY, 95] if output_img_format.lower() == "jpg" else [cv2.IMWRITE_PNG_COMPRESSION, 0]
ret_val, img_buffer = cv2.imencode(f".{output_img_format}", frame, encode_param)
if ret_val:
# 步骤2:通过Python原生文件操作(支持中文)写入文件,避免乱码
with open(img_file_path, 'wb') as f:
f.write(img_buffer.tobytes())
print(f"成功提取:{file_name} -> {img_file_name}")
else:
print(f"警告:无法编码 {file_name} 的第一帧,跳过该文件")
else:
print(f"警告:无法读取 {file_name} 的第一帧,跳过该文件")
# 释放视频资源
cap.release()
if __name__ == "__main__":
# ---------------------- 配置区域 ----------------------
# 替换为你的视频目录路径(支持中文,Windows用r'',Linux/Mac用/)
TARGET_VIDEO_DIR = r"C:\Users\YourName\Videos\我的视频文件夹"
# 输出封面图格式(可选:jpg、png)
OUTPUT_IMAGE_FORMAT = "jpg"
# -------------------------------------------------------
# 执行提取操作
extract_video_first_frame(TARGET_VIDEO_DIR, OUTPUT_IMAGE_FORMAT)
print("\n所有可处理的视频帧提取完成!")