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

Linux平台仅录制指定进程屏幕输出的技术实现方案咨询

Linux指定进程录屏实现方案

你推测的「在进程画面输出抵达屏幕前拦截抓取」的思路完全可行。Linux桌面的图形渲染链路中,每个进程的UI内容都会作为独立的渲染缓存提交给系统合成器,再由合成器叠加所有窗口后输出到屏幕,和标准输出的流程逻辑类似,完全可以单独抓取指定进程的所有渲染内容,完全不会混入其他进程的弹窗、悬浮窗等界面。

原方案的问题

你贴的PIL+OpenCV全局区域抓屏的方案,是直接读取合成器最终输出的全屏帧,自然无法区分不同进程的内容,只能做区域裁剪,不符合你的需求。

import datetime

from PIL import ImageGrab
import numpy as np
import cv2

time_stamp = datetime.datetime.now().strftime('%Y-%m-%d %H-%M-%S')
file_name = f'{time_stamp}.mp4'
fourcc = cv2.VideoWriter_fourcc('m', 'p', '4', 'v')
captured_video = cv2.VideoWriter(file_name, fourcc, 20.0, (630, 330))

while True:
    img = ImageGrab.grab(bbox=(0, 0, 630, 330))
    img_np = np.array(img)
    img_final = cv2.cvtColor(img_np, cv2.COLOR_BGR2RGB)
    cv2.imshow("Screen Recorder", img_final)
    captured_video.write(img_final)
    if cv2.waitKey(10) == ord('q'):
        break

可行实现路径

1. X11桌面环境实现(兼容性最高)

当前绝大多数Linux发行版默认还是X11架构,可按如下步骤实现:

  • 首先通过PID匹配该进程关联的所有X11窗口:遍历所有顶层窗口的_NET_WM_PID属性,筛选出和目标PID一致的窗口ID集合
  • 直接抓取指定窗口的渲染缓存:调用Xlib的XGetImage接口针对窗口ID做捕获,只要开启窗口内容重定向属性,哪怕窗口被遮挡、最小化也能正常抓取内容,不会混入其他进程的界面
  • 后续的视频编码逻辑可以直接沿用你现有代码中OpenCV写MP4的部分,只需要替换掉帧来源即可

2. Wayland桌面环境实现

Wayland因为安全限制不允许随意读取其他进程窗口内容,可通过xdg-desktop-portal的窗口捕获接口,指定仅捕获目标PID所属的窗口即可,GNOME、KDE等主流桌面环境都已支持该能力。

简化代码示例(Python X11版本)

把你原有代码的抓屏逻辑替换为如下内容即可:

import Xlib.display
from PIL import Image
import numpy as np
import cv2

# 初始化X11连接
display = Xlib.display.Display()
root = display.screen().root
target_pid = 31328 # 替换为你要录制的进程PID

# 遍历匹配目标PID的窗口
target_window = None
for window in root.query_tree().children:
    pid = window.get_full_property(display.intern_atom('_NET_WM_PID'), 0)
    if pid and pid.value[0] == target_pid:
        target_window = window
        break

# 原有编码逻辑保留,仅替换帧来源
time_stamp = datetime.datetime.now().strftime('%Y-%m-%d %H-%M-%S')
file_name = f'{time_stamp}.mp4'
geom = target_window.get_geometry()
fourcc = cv2.VideoWriter_fourcc('m', 'p', '4', 'v')
captured_video = cv2.VideoWriter(file_name, fourcc, 20.0, (geom.width, geom.height))

while True:
    raw_img = target_window.get_image(0, 0, geom.width, geom.height, Xlib.X.ZPixmap, 0xffffffff)
    img = Image.frombytes("RGB", (geom.width, geom.height), raw_img.data, "raw", "BGRX")
    img_np = np.array(img)
    img_final = cv2.cvtColor(img_np, cv2.COLOR_BGR2RGB)
    cv2.imshow("Screen Recorder", img_final)
    captured_video.write(img_final)
    if cv2.waitKey(10) == ord('q'):
        break

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 04:27:02