141笔记
分享改变你我

python如何实现win后台录屏功能

之前分享了使用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
赞(0)
未经允许不得转载:141笔记 » python如何实现win后台录屏功能