复调录屏软件
版本号:0.1.1 Alpha
发行时间:2021年02月11日
发布方:NIRE工作室
开发者:Nire_Yeyu
一、软件描述
- 目标群体:软件开发工程师、测试工程师、工程实施人员、软件购置方
- 软件功能:依照设定自动覆盖过期录屏文件
- 使用场景:相关人群在使用或测试软件过程中,可能发现软件异常,但不易描述或记录具体问题现象和自己的操作过程。从而导致研发人员在Bug修复过程中,需要耗费大量时间与精力在问题的复现上。通过复调录屏软件即第三方软件(以下称:本软件),用户可以24小时不间断录屏,一旦超过预设时间,将自动覆盖过期视频,从而保证占用较小磁盘空间。以此减少研发、测试、工程等互相推卸责任的现象,降低软件维护成本,提高工作效率。
- 关键字: 录屏、覆盖过期文件、工作效率
二、程序流程
2.1 参数设置
- 本软件有两个文件:配置文件 与 代码文件
- 单个文件录制时间、保留文件个数由用户在配置文件中自行设置,而视频的FPS由本软件自动设置
2.2 录制的视频播放速度过快问题
- 不少尝试用Python录屏的开发者都会遇到这个问题,假设录制时长为10秒,录制结束后,用播放器不到5秒就放完了,而且播放速度明显过快。
- 这种播放过快或过慢的现象,是由于FPS设置不恰当造成的。
- 本软件会在初始化过程中自动设置适合当前机器的FPS,并在录制一段时间后进行自动校正,从而保证录屏效果。
2.3 结束条件
- 软件在运行时,会开启键盘监听事件,一旦检测到用户按下ESC,软件会停止运行。建议用户用ESC结束程序,不要直接点击右上角的×关闭,否则录制的视屏没有进行释放操作,会出现异常现象。
三、配置文件
config.ini
[screen]
fps = 7.0
bk = 3
time = 10
四、源文件
VideoCut.py
"""
复调录屏软件通过Python3.7进行开发
使用复调录屏软件,您可以轻松地在各种平台上录制音频。
并且通过配置文件,设置保留视频的时长以及保留的视频个数
从而达到持续录屏,但节省空间,保留重要信息的目的
复调录屏软件的设计灵感来自:
日常测试软件过程中,需要记录操作过程及崩溃现象
如果长时间开启市面上现有的录屏软件会导致视频文件过大
并且在长视频中不易提取有效信息
关键字:
持续录屏、节省空间
"""
__author__ = "Nire_Yeyu"
__mail__ = "Nire_Yeyu@163.com"
__version__ = "0.1.1 Alpha"
__date__ = "2021.02.10"
import os
import time
import threading
import configparser as cp
from datetime import datetime
try:
import cv2
import numpy as np
from PIL import ImageGrab
from pynput import keyboard
except ImportError:
print("初始化失败:缺少依赖库")
raise
class FileMgt(object):
"""
文件管理类:
通过此类实现对配置文件的读写,以及相关文件、文件夹的管控
"""
def __init__(self):
self.current = os.getcwd()
self.screen_record_path = os.path.join(self.current, "video")
self.config_path = ".\\config.ini"
self.video_path = ""
self.fps = 7
self.n_screen_record = 3
self.video_time = 300
self.create_folder()
def create_folder(self):
"""创建文件夹"""
try:
if not os.path.exists(self.screen_record_path):
os.mkdir(self.screen_record_path)
except:
print("错误:文件夹创建异常")
return False
def make_file_path(self):
"""依据当前时间获取欲录制视频路径"""
now = str(datetime.now())[:19].replace(':', '_').replace('-', '_').replace(' ', '_')
video_name = "{}.avi".format(now)
self.video_path = os.path.join(self.screen_record_path, video_name)
return self.video_path
def control_screen_record_path(self):
"""删除过期文件"""
try:
while True:
dir_list = os.listdir(self.screen_record_path)
if len(dir_list) >= self.n_screen_record:
dir_list = sorted(dir_list,
key=lambda x: os.path.getmtime(os.path.join(self.screen_record_path, x)))
f_path = os.path.join(self.screen_record_path, dir_list[0])
os.remove(f_path)
print("删除:", f_path)
else:
break
except FileNotFoundError:
print("错误:系统找不到指定的视频文件")
def read_config(self):
"""读取配置文件"""
try:
inifile = cp.ConfigParser()
inifile.read(self.config_path, "UTF-8")
self.fps = int(float(inifile.get("screen", "fps")))
self.n_screen_record = int(inifile.get("screen", "bk"))
self.video_time = int(inifile.get("screen", "time"))
if self.fps <= 0:
print("配置文件异常:fps必须大于0")
return False
if self.n_screen_record < 3:
print("配置文件异常:保留视频个数不得小于3个")
return False
if self.video_time < 10 or self.video_time > 60 * 60:
print("配置文件异常:单个视频时长应在10秒至1小时之间")
return False
return True
except FileNotFoundError:
print("读取配置文件错误:未找到配置文件")
return False
def set_config(self, fps, record, video_time):
"""设置配置文件信息"""
self.fps = fps
self.n_screen_record = record
self.video_time = video_time
def write_config(self):
"""写配置文件"""
try:
inifile = cp.ConfigParser()
inifile.read(self.config_path, "UTF-8")
inifile["screen"]["fps"] = str(self.fps)
inifile["screen"]["bk"] = str(self.n_screen_record)
inifile["screen"]["time"] = str(self.video_time)
with open(self.config_path, 'w') as configfile:
inifile.write(configfile)
return True
except FileNotFoundError:
print("写配置文件错误:未找到配置文件")
return False
class VideoMgt(object):
"""
录屏管理类:
通过该类实现录屏功能管控
"""
def __init__(self):
self.flag = False
self.end = False
self.fileMgt = FileMgt()
def set_flag(self):
"""设置录屏标志位为结束录屏状态"""
self.flag = True
def test(self):
"""测试当前计算机性能,实现参数自动配置"""
print("初始化中,请稍候...")
if self.fileMgt.read_config() is False:
print("读取配置文件错误")
return False
test_file_name = "test.avi"
timer = threading.Timer(5,
self.set_flag)
timer.start()
screen = ImageGrab.grab()
video = cv2.VideoWriter(test_file_name,
cv2.VideoWriter_fourcc(*"XVID"),
7,
screen.size
)
count = 0
time_start = time.time()
while True:
cv2.waitKey(50)
im = ImageGrab.grab()
imm = cv2.cvtColor(np.array(im), cv2.COLOR_RGB2BGR)
video.write(imm)
count = count + 1
"""已录制5秒,测试结束"""
if self.flag:
break
time_end = time.time()
video.release()
self.fileMgt.fps = count // (time_end - time_start)
self.fileMgt.write_config()
os.remove(os.path.join(
self.fileMgt.current, test_file_name))
self.flag = False
print("初始化完成")
print("帧率:", self.fileMgt.fps)
print("时长:", self.fileMgt.video_time)
print("保留视频个数:", self.fileMgt.n_screen_record)
return True
def make_video(self):
"""录屏"""
self.fileMgt.control_screen_record_path()
if self.fileMgt.read_config() is False:
return False
timer = threading.Timer(self.fileMgt.video_time,
self.set_flag)
timer.start()
screen = ImageGrab.grab()
video = cv2.VideoWriter(self.fileMgt.make_file_path(),
cv2.VideoWriter_fourcc(*"XVID"),
self.fileMgt.fps,
screen.size
)
print("录制:", self.fileMgt.video_path)
time_start = time.time()
count = 0
while True:
cv2.waitKey(50)
im = ImageGrab.grab()
imm = cv2.cvtColor(np.array(im), cv2.COLOR_RGB2BGR)
video.write(imm)
count = count + 1
"""录制结束"""
if self.flag:
break
video.release()
self.flag = False
time_end = time.time()
self.fileMgt.fps = count // (time_end - time_start)
if self.fileMgt.write_config() is False:
return False
print("录制成功")
return True
def on_press(self, key):
"""按键事件"""
if key == keyboard.Key.esc:
self.flag = True
self.end = True
def run(self):
"""程序运行"""
if self.test() is False:
return False
while(True):
if self.make_video() is False:
return False
if self.end:
print("录制结束")
return True
if __name__ == "__main__":
print("*" * 27, "复调录屏软件", "*" * 27)
print("版权方:NIRE工作室")
print("按ESC结束录屏")
print("版本号:", __version__)
VedioMgt = VideoMgt()
th = threading.Thread(target=VedioMgt.run)
th.start()
with keyboard.Listener(on_press=VedioMgt.on_press) as listener:
listener.join()
五、编译
- 需要使用本软件的开发者只需将Config.ini与VideoCut.py这连个文件保存至本地便可以运行。
- 本软件已经过长时间的使用,可以确保以上代码可以编译通过。
- 如果在编译过程中发现有大量错误,请检查本地是否已安装需要用到的第三方库。
六、生成可执行文件
- 如果有些开发者需要生成可执行文件,可以点击查看生成方法。
6.1 Pynput ImportError
- 如果在打包完成后出现上述问题,是因为当前使用的pynput版本过高,当前最新版本为1.7.2,卸载后安装1.6.8,问题可解决。
6.2 PermissionError: [Errno 13] Permission denied:“XXX.dll”
- 网络上的解释是这个dll正在被使用或找不到这个库,其实根本不是这样。
- 解决方法:把360关掉(对,你刚刚被360制裁了)
七、结语
- 致每一位打工者:
- 中国的程序员每天没日没夜地工作着,创造了大量现象级的软件,却领着远低于发达国家程序员的薪资,如果大家甘于现状,我们创造的价值将永远被资本家占据着,还要每天听着这些人歌颂996这样的制度。
- 如果跳出来创业,又会面临大公司的围剿。
- 在这样的情况下,只有大家更加踊跃地分享自己的劳动成果,才能给一个个新兴的小团队带来便利,让他们有机会与现有的大公司较量,才能促进中国的IT行业向着更健康的方向发展。
- 愿奉献大于索取,愿明日优于过往。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)