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

为何Python的MoviePy与OpenCV获取的视频FPS和Windows、VLC不一致?

问题

我有一段以120 fps录制的视频,在Windows属性中确认其帧率为120 fps,VLC播放器中也显示该帧率。但使用Python的moviepy或cv2库获取视频帧率时,得到的却是错误的25 fps。视频采用32位FFDshow codec压缩。

相关代码:

import cv2
from moviepy.editor import *

def main():
    # Define file name
    video_name = r'C:\Users\npires.OMG\OneDrive - OMG PLC\Work Projects\Convert AVI to MP4 H264\Test\Test\Walk ' \
                 r'01.2117813.20210614134127.avi'

# import the video into Python
video_data_cv2 = cv2.VideoCapture(video_name)
video_data_moviepy = VideoFileClip(video_name)

# get the video frame rate
fps_moviepy = video_data_moviepy.fps
fps_cv2 = video_data_cv2.get(cv2.CAP_PROP_FPS)
原因

这种差异的核心问题是cv2和moviepy依赖的底层解析库(OpenCV/FFmpeg)对老旧的32位FFDshow编码AVI的元数据读取存在偏差,这类编码的视频帧率信息可能存储在非标准的容器字段中,导致Python库误读为默认的25fps。而Windows和VLC使用的解析逻辑更兼容这类旧编码,能正确提取真实帧率。

解决方案

1. 手动计算真实帧率(最可靠)

通过统计视频总帧数和实际时长来计算,避免依赖元数据读取:

使用cv2实现

import cv2

video_path = r"你的视频路径"
cap = cv2.VideoCapture(video_path)

# 获取总帧数
total_frames = int(cap.get(cv2.CAP_PROP_FRAME_COUNT))
# 获取视频总时长(秒)
total_duration = cap.get(cv2.CAP_PROP_POS_MSEC) / 1000 if cap.get(cv2.CAP_PROP_POS_MSEC) != 0 else total_frames / 25  #  fallback值
# 手动计算帧率
actual_fps = total_frames / total_duration if total_duration != 0 else 0

cap.release()
print(f"真实帧率:{actual_fps}")

使用moviepy实现

from moviepy.editor import VideoFileClip

video_path = r"你的视频路径"
clip = VideoFileClip(video_path)

# 总帧数除以时长得到真实帧率
actual_fps = clip.reader.nframes / clip.duration
print(f"真实帧率:{actual_fps}")

clip.close()

2. 用FFprobe直接读取准确帧率

FFprobe(FFmpeg套件的一部分)能像VLC一样正确解析这类编码的视频,可在Python中调用命令行获取结果:

import subprocess
import re

video_path = r"你的视频路径"
# 调用ffprobe获取帧率(分数形式,如120/1)
result = subprocess.run(
    ["ffprobe", "-v", "error", "-select_streams", "v:0", "-show_entries", "stream=r_frame_rate", "-of", "default=noprint_wrappers=1:nokey=1", video_path],
    capture_output=True,
    text=True
)
fps_str = result.stdout.strip()
# 转换为浮点数
num, den = map(int, fps_str.split('/'))
actual_fps = num / den
print(f"真实帧率:{actual_fps}")

注:需确保系统已安装FFmpeg并添加到环境变量。

3. 转码为标准编码格式

将视频转码为H.264编码的MP4格式,这类标准格式的元数据能被cv2和moviepy正确识别:
用FFmpeg命令行转码:

ffmpeg -i input.avi -c:v libx264 -crf 23 output.mp4

转码后再用Python库读取帧率即可得到正确结果。


内容的提问来源于stack exchange,提问作者Nev Pires

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 12:50:57