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

Python Selenium Webdriver封装ffmpeg录屏函数后无法终止进程如何解决

问题原因与解决方案

你遇到的报错本质是Python变量作用域问题:proc是recorder函数内部定义的局部变量,函数执行完成后外部作用域无法访问该变量,因此调用proc.kill()时会触发「未解析的引用'proc'」报错。

1 修正现有返回实例方案

你当前使用的返回proc实例的方案存在逻辑疏漏,修正后的可运行代码如下:

import subprocess

def recorder(recoder_file_name):
    # 把文件名作为参数传入,避免依赖外部变量,复用性更强
    proc = subprocess.Popen(['ffmpeg', '-f', 'gdigrab', '-framerate', '15', '-offset_x', '0', '-offset_y', '0', '-video_size', '1920x1080','-i', 'desktop', '-c:v', 'libx264', '-vprofile', 'baseline', '-g', '15', '-crf', '1', '-pix_fmt', 'yuv420p','-threads', '4', recoder_file_name],
    stdin=subprocess.PIPE) # 开启标准输入,用于正常结束ffmpeg,避免文件损坏
    return proc

# 第一段录屏
proc = recorder('output.mkv')
# 第一部分业务代码
driver.find_element(By.XPATH, "//*[@id='root']/div/div/div/form/input[1]").send_keys(username)
driver.find_element(By.XPATH, "//*[@id='root']/div/div/div/form/input[2]").send_keys(password)
driver.find_element(By.XPATH, "//*[@id='root']/div/div/div/form/button").click()
# 正常结束录屏,比直接kill更不容易出现文件损坏
proc.stdin.write(b'q')
proc.stdin.flush()
proc.wait()

# 第二段录屏
proc = recorder('output1.mkv')
# 第二部分业务代码
# 结束录屏
proc.stdin.write(b'q')
proc.stdin.flush()
proc.wait()

2 更优实现:上下文管理器方案

如果希望避免手动管理进程终止逻辑,防止代码异常时进程残留、录屏文件损坏,可以用Python上下文管理器封装录屏逻辑,使用更简洁:

import subprocess
from contextlib import contextmanager

@contextmanager
def screen_recorder(file_path, framerate=15, resolution='1920x1080'):
    # 支持自定义帧率、分辨率,扩展性更强
    proc = subprocess.Popen(
        ['ffmpeg', '-f', 'gdigrab', '-framerate', str(framerate), 
         '-offset_x', '0', '-offset_y', '0', '-video_size', resolution,
         '-i', 'desktop', '-c:v', 'libx264', '-vprofile', 'baseline', 
         '-g', str(framerate), '-crf', '1', '-pix_fmt', 'yuv420p',
         '-threads', '4', '-y', file_path],
        stdin=subprocess.PIPE,
        stdout=subprocess.DEVNULL,
        stderr=subprocess.DEVNULL # 屏蔽ffmpeg的日志输出,避免干扰业务日志
    )
    try:
        yield proc
    finally:
        # 无论with块内代码是否抛出异常,都会执行结束录屏的逻辑
        proc.stdin.write(b'q')
        proc.stdin.flush()
        proc.wait(timeout=5)
        if proc.poll() is None:
            # 如果正常结束失败再强制kill
            proc.kill()

# 使用方式非常简洁
with screen_recorder('output.mkv'):
    # 第一部分业务代码,自动录制这段代码的运行过程
    driver.find_element(By.XPATH, "//*[@id='root']/div/div/div/form/input[1]").send_keys(username)
    driver.find_element(By.XPATH, "//*[@id='root']/div/div/div/form/input[2]").send_keys(password)
    driver.find_element(By.XPATH, "//*[@id='root']/div/div/div/form/button").click()

with screen_recorder('output1.mkv'):
    # 第二部分业务代码
    pass

这个方案的优势:

  • 不需要手动调用启动、结束录屏的代码,上下文管理器自动处理
  • 代码异常时也能正常结束录屏进程,不会出现进程残留,也能降低录屏文件损坏概率
  • 录屏参数可自定义,复用性更强

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 15:45:07