经验分享python使用opencv录屏偏快或偏慢的解决方案-找到合适的帧率

python使用opencv录屏偏快或偏慢的解决方案

  • 说明
  • 调试录屏得到最接近的帧率
  • 总结

上一篇文章讲了如何用python录制视频,这次讲下视频录制成功后的一些问题,录制下来的视频速度对不上的问题

说明

FPS是图像领域中的定义,是指画面每秒传输帧数,通俗来讲就是指动画或视频的画面zhi数。FPS是测量用于保存、显示动态视频的信息数量。FPS数字越大即每秒钟帧数愈多,所显示的动作就会愈流畅。

但是由于不同计算机的处理能力不同,所以生成视频的速度和实际可能有所偏差,这个时候就要调试找到这台计算机最接近合适的帧率了。

调试录屏得到最接近的帧率

话不多说直接上代码

screen_recode.py

"""
python 屏幕录制
by:一岚大霞

"""

from PIL import ImageGrab
import numpy as np
import cv2
from cv2 import VideoCapture, CAP_PROP_FPS, CAP_PROP_FRAME_COUNT, CAP_PROP_FRAME_WIDTH, CAP_PROP_FRAME_HEIGHT
import datetime
import time
import os
from screen_recode.parse import ReadConf
import threading

conf = ReadConf()


class ScreenVideoControl(threading.Thread):
    def __init__(self, save_dir):
        threading.Thread.__init__(self)
        self.fps = int(conf.get_value('conf', 'fps'))  # 帧率为25,可以调节
        self.start_time = time.time()
        self.save_dir = save_dir
        self.screen_file_path = None
        self.get_video_path()
        self.video = cv2.VideoWriter(self.screen_file_path, cv2.VideoWriter_fourcc(*'XVID'), self.fps,
                                     ImageGrab.grab().size)

    def start(self):
        # 设置运行开始标志 FLAG=true则为结束录频
        conf.write_or_update_value('conf', "FLAG", 'False')
        # 最长录制时间
        time_delay = 30.0  # 秒 可设置
        self.video_record(time_delay)

    def video_record(self, time_delay):
        print("screen record is doing........")
        print('---录屏已经开始了--')
        while True:
            im = ImageGrab.grab()
            imm = cv2.cvtColor(np.array(im), cv2.COLOR_RGB2BGR)  # 转为opencv的BGR格式
            self.video.write(imm)
            self.now_time = time.time()
            delay = self.now_time - self.start_time
            if delay >= time_delay:
                print("---超过指定时间,录制结束!---")
                break
            elif self.end_process():
                print("---程序结束,录制结束!---")
                break
        self.video.release()
        cv2.destroyAllWindows()

    # 判断是否结束
    def end_process(self):
        flag = conf.get_value("conf", 'FLAG')
        if flag == 'False' or flag == "false":
            return False
        else:
            return True

    def get_video_path(self):
        # 录屏保存的文件目录路径
        if not os.path.exists(self.save_dir):
            os.makedirs(self.save_dir)
        # 得到录屏保存的文件路径 按照时间创建文件夹
        file_name = datetime.datetime.now().strftime('%Y-%m-%d %H-%M-%S') + '_screen.avi'
        # 文件路径
        self.screen_file_path = os.path.join(self.save_dir, file_name)

    #找到合适的帧率
    def get_fps(self):  # 视频信息
        video = VideoCapture(self.screen_file_path)  # 记得文件名加格式不要错!
        old_fps = video.get(CAP_PROP_FPS)
        Count = video.get(CAP_PROP_FRAME_COUNT)
        size = (int(video.get(CAP_PROP_FRAME_WIDTH)), int(video.get(CAP_PROP_FRAME_HEIGHT)))
        print('视频帧率=%.1f' % old_fps)
        print('视频的帧数=%.1f' % Count)
        print('视频的分辨率', size)
        print('视频时间=%.3f秒' % (int(Count) / old_fps))
        print('视频的录制时间=%.3f秒' % (self.now_time - self.start_time))
        new_fps = old_fps * (int(Count) / old_fps) / (self.now_time - self.start_time)
        print('推荐帧率=%.2f' % (new_fps))
        # 把调整过的帧率四舍五入写入配置文件中,下次录制直接拿取
        conf.write_or_update_value('conf', "fps", str(round(float(new_fps))))


if __name__ == "__main__":
    path = r'C:\Users\xxx\Desktop\video_fx'
    t1 = ScreenVideoControl(path)
    t1.start()
    time.sleep(1)  # 等待视频释放过后
    t1.get_fps()

上面代码中,用于调试出合适帧率的是get_fps方法,比较实际录下来的时间和视频的时间,从而计算出合适的帧率,并且写入配置文件中,用于下一次的录屏使用。

parse

import os
import configparser


class ReadConf(object):

    # 程序化入口类
    def __init__(self, file_name='system.inf', path='./', encode='utf-8'):
        self.conf = configparser.ConfigParser()
        self.file_path = os.path.join(path, file_name)
        self.conf.read(self.file_path, encoding=encode)


    def get_value(self, section,key,):
        # 获取配置文件的信息
        return self.conf.get(section, key)

    def get_conf(self):
        return self.conf

    def write_or_update_value(self, section, key, value):
        self.conf.set(section, key, value)
        with open(self.file_path, 'w',encoding='utf-8') as fw:  # 循环写入
            self.conf.write(fw)

配置文件 system.inf

[conf]
fps = 23
flag = False


总结

该方法就是先执行代码录下一个视频,然后比较实际的录下的时间和视频的时间,比如实际录了60s,但是视频只有40s这就是速度偏快了。这个时候就可以算出合适的帧率了。
新的帧率=原来的视频帧率 * (帧数 / 原来的视频帧率) / 视频实际录制时间
new_fps = old_fps * (int(Count) / old_fps) / screen_time

程序至少运行两遍,以找到合适的帧率
经验分享python使用opencv录屏偏快或偏慢的解决方案-找到合适的帧率_第1张图片
可以看到,调试帧率后,视频时间和录制时间相差无几,视觉上感觉不出啊差别。

遇到相同问题的小伙伴可以自己试下,see,you!

你可能感兴趣的:(python,技术,python,多线程,pycharm,经验分享)