python录屏

import time,threading
from datetime import datetime
from PIL import ImageGrab
#from cv2 import *
import cv2
import numpy as np
from pynput import keyboard
def video_record():   # 录入视频
  global name
  fps=15
  name = datetime.now().strftime('%Y-%m-%d %H-%M-%S') # 当前的时间(当文件名)
  screen = ImageGrab.grab() # 获取当前屏幕
  width, high = screen.size # 获取当前屏幕的大小
  fourcc = cv2.VideoWriter_fourcc('X', 'V', 'I', 'D') # MPEG-4编码,文件后缀可为.avi .asf .mov等
  video = cv2.VideoWriter('%s.avi' % name, fourcc, fps, (width, high)) # (文件名,编码器,帧率,视频宽高)
  #print('3秒后开始录制----')  # 可选
  #time.sleep(3)
  print('开始录制!')
  global start_time
  start_time = time.time()
  while True:
    if flag:
      print("录制结束!")
      global final_time
      final_time = time.time()
      video.release() #释放
      break
    im = ImageGrab.grab()  # 屏幕抓图,图片为RGB模式
    frame = cv2.cvtColor(np.array(im), cv2.COLOR_RGB2BGR) # 转为opencv的BGR模式
    video.write(frame)  #写入vedio定义的文件
    # time.sleep(5) # 等待5秒再次循环,控制帧数
    #等0.1毫秒---十分之一秒--10帧/秒
def on_press(key):   # 监听按键-home
  global flag
  if key == keyboard.Key.home:
    flag = True # 改变
    return False # 返回False,键盘监听结束!
def video_info():   # 视频信息
  video = cv2.VideoCapture('%s.avi' % name)  # 记得文件名加格式不要错!
  fps = video.get(cv2.CAP_PROP_FPS)
  Count = video.get(cv2.CAP_PROP_FRAME_COUNT)
  size = (int(video.get(cv2.CAP_PROP_FRAME_WIDTH)), int(video.get(cv2.CAP_PROP_FRAME_HEIGHT)))
  print('帧率=%.1f'%fps)
  print('帧数=%.1f'%Count)
  print('分辨率',size)
  print('视频时间=%.3f秒'%(int(Count)/fps))
  print('录制时间=%.3f秒'%(final_time-start_time))
  print('推荐帧率=%.2f'%(fps*((int(Count)/fps)/(final_time-start_time))))
if __name__ == '__main__':
  flag = False
  th = threading.Thread(target=video_record)
  th.start()
  with keyboard.Listener(on_press=on_press) as listener:
    listener.join()
  time.sleep(1)  # 等待视频释放过后
  video_info()

代码解释:

观察代码可以发现实现录屏的方式就是不断循环获取屏幕然后写入,可以想到每循环一次就是一帧,而循环一次要多长时间就取决于运行的速度了。所以我们只要让一秒中写入的帧数(也就是1秒中循环的次数)和video中的参数帧率相等,就能获得差不多正常的速度

因此我在代码中加入了视频信息,算出了视频播放的时间和录制时间,再推算出来正常速度的帧率?推荐帧率。只要先运行试一下,看一下推荐帧率是多少,再把代码中的参数改过来就行了(要取整数哦)

开始录制! 录制结束! 帧率=15.0 帧数=446.0 分辨率 (1600, 900) 视频时间=29.733秒 录制时间=22.233秒 推荐帧率=20.06

要按home键来正常结束程序,才会有video_info出现

我在循环中加入了‘等待5秒’,这样就差不多每5秒获取1帧,推荐帧率显示0.20,当然,我不能也不会按这个速度播放,给它来个25倍(帧率为0.20*25=5,这样视频出来就又小又短了?)

多提一下,因为两个线程并不会同时结束,只是通过flag这个变量改变来使得另一个结束,所以按home键flag改变的时候,另一个线程video_record还处于运行循环中,因此我们要等它经过这次循环,进入下一次条件判断,视频才得以从内存释放…呃嗯,就是我要在代码倒数第2行那里等待个5+1=6秒(这样比较保险),否则的话,那个帧数会显示为0,甚至会出现运行错误(不能除0)

总结

到此这篇关于python实现录屏功能就介绍到这了,更多相关python 实现录屏内容请搜索ZaLou.Cn