之前分享了使用python编写一个根据关键词移动.txt文件的脚本工具,今天分享一个使用python实现win后台录屏功能。这是一个小众需求,使用pyhton监控录制屏幕其实需要考虑的因素有很多,本文代码仅仅是一个基础功能,抛砖引玉。
import os import subprocess import sys import pyautogui import cv2 import numpy as np import threading from datetime import datetime import time import signal # 解析命令行参数 parser = argparse.ArgumentParser(description="Screen Recording Service") parser.add_argument("--duration", type=int, default=10, help="Video duration in seconds (default: 3600 seconds)") parser.add_argument("--save_path", type=str, default="D:/doc/local/vid", help="Directory to save videos (default: D:/doc/local/vid)") args = parser.parse_args() VIDEO_DURATION = args.duration SAVE_PATH = args.save_path TARGET_RESOLUTION = (1280, 720) # 目标视频分辨率 FPS = 15 # 帧率 # 录屏变量 recording = False current_video = None out = None # 用于保存视频的cv2对象 # 确保 ffmpeg.exe 在正确的路径 if getattr(sys, 'frozen', False): # PyInstaller 生成的可执行文件运行时 BASE_PATH = sys._MEIPASS else: # 运行 .py 文件时 BASE_PATH = os.path.dirname(os.path.abspath(__file__)) FFMPEG_PATH = os.path.join(BASE_PATH, 'ffmpeg.exe') print(FFMPEG_PATH) # 确保保存目录存在 os.makedirs(SAVE_PATH, exist_ok=True) def record_screen(): global recording, current_video, out screen_width, screen_height = pyautogui.size() fourcc = cv2.VideoWriter_fourcc(*'XVID') # 当前时间戳作为视频文件名 current_video = f"recording_{datetime.now().strftime('%Y-%m-%d_%H-%M-%S')}.mp4" output_path = os.path.join(SAVE_PATH, current_video) # 创建视频写入对象 out = cv2.VideoWriter(output_path, fourcc, FPS, TARGET_RESOLUTION) # 开始录制 start_time = time.time() recording = True while recording and (time.time() - start_time < VIDEO_DURATION): # 捕获屏幕截图 screenshot = pyautogui.screenshot() frame = np.array(screenshot) frame = cv2.cvtColor(frame, cv2.COLOR_RGB2BGR) # 调整帧的大小 frame_resized = cv2.resize(frame, TARGET_RESOLUTION) out.write(frame_resized) # 释放资源 out.release() print(f"视频保存为: {output_path}") def save_video(): """保存并压缩视频""" global current_video if current_video: video_path = os.path.join(SAVE_PATH, current_video) # 如果发生异常退出,不进行压缩,直接保存原视频文件 if out is None: print(f"发生异常,视频未压缩,原视频文件保存在:{video_path}") else: # 使用 FFmpeg 压缩视频 compressed_video_path = os.path.join(SAVE_PATH, current_video.replace('.mp4', '_compressed.mp4')) compress_video_with_ffmpeg(video_path, compressed_video_path) # 删除原视频 os.remove(video_path) print(f"已删除原视频文件:{video_path}") def compress_video_with_ffmpeg(video_path, output_path): """使用 FFmpeg 压缩视频""" ffmpeg_cmd = [ FFMPEG_PATH, '-i', video_path, '-vcodec', 'libx264', # 使用 h.264 编码 '-crf', '23', # 控制视频质量,数值越小质量越高,文件越大 '-an', # 去除音频,文件更小 '-preset', 'fast', # 快速压缩 '-movflags', 'faststart', # 优化视频播放 '-y', output_path ] startupinfo = None if sys.platform == "win32": startupinfo = subprocess.STARTUPINFO() startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW # 隐藏窗口 try: # subprocess.run(ffmpeg_cmd, check=True) # 上面命令要弹出窗口。下面这个不会弹出 subprocess.run(ffmpeg_cmd, check=True, startupinfo=startupinfo) print(f"视频已压缩并保存为:{output_path}") except subprocess.CalledProcessError as e: print(f"FFmpeg 压缩失败: {e}") def stop_recording(): """停止录制""" global recording recording = False save_video() def schedule_recording(): """每小时录制一次""" while True: record_screen() # 开始录制 time.sleep(VIDEO_DURATION) # 等待一小时 stop_recording() # 停止录制 def start_service(): """启动录屏服务""" recording_thread = threading.Thread(target=schedule_recording) recording_thread.daemon = True # 使线程在程序退出时自动结束 recording_thread.start() print("录屏服务已启动...") def exit_gracefully(signum, frame): """程序异常退出时保存视频""" global out print("程序异常退出,正在保存视频...") if out is not None: out.release() # 确保视频流关闭 if __name__ == "__main__": # 捕获异常退出信号 signal.signal(signal.SIGINT, exit_gracefully) signal.signal(signal.SIGTERM, exit_gracefully) start_service() while True: time.sleep(1) # 保持程序运行
然后我们通过打包命令打包成可执行文件
pyinstaller -w --onefile --windowed --add-data "ffmpeg.exe:." -i .\ico.ico -n ikunScreenW.exe screen.py