新艳录屏器(跨平台自适应)
一套脚本跑 Windows / macOS / Linux,不写死任何分辨率、路径、设备名,全部运行时自动探测。
环境要求
- Python 3.8+(标准库即可,无第三方依赖)
- FFmpeg(脚本会自动找;找不到会给出安装指引)
- Windows:https://www.gyan.dev/ffmpeg/builds/
- macOS:
brew install ffmpeg - Linux:
sudo apt install ffmpeg
先跑自检,确认环境:
python scripts/recorder.py info
快速开始
# 无限长录制(默认,每 3 分钟自动切一段),后台跑
python scripts/recorder.py start
# 录 60 秒全屏,自动停
python scripts/recorder.py start -d 60
# 录指定窗口(先列窗口)
python scripts/recorder.py windows
python scripts/recorder.py start -w "记事本"
# 停止录制
python scripts/recorder.py stop
# 把录出来的多段合成一条完整视频
python scripts/recorder.py list
python scripts/recorder.py merge "录屏_20260829_120000.mp4"
命令一览
| 命令 | 作用 |
|---|---|
info |
环境自检:系统、FFmpeg、编码器、显示器、声卡 |
monitors |
列出所有显示器及分辨率 |
windows |
列出可见窗口(Windows 完整,其他平台尽力) |
devices |
列出可用音频设备 |
start |
开始录制 |
stop |
优雅停止(保证文件头完整可播) |
status |
查看正在录的状态 |
list |
列出目录里的录制(多片段会标"可合并") |
merge |
把多片段无损合成一条完整视频 |
kill |
杀残留进程(--all 连其他 ffmpeg 一起杀) |
start 参数
| 参数 | 说明 |
|---|---|
-d, --duration |
录制秒数,默认 0 = 无限长 |
-r, --region |
full / left / right / top / bottom / center / 宽,高,左,上 |
-m, --monitor |
显示器序号(从 1 开始),默认主屏 |
-w, --window |
窗口标题关键词(模糊匹配) |
-o, --out |
输出文件路径 |
-q, --quality |
draft(小文件)/ normal(默认)/ high |
--no-mouse |
不捕获鼠标指针 |
--no-audio |
不录声音 |
--audio NAME |
手动指定音频设备名 |
--cpu |
强制 CPU 软编(显卡不支 NVENC 时用) |
--ffmpeg PATH |
手动指定 ffmpeg |
三大自适应机制
1. 屏幕自适应(不写死分辨率)
- 运行时枚举所有显示器(Windows
EnumDisplayMonitors/ macOSosascript/ Linuxxrandr) - 所有区域预设按实际分辨率动态计算:
left/right= 屏幕宽度的一半center= 屏幕 80% 区域并居中top/bottom= 屏幕高度的一半- 多显示器用
-m 2指定第二块屏 - 分辨率自动取偶数(H.264 要求)
2. 音频自适应(有就录,没有就跳过)
- 自动探测音频设备:Windows
dshow/ macOSavfoundation/ Linuxpulse+alsa - 探测不到 → 只录画面,不报错、不中断
- 带声音启动失败 → 自动降级纯视频重试一次
- 有设备但探测不到时,用
--audio "设备名"手动指定 - 不想录声音用
--no-audio
3. 平台与编码器自适应
- 抓屏后端:Windows
gdigrab→ macOSavfoundation→ Linuxx11grab - FFmpeg 查找顺序:
--ffmpeg参数 → 环境变量FFMPEG_PATH→ PATH → 常见安装位置 - 编码器:优先
h264_nvenc硬编,不支持自动回退libx264 - 停止信号:Windows
CTRL_BREAK_EVENT,UnixSIGINT(都能让 FFmpeg 写完整文件头)
无限长录制与切片
无限长录制默认每 3 分钟自动切一个文件(文件名_000.mp4、_001.mp4…)。
为什么切片:录几小时的单文件一旦中途崩溃/断电,整个文件报废(缺 moov 头无法播放)。切片后最多只丢当前这 3 分钟。
看回放时合成一条:
python scripts/recorder.py merge "录屏_20260829_120000.mp4"
# → 输出 录屏_20260829_120000_完整版.mp4
合并用 concat 解复用器 -c copy 无损拼接,不重编码,几 GB 素材也是秒级完成。
进程兜底(重要)
录屏最怕"以为停了其实还在录":
stop发优雅停止信号,等待 FFmpeg 写完文件头- 超时自动强杀
- 停止后再复查进程是否真退出,没退出会明确警告
kill兜底清理残留,kill --all连其他 ffmpeg 一起杀kill执行完会复查并报告是否还有残留
python scripts/recorder.py kill # 只杀本工具的录制进程
python scripts/recorder.py kill --all # 杀掉所有 ffmpeg 进程(注意可能误杀别人的任务)
踩坑记录(技术通用)
tasklist /FI "IMAGENAME eq xxx"在 Git Bash 下不可靠:可能返回空导致误判进程已死,实测留下 4 个僵尸 FFmpeg 持续偷录十几分钟。正确做法用tasklist | grep -i ffmpeg全量排查。脚本里list_ffmpeg_pids()就是这么做的。- 后台录制必须
stdin=subprocess.DEVNULL:用PIPE时父进程一退出,子进程 stdin 断裂会自杀。 tasklist输出是 CP936 中文编码:Python 里要用 bytes 匹配str(pid).encode() in out,不能text=True按 UTF-8 解码(会抛 UnicodeDecodeError 导致误判)。- 分段模式下
-t必须插在输出文件之前:曾经用cmd.insert(-2)把-t插到了-segment_format和mp4中间,导致mp4被当成输出文件名,报Output file does not contain any stream。正确做法是先cmd.index(输出文件路径)定位。 - 窗口标题不能直接进文件名:含零宽字符、冒号、斜杠等非法字符且超长。必须 sanitize(去零宽/控制字符 → 去非法字符 → 空白转下划线 → 截断)。
- 合并用的临时列表文件要放系统临时目录:放输出目录删不掉时会污染用户工作区。
- 被占用的文件删不掉:Windows 报"另一个程序正在使用此文件"= 还有进程在写。先
kill再删。 - 分辨率必须是偶数:H.264 要求,脚本已自动
w - (w % 2)。
隐私说明
- 本技能不含任何个人凭据、账号信息
- 所有状态/日志文件写在系统临时目录,不污染用户目录
- 录屏内容完全由使用者决定,脚本不会上传任何数据
- 用
kill清理残留进程,可避免后台偷录
输出文件说明
| 文件 | 含义 |
|---|---|
xxx_000.mp4 xxx_001.mp4 |
分段录制的切片 |
xxx_完整版.mp4 |
merge 合成的完整视频 |