1

I edited my question because now when i ran my code outside Pycharm (IN Powershell) the keyboard interrupt works fine but now i am struggling to terminate the code on Escape key press.

from PIL import ImageGrab
import numpy as np
import cv2
import ctypes
user32 = ctypes.windll.user32
screensize = user32.GetSystemMetrics(0), user32.GetSystemMetrics(1)

def record_screen():

    fourcc = cv2.VideoWriter_fourcc(*'XVID')
    out = cv2.VideoWriter('ResultFile.avi', fourcc, 25.0, screensize)

    while True:
        try:
            img = ImageGrab.grab()
            img_np = np.array(img)
            frame = cv2.cvtColor(img_np, cv2.COLOR_BGR2RGB)
            out.write(frame)
            print('recording....')
        except KeyboardInterrupt:
            break

    out.release()
    cv2.destroyAllWindows()


record_screen()
Carl
  • 365
  • 2
  • 5
  • 17

2 Answers2

0

Unfortunately it's pretty difficult to listen for keypresses unless you expect one for every iteration of your loop, which for what you're doing is impractical. I think Joel has it right in the comments, you should be using

Ctrl+C

and catching the KeyboardInterrupt like this

from PIL import ImageGrab
import numpy as np
import cv2
import ctypes
user32 = ctypes.windll.user32
screensize = user32.GetSystemMetrics(0), user32.GetSystemMetrics(1)

def record_screen():

    fourcc = cv2.VideoWriter_fourcc(*'XVID')
    out = cv2.VideoWriter('ResultFile.avi', fourcc, 25.0, screensize)

    while True:
        try:
            img = ImageGrab.grab()
            img_np = np.array(img)
            frame = cv2.cvtColor(img_np, cv2.COLOR_BGR2RGB)
            out.write(frame)
            print('recording....')
        except KeyboardInterrupt:
            break

    out.release()
    cv2.destroyAllWindows()


record_screen()

This way, the KeyboardInterrupt won't terminate the program, it'll just end the while loop, allowing you to release your writer and cleanup the rest of the cv2 resources.

Because you're using PyCharm as your IDE, Ctrl+C might not work for you - try Ctrl+F2 instead.

wpercy
  • 9,636
  • 4
  • 33
  • 45
  • i tried using the above solution but the loop didn't terminate after i pressed ctrl+c – Carl Jul 23 '18 at 18:53
  • 1
    I've updated my answer for you because you use PyCharm, use ctrl+f2 – wpercy Jul 23 '18 at 18:53
  • i just used ctrl+f2 key but the loop still didn't terminate – Carl Jul 23 '18 at 18:54
  • Can't figure out the reason for this – Carl Jul 23 '18 at 18:58
  • and here is another problem if i use cv2.imshow('Screen', frame) just before out.write(frame) and then run my program i am able to stop the recording by pressing the escape key – Carl Jul 23 '18 at 19:00
  • but the downside of it is that every time the program starts the screen is bombarded with frames – Carl Jul 23 '18 at 19:01
  • @Carl what about this - don't put the `cv2.imshow('Screen', frame)` in the while loop, put it just before - then does it work? If you put it in the loop, it'll create a frame for each iteration, but if you put it before, it should only create one – wpercy Jul 24 '18 at 16:26
0

You should make a variable called running! Set 'running = True' before the while loop. And instead of the while loop being 'while True:', make it 'while running = True:'. Finally, in the while loop, if you hit ESC, set 'running = False'

Here is an example with pygame:

import pygame
pygame.init()

def record():

    # init
    running = True

    while running == True:

        # record

        events = pygame.event.get()

        for event in events:

            if event.type == pygame.K_ESCAPE:

                running = False

    quit()

record()
Terabyte
  • 69
  • 10