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

如何修改Python脚本实现循环运行并解决OpenCV报错问题

解决游戏直播回放脚本的循环运行与OpenCV问题

嘿,作为Python新手能自己捣鼓直播回放功能已经超棒啦!我来帮你调整脚本,解决那些报错,让它能稳定循环运行,完美实现“只播放最新视频一次”的需求~

核心问题修复与优化点

我先梳理下你当前脚本的几个痛点,然后逐个解决:

  • 删除replay.mp4时如果文件不存在会报错
  • 无法持续循环检测新的视频片段
  • OpenCV播放时可能出现的视频读取失败、窗口未正确释放等问题

优化后的完整代码

import os
import time
import cv2
from pathlib import Path

# 配置你的视频目录
VIDEO_DIR = "./your_video_folder"  # 替换成你的实际路径
CHECK_INTERVAL = 2  # 每隔2秒检查一次新文件(可根据需求调整)

def get_latest_video(directory):
    """获取目录中最新的视频文件(支持常见视频格式)"""
    video_extensions = (".mp4", ".avi", ".mov", ".mkv")
    files = [f for f in Path(directory).iterdir() if f.suffix.lower() in video_extensions]
    if not files:
        return None
    # 根据文件修改时间排序,取最新的
    return max(files, key=lambda x: x.stat().st_mtime)

def play_video(video_path):
    """用OpenCV在缩放窗口中播放视频,播放完成后自动关闭"""
    cap = cv2.VideoCapture(str(video_path))
    if not cap.isOpened():
        print(f"无法打开视频文件: {video_path}")
        return
    
    # 获取视频宽高,设置缩放窗口大小(比如缩放到原尺寸的70%)
    width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH) * 0.7)
    height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT) * 0.7)
    
    while cap.isOpened():
        ret, frame = cap.read()
        if not ret:
            break  # 播放完成
        
        # 缩放帧并显示
        resized_frame = cv2.resize(frame, (width, height))
        cv2.imshow("Live Replay", resized_frame)
        
        # 按q可以提前退出播放
        if cv2.waitKey(25) & 0xFF == ord('q'):
            break
    
    # 释放资源,关闭窗口
    cap.release()
    cv2.destroyAllWindows()
    # 额外加个延迟,确保窗口完全关闭(避免OpenCV窗口残留问题)
    time.sleep(0.5)

def main():
    last_played_file = None  # 记录上一次播放的文件,避免重复播放
    print("直播回放脚本已启动,按Ctrl+C停止...")
    
    try:
        while True:
            latest_video = get_latest_video(VIDEO_DIR)
            if not latest_video:
                print("目录中暂无视频文件,等待中...")
                time.sleep(CHECK_INTERVAL)
                continue
            
            # 只播放最新的、未播放过的视频
            if latest_video != last_played_file:
                print(f"发现新视频,准备播放: {latest_video.name}")
                
                # 安全删除旧的replay.mp4(如果存在)
                replay_path = Path(VIDEO_DIR) / "replay.mp4"
                try:
                    if replay_path.exists():
                        replay_path.unlink()
                except OSError as e:
                    print(f"删除旧replay.mp4时出错: {e}")
                
                # 重命名最新视频为replay.mp4
                try:
                    latest_video.rename(replay_path)
                    # 播放视频
                    play_video(replay_path)
                    # 更新已播放记录
                    last_played_file = replay_path  # 注意这里要记录重命名后的路径
                except OSError as e:
                    print(f"重命名或播放视频时出错: {e}")
                    # 如果重命名失败,直接播放原文件作为备选
                    play_video(latest_video)
                    last_played_file = latest_video
            else:
                # 没有新视频,等待后继续检测
                time.sleep(CHECK_INTERVAL)
                
    except KeyboardInterrupt:
        print("\n脚本已停止")

if __name__ == "__main__":
    main()

关键改进点说明

  1. 安全删除文件:用try-except包裹删除操作,同时先判断文件是否存在,彻底避免“文件不存在”的报错
  2. 循环检测新文件:通过while True循环+时间间隔,持续监控目录,用last_played_file确保同一个视频只播放一次
  3. 鲁棒的视频播放:
    • 先检查视频是否成功打开,避免读取失败的报错
    • 播放完成后强制释放OpenCV资源并关闭窗口,解决窗口残留问题
    • 增加了提前退出播放的功能(按q键)
  4. 灵活的视频格式支持:支持mp4/avi/mov/mkv等常见格式,你可以根据自己的需求添加更多格式

现在这个脚本可以稳定循环运行,解决了你提到的所有问题~

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 08:30:56