Recently have been using screen recording software to record the desktop, in the process of using a whim, using python can do screen recording tools, but also exercise their hands. Next ready to write a series of articles using python how to do screen recording tool:
Record Screen Production Video
Record Audio
Composite video, audio
Making visualization windows based on pyqt5
Roughly the above four parts, hopefully I will be able to perfect it soon, next start using python to create the screen recording part.
application platform (computing)
- windows 10
- python 3.7
Screen recording section
Screen recording can be simply understood as a snapshot of the screen to play in the form of moving pictures, here I choose to use PIL under the ImageGrab to intercept the screen, first of all, the
pip install Pillow
After that you need to combine the number of intercepted snapshots into a video, using the cv2 module
pip install opencv-python
ImageGrab class can not be stored directly as a video, using numpy module for arraying, and then converted to cv2 color channel by cv2.COLOR_BGR2RGB.
pip install numpy
Screen recording main code:
import numpy as np from PIL import ImageGrab import cv2 im = () width, high = # Get the width and height of the screen fourcc = cv2.VideoWriter_fourcc(*'I420') # Set the video encoding format fps = 15 # Setting the frame rate video = ('', fourcc, fps, (width, high)) while True: # Start recording im = () im_cv = ((im), cv2.COLOR_BGR2RGB) # Image Write (im_cv) if xx: # Interrupt the loop when a certain condition is met break () # Releasing the cache,Persistent Video
A test run can save a screen snapshot as a video, but the operation is not elegant or conducive to subsequent operations.
Encapsulated into a class that inherits from the thread parent to facilitate the use of the keyboard to control the end of the video recording.
from threading import Thread class ScreenshotVideo(Thread): def __init__(self): """Initialization parameters""" super().__init__()
Detailed code will be given at the end of the article.
Calculating the optimal fps for a video and using numpy to calculate the intermediate frame array
In practice, video recording will have different frame rates in different computers, resulting in either fast or slow video playback, and you need to calculate the corresponding optimal fps values according to different computers.
def video_best_fps(self, path): """Getting the optimal frame rate for a computer-recorded video.""" video = (path) # Read the video fps = (cv2.CAP_PROP_FPS) # Get the frame rate of the current video count = (cv2.CAP_PROP_FRAME_COUNT) # Get the number of frames in the video, i.e. how many frames are in the video self.best_fps = int(fps * ((int(count) / fps) / self.spend_time)) # Calculate playback time vs. recording time to get the optimal frame rate ()
Then adjust the frame rate parameter to record the video will weaken the video playback too fast or too slow. You can also add frames to the video to extend the playback time, here I use a very simple method to increase the video frame, just for reference.
from numba import jit # Use numpy to compute two images that are two frames adjacent and closer to the later frame # Call the jit method to speed up array calculations @jit(nopython=True) def average_n(x, y): """Numpy computes convergence values.""" return ((x + y + y) // 3).astype()
This method is only for the set fps is higher than the optimal fps, after the processing of the video view, the video is still more rapid, but the details of the frame increased, so the playback time will be longer than before processing, slightly residual shadow.
Listening to keyboard keys with pynput
In video recording, it is not known when the video ends, so the recording code is wrapped in a while loop, but it is not possible to let the code run endlessly, and here we use the Listen to Keyboard module to interrupt the running of the recording code.
from pynput import keyboard # pip install pynput def hotkey(self): """Hot Key Listening""" with (on_press=self.on_press) as listener: () def on_press(self, key): try: if == 't': # End of screen recording, save video = True elif == 'k': # Recording screen aborts, deletes files = True = True except Exception as e: print(e)
Press "T" key to end the recording and save the video. The "K" key stops recording and deletes the cache file.
How to save MP4 format video
The video encoding format should be ('a', 'v', 'c', '1') with a file extension of '.mp4', before recording go to the/cisco/openh264/releasesDownload the dll.bz2 file for the corresponding platform under and unzip the zip package in the project folder. Run the code again and a line of coding instructions will appear for success:
OpenH264 Video Codec provided by Cisco Systems, Inc.
source code (computing)
The source code implemented in this article is as follows:
import time from PIL import ImageGrab import cv2 from pathlib import Path import numpy as np from numba import jit from pynput import keyboard from threading import Thread @jit(nopython=True) def average_n(x, y): """Numpy computes convergence values.""" return ((x + y + y) // 3).astype() class ScreenshotVideo(Thread): def __init__(self, width, high, path='', fps=15): """Initialization parameters""" super().__init__() self.save_file = path self.best_fps = fps = fps = width = high self.spend_time = 1 = False = False = None def __call__(self, path): """Overloading video paths for easy secondary calls to classes""" self.save_file = Path(path) = self.init_videowriter(self.save_file) @staticmethod def screenshot(): """Static method, screenshot, and convert to array""" return (()) @staticmethod def get_fourcc(name): """Video Coding Dictionary""" fourcc_maps = {'.avi': 'I420', '.m4v': 'mp4v', '.mp4': 'avc1', '.ogv': 'THEO', '.flv': 'FLV1', } return fourcc_maps.get(name) def init_videowriter(self, path): """Get video encoding and create new video file""" if not path: raise Exception('Video path not set,Please set\nvideo = ScreenshotVideo(fps,width,high)\nvideo = video(video_path)') path = Path(path) if isinstance(path, str) else path fourcc = cv2.VideoWriter_fourcc(*self.get_fourcc()) return (path.as_posix(), fourcc, , (, )) def video_record_doing(self, img): """Converting BGR arrays to RGB arrays""" im_cv = (img, cv2.COLOR_BGR2RGB) (im_cv) def video_record_end(self): """End of recording, determine if the file is saved based on the conditions""" () () if self.save_file and : Path(self.save_file).unlink() def video_best_fps(self, path): """Getting the optimal frame rate for a computer-recorded video.""" video = (path) fps = (cv2.CAP_PROP_FPS) count = (cv2.CAP_PROP_FRAME_COUNT) self.best_fps = int(fps * ((int(count) / fps) / self.spend_time)) () def pre_video_record(self): """Pre-recording for optimal fps.""" = self.init_videowriter('test.mp4') start_time = () for _ in range(10): im = () self.video_record_doing(im) self.spend_time = round(() - start_time, 4) self.video_record_end() (2) self.video_best_fps('test.mp4') Path('test.mp4').unlink() def insert_frame_array(self, frame_list): """Numpy Enhanced Screenshot Information.""" fps_n = round( / self.best_fps) if fps_n <= 0: return frame_list times = int(np.log2(fps_n)) # Multiplier for _ in range(times): frame_list2 = map(average_n, [frame_list[0]] + frame_list[:-1], frame_list) frame_list = [[x, y] for x, y in zip(frame_list2, frame_list)] frame_list = [j for i in frame_list for j in i] return frame_list def frame2video_run(self): """Converting continuous type screenshots to video using opencv""" = self.init_videowriter(self.save_file) start_time = () frame_list = [] while True: frame_list.append(()) if : break self.spend_time = round(() - start_time, 4) if not : # Video recording is not terminated will process the image frame by frame frame_list = self.insert_frame_array(frame_list) for im in frame_list: self.video_record_doing(im) self.video_record_end() def hotkey(self): """Hot Key Listening""" with (on_press=self.on_press) as listener: () def on_press(self, key): try: if == 't': # End of screen recording, save video = True elif == 'k': # Recording screen aborts, deletes files = True = True except Exception as e: print(e) def run(self): # Run the function # Set up daemon threads Thread(target=, daemon=True).start() # Run the screenshot function self.frame2video_run() screen = () width, high = video = ScreenshotVideo(width, high, fps=60) video.pre_video_record() # Pre-record for optimal fps video('test1.mp4') ()
summarize
In this paper, the current use of opencv and related modules to record the screen and convert it to video to save, learn to encapsulate multiple functions into classes to facilitate the subsequent development of the function. The road to learning is endless, bold steps to go!
The above is based on Python + OpenCV to create screen recording tools in detail, more information about Python OpenCV screen recording please pay attention to my other related articles!