如何用Python获取视频元数据及帧像素数据
在Python中提取视频元数据与帧像素数据的方案
下面提供两种实用的Python实现方案,既能提取帧率、尺寸、比特率、时长等元数据,也能将帧转换为2D NumPy数组:
方法一:OpenCV + FFprobe(灵活可控)
OpenCV擅长帧像素提取,FFprobe(FFmpeg配套工具)可获取完整元数据,两者结合能覆盖所有需求。
安装依赖
pip install opencv-python numpy # 需额外安装FFmpeg,确保`ffprobe`命令可在终端调用
提取帧数据与基础元数据
import cv2 import numpy as np def get_video_frames_and_basic_info(video_path): cap = cv2.VideoCapture(video_path) # 读取基础元数据 fps = cap.get(cv2.CAP_PROP_FPS) width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH)) height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT)) total_frames = int(cap.get(cv2.CAP_PROP_FRAME_COUNT)) duration = total_frames / fps # 计算视频时长(秒) # 逐帧提取并转为2D灰度数组 frames = [] while cap.isOpened(): ret, frame = cap.read() if not ret: break # 若需彩色帧,移除该行即可(此时帧为3D数组) gray_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) frames.append(gray_frame) cap.release() frames_array = np.array(frames) # 形状:(总帧数, 高度, 宽度) return { "fps": fps, "width": width, "height": height, "total_frames": total_frames, "duration": duration, "frames": frames_array }
用FFprobe获取完整元数据(比特率、编码等)
import subprocess import json def get_full_video_metadata(video_path): cmd = [ "ffprobe", "-v", "quiet", "-print_format", "json", "-show_format", "-show_streams", video_path ] result = subprocess.run(cmd, capture_output=True, text=True) metadata = json.loads(result.stdout) # 解析关键元数据 format_data = metadata["format"] bitrate_kbps = int(format_data["bit_rate"]) / 1000 codec = metadata["streams"][0]["codec_name"] file_size = int(format_data["size"]) return { "bitrate_kbps": bitrate_kbps, "codec": codec, "file_size_bytes": file_size, "raw_metadata": metadata # 返回完整原始元数据 }
方法二:MoviePy(一站式简洁方案)
MoviePy基于FFmpeg封装,语法更直观,无需分开调用工具即可获取所有数据。
安装依赖
pip install moviepy numpy
提取所有数据
from moviepy.editor import VideoFileClip import numpy as np def extract_video_all_data(video_path): clip = VideoFileClip(video_path) # 提取核心元数据 fps = clip.fps width, height = clip.size duration = clip.duration bitrate_kbps = clip.reader.bitrate / 1000 codec = clip.reader.codec # 逐帧转为2D灰度数组 frames = [] for rgb_frame in clip.iter_frames(): # RGB转灰度的加权公式 gray_frame = np.dot(rgb_frame[..., :3], [0.2989, 0.5870, 0.1140]).astype(np.uint8) frames.append(gray_frame) frames_array = np.array(frames) clip.close() return { "fps": fps, "width": width, "height": height, "duration": duration, "bitrate_kbps": bitrate_kbps, "codec": codec, "frames": frames_array }
注意事项
- 处理大视频时,一次性存储所有帧会占用大量内存,建议改为逐帧处理而非全部存入数组
- 若需彩色帧,跳过灰度转换步骤即可,此时帧数组为3D结构(高度, 宽度, 3)
- FFmpeg需确保已添加至系统环境变量,否则MoviePy和FFprobe可能无法正常工作
内容的提问来源于stack exchange,提问作者Yoav Damari
相关产品推荐
相关产品推荐

