如何让 Python 以正确的帧速率捕获屏幕

问题描述 投票:0回答:1

我有这个 python 脚本,应该在 mac os 上记录我的屏幕。

import cv2
import numpy as np
from PIL import ImageGrab
import subprocess
import time

def record_screen():
    # Define the screen resolution
    screen_width, screen_height = 1440, 900  # Adjust this to match your screen resolution
    fps = 30  # Target FPS for recording

    # Define the ffmpeg command
    ffmpeg_cmd = [
        'ffmpeg',
        '-y',  # Overwrite output file if it exists
        '-f', 'rawvideo',
        '-vcodec', 'rawvideo',
        '-pix_fmt', 'bgr24',
        '-s', f'{screen_width}x{screen_height}',  # Size of one frame
        '-r', str(fps),  # Input frames per second
        '-i', '-',  # Input from pipe
        '-an',  # No audio
        '-vcodec', 'libx264',
        '-pix_fmt', 'yuv420p',
        '-crf', '18',  # Higher quality
        '-preset', 'medium',  # Encoding speed
        'screen_recording.mp4'
    ]

    # Start the ffmpeg process
    ffmpeg_process = subprocess.Popen(ffmpeg_cmd, stdin=subprocess.PIPE)

    frame_count = 0
    start_time = time.time()

    while True:
        # Capture the screen
        img = ImageGrab.grab()
        img_np = np.array(img)

        # Convert and resize the frame
        frame = cv2.cvtColor(img_np, cv2.COLOR_RGB2BGR)
        resized_frame = cv2.resize(frame, (screen_width, screen_height))

        # Write the frame to ffmpeg
        ffmpeg_process.stdin.write(resized_frame.tobytes())

        # Display the frame
        cv2.imshow('Screen Recording', resized_frame)

        # Stop recording when 'q' is pressed
        if cv2.waitKey(1) & 0xFF == ord('q'):
            break

    # Close the ffmpeg process
    ffmpeg_process.stdin.close()
    ffmpeg_process.wait()

    # Release everything when job is finished
    cv2.destroyAllWindows()

if __name__ == "__main__":
    record_screen()


如您所见,它应该是每秒 30 帧,但问题是当我之后打开文件时,它的速度全部加快了。我认为这与帧捕获率有关,而不是与编码率有关。不过我不太确定。如果我随后尝试降低视频速度以使其实时播放,则视频会非常不稳定。我设置的 fps 越高,视频播放的速度就越快,这意味着我必须放慢速度,但视频仍然断断续续。我非常确定它以非常慢的速率捕获帧,然后将它们放入视频中并以 30 fps 的速度播放。有人能解决这个问题吗?任何能在 mac os 上运行屏幕录像机的东西我都会接受。

python ffmpeg screen-recording ffmpeg-python
1个回答
0
投票

考虑使用屏幕捕获 FFmpeg 设备,而不是使用自定义 Python 循环。

在 cli 中,运行

ffmpeg -devices

它会为您提供系统上可用的设备列表,您应该能够找到可以捕获屏幕的设备。例如,在我的 Windows PC 上,我得到

Devices:
 D. = Demuxing supported
 .E = Muxing supported
 --
 D  dshow           DirectShow capture
 D  gdigrab         GDI API Windows frame grabber
 D  lavfi           Libavfilter virtual input device
  E sdl,sdl2        SDL2 output device
 D  vfwcap          VfW video capture

可用的功能因操作系统而异,仅供参考。然后,您可以在 [

ffmpeg.org](https://ffmpeg.org/ffmpeg-devices.html) and use the one you picked as the input device for your 
subprocess` 调用中阅读您的选项。

© www.soinside.com 2019 - 2024. All rights reserved.