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

Python如何给视频添加滤镜且保证输出视频与原视频时长一致

解决思路

你猜测的方向是对的,核心问题出在输出参数和帧处理逻辑的问题上,具体可按以下步骤修正:

  • 替换硬编码的输出帧率,匹配原视频实际帧率
    视频时长 = 总帧数 ÷ 帧率,你直接写死输出帧率为30,如果原视频帧率不是30,相同帧数下时长必然不一致。你可以用cap.get(cv2.CAP_PROP_FPS)直接读取原视频的真实帧率,传给VideoWriter的第三个参数即可。
  • 补全帧读取校验和写入逻辑,避免丢帧
    你现有代码的循环里没有判断读取帧是否成功的ret返回值,也没有把处理后的帧写入输出视频,再加上cv2.waitKey的中断逻辑可能被误触发,很容易出现实际写入的帧数比原视频总帧数少的情况,导致时长变短。
  • 增加帧数校验环节
    读取原视频总帧数cap.get(cv2.CAP_PROP_FRAME_COUNT),处理完成后对比实际写入的帧数,确认两者完全一致即可排除帧丢失问题。
修正后可直接运行的代码
import cv2
import numpy as np
from PIL import Image, ImageOps, ImageEnhance, ImageChops

cap = cv2.VideoCapture('fish.mp4')

# 读取原视频的参数,全部沿用原参数避免不匹配
frame_width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
frame_height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
fps = cap.get(cv2.CAP_PROP_FPS)
total_frames = int(cap.get(cv2.CAP_PROP_FRAME_COUNT))
size = (frame_width, frame_height)

# 输出帧率用原视频的fps,不要硬写30
result = cv2.VideoWriter('end.avi', cv2.VideoWriter_fourcc(*'MJPG'), fps, size)

# 统计实际写入的帧数,可选用于校验
write_count = 0

while cap.isOpened():
    ret, frame = cap.read()
    # 读到视频末尾直接跳出
    if not ret:
        break
    
    # 帧编辑部分写在这里
    # 示例:把帧转成灰度
    # frame = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
    # frame = cv2.cvtColor(frame, cv2.COLOR_GRAY2BGR) # 单通道转三通道才能正常写入
    
    # 写入处理后的帧,不能漏
    result.write(frame)
    write_count += 1

    # 如果不需要实时预览可以删掉下面这行,避免误触q提前中断
    # if cv2.waitKey(1) & 0xFF == ord('q'):
    #     break

# 校验帧数
print(f"原视频总帧数:{total_frames},实际写入帧数:{write_count}")
if total_frames == write_count:
    print("帧数一致,时长不会出现偏差")
else:
    print("存在丢帧,请检查处理逻辑")

cap.release()
result.release() # 不要漏释放VideoWriter
cv2.destroyAllWindows()
额外注意事项
  • 如果输出需要保留原视频音频,OpenCV本身不处理音频轨道,你可以用ffmpeg工具把原视频的音频合并到输出视频中,该操作不影响视频轨道的时长。
  • 如果需要输出MP4格式,把fourcc改成cv2.VideoWriter_fourcc(*'mp4v'),文件后缀改成.mp4即可,只要帧率和帧数匹配就不会影响时长。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.13 16:15:02