0

Using the following code:

import cv2
import numpy as np
from win32api import GetSystemMetrics # screen size
import elapsed
import datetime

screen_width = GetSystemMetrics (0)
screen_height = GetSystemMetrics (1)
resolution = (screen_width, screen_height)
codec = cv2.VideoWriter_fourcc(*'x264')
filename = ".\\screen_video.mp4"
fps = 30.0
out = cv2.VideoWriter(filename, codec, fps, resolution)

record_timer = datetime.datetime.now() 
  
while True:

    img = pyautogui.screenshot()
    frame = np.array(img)
    frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
    out.write(frame)

    if elapsed.get (record_timer ).seconds >= 30: break
  
out.release()

I am recording a 30 sec video of my screen.

Problem is: the recorded video speed is incorrect. It is just too fast. To be precise, instead of a 30 sec normal video, the result is a 6 seconds video. It is not lagging, I mean all content recorded correctly, just in a "fast forward" way.

I check these solutions, but did not solved my problem: The output of cv2.VideoWriter is incorrect. It's faster

Can you help me please what can be the problem here? Many thanks in advance for any concrete help!

Daniel Widdis
  • 8,424
  • 13
  • 41
  • 63
D.Moore
  • 45
  • 1
  • 6
  • 3
    Make sure that the fps setting of the VideoWriter and the fps of the data match well. E.g. if you set to 30 fps but the distance between frames you give to the writer is 100 ms then the video will be played too fast (you would have to set 10 fps instead). – Micka Apr 21 '22 at 09:13
  • 1
    you aren't pacing your screenshotting at all. you can't know at what frame rate you're getting the data. -- are you saying if you specified *6 fps* to VideoWriter, the video would be playing at roughly realtime speed? that would mean you're only getting screenshots at 6 fps... without throttling/sleeping at all. – Christoph Rackwitz Apr 21 '22 at 10:01
  • please use the code `COLOR_RGB2BGR` because pyautogui makes RGB data and OpenCV wants BGR data. the operation is the same (flip R and B channels) but the identifier conveys the proper orders for input and output – Christoph Rackwitz Apr 21 '22 at 10:03
  • @Micka Thank you for your reply. Do I understand you correctly, that I should use "cv2.waitKey(300)" right after "out.write(frame)" ? Because I tried that, but it did not solved the problem, recorded video is till in superspeed. In case I misunderstood you, could you be so kind and help me with a bit more detailed/concrete based on my code above? Thank you for your time and help! – D.Moore Apr 21 '22 at 10:21
  • @Christoph Rackwitz Thank you for your reply. Exactly, when I set fps to 6 as you suggested, the recorded video, indeed playing roughly at real-time speed! Could you help me please to understand with a concrete example, what should I do? As mentioned in my comment above, I tried to add sleeping, but it did not solved the problem, and I lost a bit in understanding the right steps. I also corrected the "COLOR_RGB2BGR" as you suggested. Man thanks for your time and help! – D.Moore Apr 21 '22 at 10:35
  • No, instead of setting fps = 30.0, set fps variable to the actually achieved fps of your screencapturing, encoding and writing, or add dummy frames if your achieved fps is lower than the set fps. – Micka Apr 21 '22 at 10:41
  • `pyautogui.screenshot()` is not suitable for *video* capture. it's slow. if you need to capture faster than 6 fps, you need a different API (in pyautogui) or different library (not pyautogui). alternative: https://pypi.org/project/mss/ and d3dshot used to work but it's been abandoned – Christoph Rackwitz Apr 21 '22 at 10:42
  • 1
    Specific: If you recorded 30 seconds but your video is 6 seconds, your set fps is factor 5 too high. So set fps = 6.0 and you should see a better video in the end. – Micka Apr 21 '22 at 10:43
  • careful with the math :) if numframes = 30 seconds * input_fps, and numframes / (30 fps)= 6 seconds, then input_fps = 6 seconds * 30 fps / 30 secs = 6 fps – Christoph Rackwitz Apr 21 '22 at 10:45
  • BIG thanks for all your helps, I had added the votes accordingly! – D.Moore Apr 22 '22 at 10:42

0 Answers0