使用Python實(shí)現(xiàn)屏幕錄制與鍵盤監(jiān)聽功能
一、引言
在Python中,我們可以借助多個(gè)強(qiáng)大的庫(kù)來實(shí)現(xiàn)豐富的功能,比如屏幕錄制和鍵盤監(jiān)聽。今天,我們將通過結(jié)合PIL(Python Imaging Library的分支Pillow)、OpenCV、pynput以及threading等庫(kù),來實(shí)現(xiàn)一個(gè)簡(jiǎn)單的屏幕錄制工具,該工具能夠通過監(jiān)聽鍵盤事件來控制錄制的開始與結(jié)束。
二、所需庫(kù)介紹
- PIL(Pillow):用于屏幕截圖。
- OpenCV:用于視頻文件的創(chuàng)建與寫入。
- pynput:用于監(jiān)聽鍵盤事件。
- threading:用于并行執(zhí)行代碼,實(shí)現(xiàn)屏幕錄制與鍵盤監(jiān)聽的同時(shí)進(jìn)行。
三、代碼詳解
導(dǎo)入所需庫(kù)
import time
import threading
from datetime import datetime
from PIL import ImageGrab
import numpy as np
from cv2.cv2 import cvtColor, VideoWriter_fourcc, VideoWriter, COLOR_RGB2BGR, VideoCapture, \
CAP_PROP_FPS, CAP_PROP_FRAME_COUNT, CAP_PROP_FRAME_WIDTH, CAP_PROP_FRAME_HEIGHT
from pynput import keyboard
定義視頻錄制函數(shù)
def video_record():
# ...(省略了部分代碼)
while True:
if flag:
# ...(省略了部分代碼)
break
im = ImageGrab.grab() # 截圖
imm = cvtColor(np.array(im), COLOR_RGB2BGR) # 轉(zhuǎn)換顏色模式
video.write(imm) # 寫入視頻文件
這個(gè)函數(shù)首先獲取當(dāng)前時(shí)間作為文件名,然后初始化視頻寫入對(duì)象。接著,它會(huì)顯示一個(gè)3秒的倒計(jì)時(shí),之后開始錄制屏幕。在錄制過程中,它會(huì)不斷檢查一個(gè)全局變量
flag,如果flag變?yōu)?code>True,則停止錄制并釋放視頻寫入對(duì)象。
定義鍵盤監(jiān)聽函數(shù)
def on_press(key):
global flag
if key == keyboard.Key.esc:
flag = True
return False
這個(gè)函數(shù)會(huì)監(jiān)聽鍵盤事件,當(dāng)按下
esc鍵時(shí),將全局變量flag設(shè)置為True,并返回False以停止鍵盤監(jiān)聽。
定義視頻信息打印函數(shù)
def video_info():
# ...(省略了部分代碼)
print('幀率=%.1f' % fps)
# ...(省略了部分代碼)
print('推薦幀率=%.2f' % (fps*((int(count)/fps)/(final_time-start_time))))
這個(gè)函數(shù)會(huì)在錄制結(jié)束后讀取視頻文件的信息,包括幀率、幀數(shù)、分辨率以及錄制時(shí)間等,并打印出來。同時(shí),它還會(huì)計(jì)算并打印一個(gè)推薦幀率,這個(gè)推薦幀率是基于實(shí)際錄制時(shí)間與視頻文件中的幀數(shù)計(jì)算得出的。
主函數(shù)
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()
- 在主函數(shù)中,我們首先初始化全局變量flag為False,然后創(chuàng)建一個(gè)線程來運(yùn)行video_record函數(shù)。接著,我們使用pynput庫(kù)的keyboard.Listener來監(jiān)聽鍵盤事件,并將on_press函數(shù)作為回調(diào)函數(shù)。當(dāng)鍵盤監(jiān)聽結(jié)束時(shí)(即按下esc鍵后),主線程會(huì)等待1秒以確保視頻文件被正確釋放,然后調(diào)用video_info函數(shù)來打印視頻信息。
四、完整代碼
#!/usr/bin/env python
# -*- coding = utf-8 -*-
# @Time : 2021/10/6 17:43
# @Author : Leuanghing Chen
# @Blog : https://blog.csdn.net/weixin_46153372?spm=1010.2135.3001.5421
# @File : python實(shí)現(xiàn)錄屏功能.py
# @Software : PyCharm
# 發(fā)布程序:pyinstaller -F -w -i F:\python_demo\2.ico F:\python_demo\python實(shí)現(xiàn)錄屏功能.py
import time
import threading
from datetime import datetime
from PIL import ImageGrab
import numpy as np
from cv2.cv2 import cvtColor, VideoWriter_fourcc, VideoWriter, COLOR_RGB2BGR, VideoCapture,\
CAP_PROP_FPS, CAP_PROP_FRAME_COUNT, CAP_PROP_FRAME_WIDTH, CAP_PROP_FRAME_HEIGHT
from pynput import keyboard
# 錄入視頻
def video_record():
# 加了global,則可以在函數(shù)內(nèi)部對(duì)函數(shù)外的對(duì)象進(jìn)行操作了,也可以改變它的值了
global name
name = datetime.now().strftime('%Y-%m-%d %H-%M-%S') # 當(dāng)前的時(shí)間(當(dāng)文件名)
screen = ImageGrab.grab() # 獲取當(dāng)前屏幕
width, high = screen.size # 獲取當(dāng)前屏幕的大小
fourcc = VideoWriter_fourcc('X', 'V', 'I', 'D') # MPEG-4編碼,文件后綴可為.avi .asf .mov等
video = VideoWriter('%s.avi' % name, fourcc, 15, (width, high)) # (文件名,編碼器,幀率,視頻寬高)
for i in range(3):
time.sleep(1)
print("倒計(jì)時(shí):{}".format(3-i))
print('開始錄制!')
global start_time
start_time = time.time()
while True:
if flag:
print("錄制結(jié)束!")
global final_time
final_time = time.time()
video.release() # 釋放
break
im = ImageGrab.grab() # 圖片為RGB模式
imm = cvtColor(np.array(im), COLOR_RGB2BGR) # 轉(zhuǎn)為opencv的BGR模式
video.write(imm) # 寫入
# time.sleep(5) # 等待5秒再次循環(huán)
# 結(jié)束監(jiān)聽按鍵,按下esc結(jié)束錄屏
def on_press(key):
global flag
# esc鍵
if key == keyboard.Key.esc:
flag = True # 改變
return False # 返回False,鍵盤監(jiān)聽結(jié)束!
# 視頻信息
def video_info():
video = VideoCapture('%s.avi' % name) # 記得文件名加格式不要錯(cuò)!
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' % fps)
print('幀數(shù)=%.1f' % count)
print('分辨率', size)
print('視頻時(shí)間=%.3f秒' % (int(count)/fps))
print('錄制時(shí)間=%.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()
五、總結(jié)
通過結(jié)合多個(gè)Python庫(kù),我們實(shí)現(xiàn)了一個(gè)簡(jiǎn)單的屏幕錄制工具,該工具能夠?qū)崟r(shí)錄制屏幕并通過監(jiān)聽鍵盤事件來控制錄制的開始與結(jié)束。這個(gè)工具不僅可以用于個(gè)人娛樂或?qū)W習(xí),還可以作為開發(fā)屏幕錄制功能應(yīng)用程序的基礎(chǔ)。希望這篇博文能幫助你更好地理解如何使用Python來實(shí)現(xiàn)屏幕錄制與鍵盤監(jiān)聽功能。
以上就是使用Python實(shí)現(xiàn)屏幕錄制與鍵盤監(jiān)聽功能的詳細(xì)內(nèi)容,更多關(guān)于Python屏幕錄制與鍵盤監(jiān)聽的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
python PyQt5事件機(jī)制和定時(shí)器原理分析及用法詳解
PyQt為事件處理提供了兩種機(jī)制:高級(jí)的信號(hào)與槽機(jī)制,以及低級(jí)的事件處理機(jī)制,在基于PyQt5的應(yīng)用程序開發(fā)過程中經(jīng)常會(huì)遇到一些需要循環(huán)執(zhí)行的任務(wù),即定時(shí)多長(zhǎng)時(shí)間任務(wù)循環(huán)一次,本文給大家介紹了python PyQt5事件機(jī)制和定時(shí)器原理和用法,需要的朋友可以參考下2024-07-07
pandas 數(shù)據(jù)索引與選取的實(shí)現(xiàn)方法
這篇文章主要介紹了pandas 數(shù)據(jù)索引與選取的實(shí)現(xiàn)方法,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-06-06
利用matplotlib為圖片上添加觸發(fā)事件進(jìn)行交互
這篇文章主要介紹了利用matplotlib為圖片上添加觸發(fā)事件進(jìn)行交互,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2020-04-04
python實(shí)現(xiàn)替換word中的關(guān)鍵文字(使用通配符)
今天小編就為大家分享一篇python實(shí)現(xiàn)替換word中的關(guān)鍵文字(使用通配符),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2020-02-02
基于Python的A*算法解決八數(shù)碼問題實(shí)現(xiàn)步驟
這篇文章主要給大家介紹了關(guān)于如何基于Python的A*算法解決八數(shù)碼問題的實(shí)現(xiàn)步驟,文中介紹了八數(shù)碼問題及其求解方法,通過啟發(fā)式搜索算法,特別是A*算法,可以有效地解決八數(shù)碼問題,,需要的朋友可以參考下2024-11-11
Python?字符串使用多個(gè)分隔符分割成列表的2種方法
本文主要介紹了Python?字符串使用多個(gè)分隔符分割成列表,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2023-04-04

