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

Windows登出/关机时Python录屏MP4无法播放如何解决

问题根因

你遇到的MP4文件损坏问题,核心原因是进程被强制终止时,OpenCV的VideoWriter没有执行release()方法,MP4的文件头、帧索引信息没有写入到文件尾部,导致播放器无法识别文件结构。
你做的对照测试已经验证了这点:通过Ctrl+C、IDE停止按钮终止脚本时,Python进程会触发常规退出流程,隐式执行资源释放,文件可以正常播放;而强制关闭CMD窗口、系统登出/关机时,系统会直接终止进程,不会走常规的资源释放流程,因此文件损坏。

实现方案

核心目标是在所有进程退出场景下,保证VideoWriter.release()被执行,具体实现分两步:

1. 注册Windows系统信号处理函数

Windows在控制台关闭、用户登出、系统关机时,会给所有运行中的控制台进程发送对应控制信号,提前注册信号处理函数即可在进程被终止前拿到执行权,完成文件收尾。
需要处理的信号包括:

  • CTRL_C_EVENT:Ctrl+C终止
  • CTRL_BREAK_EVENT:Ctrl+Break终止
  • CTRL_CLOSE_EVENT:点击控制台窗口关闭按钮
  • CTRL_LOGOFF_EVENT:用户登出系统
  • CTRL_SHUTDOWN_EVENT:系统关机

完整可运行代码示例:

import cv2
import numpy as np
import mss
import win32api
import sys

# 全局资源实例
video_writer = None
screen_capture = None

def release_resource():
    """统一的资源释放逻辑,保证MP4文件正确封装"""
    global video_writer, screen_capture
    if video_writer is not None and video_writer.isOpened():
        video_writer.release()
    if screen_capture is not None:
        screen_capture.close()

def console_signal_handler(signal_type):
    """Windows控制台信号处理回调"""
    if signal_type in [
        win32api.CTRL_C_EVENT,
        win32api.CTRL_BREAK_EVENT,
        win32api.CTRL_CLOSE_EVENT,
        win32api.CTRL_LOGOFF_EVENT,
        win32api.CTRL_SHUTDOWN_EVENT
    ]:
        release_resource()
        return True
    return False

# 注册信号处理
win32api.SetConsoleCtrlHandler(console_signal_handler, True)

# 原有初始化逻辑
screen_capture = mss.mss()
fourcc = cv2.VideoWriter_fourcc(*'mp4v')
video_writer = cv2.VideoWriter(
    recording_file_name_location, 
    fourcc, 
    20.0, 
    (1920, 1080)
)

# 录制主循环,加finally做双保险
try:
    while True:
        frame = screen_capture.grab(screen_resolution)
        video_writer.write(np.array(frame))
except KeyboardInterrupt:
    pass
finally:
    release_resource()

注意:系统关机/登出场景下,Windows只会给每个进程预留最多5秒的清理时间,release()操作仅写入文件元数据,耗时在毫秒级,完全可以在时间窗口内完成。

2. 高鲁棒性优化(可选)

如果需要应对极端场景下信号处理失效的问题,可以采用分段录制方案:

  • 不要把所有帧写入单个MP4文件,每1~2分钟生成一个独立的小MP4文件
  • 进程意外终止时,已经完成写入的小文件都是完整可播放的,不会出现整个录像全损的情况
  • 录制结束后可以调用ffmpeg或者OpenCV把所有分段文件拼接成完整视频
    如果你的脚本是通过pythonw.exe无窗口后台运行的,没有附加控制台,无法收到上述控制台信号,需要创建一个隐藏的顶层窗口,监听WM_ENDSESSION窗口消息来触发资源释放。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.01 04:03:26