上一篇文章讲了如何用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
程序至少运行两遍,以找到合适的帧率
可以看到,调试帧率后,视频时间和录制时间相差无几,视觉上感觉不出啊差别。
遇到相同问题的小伙伴可以自己试下,see,you!