我的编程空间,编程开发者的网络收藏夹
学习永远不晚

基于Python+OpenCV如何制作屏幕录制工具

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

基于Python+OpenCV如何制作屏幕录制工具

这篇文章跟大家分析一下“基于Python+OpenCV如何制作屏幕录制工具”。内容详细易懂,对“基于Python+OpenCV如何制作屏幕录制工具”感兴趣的朋友可以跟着小编的思路慢慢深入来阅读一下,希望阅读后能够对大家有所帮助。下面跟着小编一起深入学习“基于Python+OpenCV如何制作屏幕录制工具”的知识吧。

应用平台

  • windows 10

  • python 3.7

屏幕录制部分

屏幕录制可以简单地理解为将屏幕快照以动图的形式播放,这里我选用PIL下的ImageGrab来截取屏幕画面,首先

pip install Pillow

之后需要将截取到的快照数组合成为视频,使用cv2模块

pip install opencv-python

ImageGrab类不能直接存储为视频,使用numpy模块进行数组化,再通过cv2.COLOR_BGR2RGB转换为cv2色彩通道。

pip install numpy

屏幕录制主要代码:

import numpy as npfrom PIL import ImageGrabimport cv2im = ImageGrab.grab()width, high = im.size  # 获取屏幕的宽和高fourcc = cv2.VideoWriter_fourcc(*'I420')  # 设置视频编码格式fps = 15  # 设置帧率video = cv2.VideoWriter('test.avi', fourcc, fps, (width, high))while True:  # 开始录制    im = ImageGrab.grab()    im_cv = cv2.cvtColor(np.array(im), cv2.COLOR_BGR2RGB)    # 图像写入    video.write(im_cv)    if xx:  # 当某某条件满足中断循环        breakvideo.release()  # 释放缓存,持久化视频

测试运行可以保存屏幕快照为视频,但操作起来不优雅,也不利于后续的操作。

封装成类,继承线程父类,方便使用键盘来控制视频录制的结束。

from threading import Threadclass ScreenshotVideo(Thread):    def __init__(self):     """初始化参数"""        super().__init__()

详细代码将在文末给出。

计算视频最优fps及使用numpy计算中间帧数组

实际操作中视频录制在不同电脑中会出现不一样的帧率,导致视频播放或快或慢,需要根据不同的电脑计算出相应的最优fps值。

def video_best_fps(self, path):    """获取电脑录制视频的最优帧率"""    video = cv2.VideoCapture(path)  # 读取视频    fps = video.get(cv2.CAP_PROP_FPS)  # 获取当前视频的帧率    count = video.get(cv2.CAP_PROP_FRAME_COUNT)  # 获取视频帧数,即该视频有多少幅画面    self.best_fps = int(fps * ((int(count) / fps) / self.spend_time))   # 计算播放时间与录制时间对比得到最优帧率    video.release()

再调整帧率参数进行录制视频就减弱了视频播放太快或者太慢。也可以给视频增加帧数从而延长播放时间,这里我采用一种很简单的方法增加视频帧,仅供参考。

from numba import jit# 使用numpy计算相邻两帧图像且更接近于后一帧的图像# 调用jit方法加速数组计算@jit(nopython=True)def average_n(x, y):    """Numpy计算趋近值"""    return ((x + y + y) // 3).astype(x.dtype)

该方法仅针对于设置的fps比最优fps要高时,处理后的视频观感,视频还是较为急促,但是细节帧增多,所以播放时长会比未处理前的要长,略有残影。

使用pynput监听键盘按键

在视频录制中,并不知道视频何时结束,所以用while循环包裹录制代码,但也不可能让代码无休止的运行下去,在此使用监听键盘模块来中断录制代码的运行。

from pynput import keyboard  # pip install pynputdef hotkey(self):    """热键监听"""    with keyboard.Listener(on_press=self.on_press) as listener:        listener.join()def on_press(self, key):    try:        if key.char == 't':  # 录屏结束,保存视频            self.flag = True        elif key.char == 'k':  # 录屏中止,删除文件            self.flag = True            self.kill = True    except Exception as e:        print(e)

按下键盘“T”键时,结束录制,保存视频。“K”键则是停止录制,删除缓存文件。

如何保存MP4格式视频

视频编码格式应该为('a', 'v', 'c', '1'),文件后缀为'.mp4',在录制前先去https://github.com/cisco/openh364/releases下下载对应平台的dll.bz2文件,将压缩包解压放在项目文件夹下。再运行代码,成功会出现一行编码说明:

OpenH264 Video Codec provided by Cisco Systems, Inc.

源码

本文实现的源码如下:

import timefrom PIL import ImageGrabimport cv2from pathlib import Pathimport numpy as npfrom numba import jitfrom pynput import keyboardfrom threading import Thread@jit(nopython=True)def average_n(x, y):    """Numpy计算趋近值"""    return ((x + y + y) // 3).astype(x.dtype)class ScreenshotVideo(Thread):    def __init__(self, width, high, path='', fps=15):        """初始化参数"""        super().__init__()        self.save_file = path        self.best_fps = fps        self.fps = fps        self.width = width        self.high = high        self.spend_time = 1        self.flag = False        self.kill = False        self.video = None    def __call__(self, path):        """重载视频路径,便于类的二次调用"""        self.save_file = Path(path)        self.video = self.init_videowriter(self.save_file)    @staticmethod    def screenshot():        """静态方法,屏幕截图,并转换为np.array数组"""        return np.array(ImageGrab.grab())    @staticmethod    def get_fourcc(name):        """视频编码字典"""        fourcc_maps = {'.avi': 'I420',                       '.m4v': 'mp4v',                       '.mp4': 'avc1',                       '.ogv': 'THEO',                       '.flv': 'FLV1',                       }        return fourcc_maps.get(name)    def init_videowriter(self, path):        """获取视频编码并新建视频文件"""        if not path:            raise Exception('视频路径未设置,请设置\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(path.suffix))        return cv2.VideoWriter(path.as_posix(), fourcc, self.fps, (self.width, self.high))    def video_record_doing(self, img):        """将BGR数组转换为RGB数组"""        im_cv = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)        self.video.write(im_cv)    def video_record_end(self):        """录制结束,根据条件判断文件是否保存"""        self.video.release()        cv2.destroyAllWindows()        if self.save_file and self.kill:            Path(self.save_file).unlink()    def video_best_fps(self, path):        """获取电脑录制视频的最优帧率"""        video = cv2.VideoCapture(path)        fps = video.get(cv2.CAP_PROP_FPS)        count = video.get(cv2.CAP_PROP_FRAME_COUNT)        self.best_fps = int(fps * ((int(count) / fps) / self.spend_time))        video.release()    def pre_video_record(self):        """预录制,以获取最佳fps值"""        self.video = self.init_videowriter('test.mp4')        start_time = time.time()        for _ in range(10):            im = self.screenshot()            self.video_record_doing(im)        self.spend_time = round(time.time() - start_time, 4)        self.video_record_end()        time.sleep(2)        self.video_best_fps('test.mp4')        Path('test.mp4').unlink()    def insert_frame_array(self, frame_list):        """Numpy增强截图信息"""        fps_n = round(self.fps / self.best_fps)        if fps_n <= 0:            return frame_list        times = int(np.log2(fps_n))  # 倍率        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):        """使用opencv将连续型截图转换为视频"""        self.video = self.init_videowriter(self.save_file)        start_time = time.time()        frame_list = []        while True:            frame_list.append(self.screenshot())            if self.flag:                break        self.spend_time = round(time.time() - start_time, 4)        if not self.kill:  # 视频录制不被终止将逐帧处理图像            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):        """热键监听"""        with keyboard.Listener(on_press=self.on_press) as listener:            listener.join()    def on_press(self, key):        try:            if key.char == 't':  # 录屏结束,保存视频                self.flag = True            elif key.char == 'k':  # 录屏中止,删除文件                self.flag = True                self.kill = True        except Exception as e:            print(e)    def run(self):        # 运行函数        # 设置守护线程        Thread(target=self.hotkey, daemon=True).start()        # 运行截图函数        self.frame2video_run()screen = ImageGrab.grab()width, high = screen.sizevideo = ScreenshotVideo(width, high, fps=60)video.pre_video_record()  # 预录制获取最优fpsvideo('test1.mp4')video.run()

关于基于Python+OpenCV如何制作屏幕录制工具就分享到这里啦,希望上述内容能够让大家有所提升。如果想要学习更多知识,请大家多多留意小编的更新。谢谢大家关注一下编程网网站!

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

基于Python+OpenCV如何制作屏幕录制工具

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

基于Python+OpenCV如何制作屏幕录制工具

这篇文章跟大家分析一下“基于Python+OpenCV如何制作屏幕录制工具”。内容详细易懂,对“基于Python+OpenCV如何制作屏幕录制工具”感兴趣的朋友可以跟着小编的思路慢慢深入来阅读一下,希望阅读后能够对大家有所帮助。下面跟着小编
2023-06-26

[python小工具]实现屏幕录制

用python实现屏幕录制PIL 即pollow 的安装命令如下:pip install pillow其中cv2的安装是下面这条命令pip install opencv-python#python + opencv 实现屏幕录制from P
2023-01-31

win10屏幕录制如何操作

win10怎么录屏是很多小伙伴心中的一个疑问,因为随着录屏的需求增多录屏软件也随之增加,但是不同录屏软件在录制的质量上存在着不小的区别,接下来就和大家聊聊win10电脑录屏所涉及到的方法吧。win10自带:随着系统的升级现在的win10系统
2023-07-10

基于Python制作个抢红包的工具

快过年了,刚刚收到了两个消息,一个好消息,一个坏消息。好消息就是微信群里有人要发红包,坏消息是不一定能都抢到。所以本文就来用Python做一个抢红包工具,需要的可以参考一下
2023-01-10

python基于tkinter制作下班倒计时工具

你有过摸鱼时间吗在互联网圈子里,常常说996上班制,但是也不乏965的,更甚有007的,而007则就有点ICU的感觉了,所以,大家都会忙里偷闲,偶尔摸摸鱼,摸鱼的方式多种多样的,你有过上班摸鱼吗?你的摸鱼时间都干了些什么呢?如果你早早的完成
2022-06-02

如何基于PyQt5制作数据处理小工具

小编给大家分享一下如何基于PyQt5制作数据处理小工具,希望大家阅读完这篇文章之后都有所收获,下面让我们一起去探讨吧!需求分析:现在有一大堆的Excel数据文件,需要根据每个Excel数据文件里面的Sheet批量将数据文件合并成为一个汇总后
2023-06-29

Linux自带的录屏工具如何录制gif图

这篇文章将为大家详细讲解有关Linux自带的录屏工具如何录制gif图,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。方法如下1、打开深度Linux桌面。2、找到启动器,打开。3、找到录屏,打开。4、拖动一个
2023-06-10

如何在Linux的命令行中操作屏幕录制

本篇内容主要讲解“如何在Linux的命令行中操作屏幕录制”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“如何在Linux的命令行中操作屏幕录制”吧!script和scriptreplay在绝大多数
2023-06-13

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录