python全局键盘监听(pynput快捷键);利用pywin32快速截屏并生成视频
python全局鍵盤監聽(pynput快捷鍵);利用pywin32快速截屏并生成視頻
第一次在CSDN寫博客,有點小緊張(/ω\)
以下內容完全個人理解,有錯誤請指出~
最近在用python做一個小工具包,這兩天想加入錄屏功能了;就在網上搜羅了一大堆python錄屏的代碼,思路都差不多,除了ffmpeg的方法其他都是用先截屏在用opencv生成視頻的,ffmpeg的方法因為過于復雜我就不研究了,其他的主要有PLC+opencv的、pyqt5+opencv的、還有本篇文章用到的pywin32的方法前面的兩種其實都可以實現(我的小工具包就是用pyqt5截屏的),但相對于pywin32來說都是太!慢!了!
進入正題:
鍵盤監聽功能實現
這個錄屏工具還有我正在做的工具包都是主要利用快捷鍵功能啟動的,鍵盤監聽就用了pynput,話不多說,上后臺監聽部分代碼:
from pynput import keyboardALT = False Z = False X = False C = False #本文中只用到ALT和C其他的備用(在我的小工具包里ALT+Z是截屏、ALT+x是截屏文字識別)自行擴展 def listen(): # 鍵盤監聽函數print("listening")def on_press(key):global ALT, Z, X, C, start_time, real_fpsif key == keyboard.Key.alt or key == keyboard.Key.alt_l or key == keyboard.Key.alt_r:ALT = Trueif key == keyboard.KeyCode(char='z') or key == keyboard.KeyCode(char='Z'):Z = Trueif key == keyboard.KeyCode(char='x') or key == keyboard.KeyCode(char='X'):X = Trueif key == keyboard.KeyCode(char='c') or key == keyboard.KeyCode(char='C'):C = True# print(ALT, Z, X, C)if ALT and C: # 檢測到Alt和c同時按下時,啟動/關閉錄屏ALT = C = Falserecord.recording = not record.recordingprint(11)# startt = time.process_time()if record.recording:start_time = time.process_time() # 記錄錄屏開始時間startrecord = StartRecord()startrecord.start()print("錄屏開始")else:print("錄制時間" + str(time.process_time() - start_time))real_fps = i / (time.process_time() - start_time) # 計算真實幀率print("fps" + str(real_fps))def on_release(key):global ALT, Z, X, Cif key == keyboard.Key.alt or key == keyboard.Key.alt_l or key == keyboard.Key.alt_r:ALT = Falseif key == keyboard.KeyCode(char='z') or key == keyboard.KeyCode(char='Z'):Z = Falseif key == keyboard.KeyCode(char='x') or key == keyboard.KeyCode(char='X'):X = Falseif key == keyboard.KeyCode(char='c') or key == keyboard.KeyCode(char='C'):C = Falsewith keyboard.Listener(on_press=on_press, on_release=on_release) as listener:listener.join()class ListenThread(Thread): # 截屏監聽線程,監聽函數一定要放在后臺線程里康康說明那個join了嗎( ̄︶ ̄)↗ def __init__(self):super().__init__()def run(self):listen()if __name__ == "__main__":listenThread = ListenThread() # 創建監聽線程listenThread.start()這個應該很好懂的,不懂就看官方文檔吧https://pynput.readthedocs.io/en/latest/index.html
(゜ー゜)畢竟我也是這么看過來的…
下面就是主角了
截屏及生成視頻
下面是錄屏主體,我把它放在一個類中(我也不知道為撒,直覺告訴我放在類中好用一點點)
import win32con import win32gui import win32ui class Recordingthescreen():def __init__(self):self.recording = Falseself.recorded = Falseself.recorded2 = Falseself.namelist = []self.fps = real_fpsself.size = (500, 500) # 截屏寬度,改變這個可以自定義錄屏范圍self.x = 0self.y = 0 # 截屏開始點,改變這個可以自定義錄屏范圍self.videoWriter = cv2.VideoWriter('t/TestVideo.avi', cv2.VideoWriter_fourcc(*'XVID'),self.fps,self.size) # *'XVID'MPEG-4編碼 *'mp4v' *'PIMI' MPEG-1編碼 *'I420'(無損壓縮avidef window_capture(self, filename, x, y, w, h):hwnd = 0 # 窗口的編號,0號表示當前活躍窗口# 根據窗口句柄獲取窗口的設備上下文DC(Divice Context)hwndDC = win32gui.GetWindowDC(hwnd)# 根據窗口的DC獲取mfcDCmfcDC = win32ui.CreateDCFromHandle(hwndDC)# mfcDC創建可兼容的DCsaveDC = mfcDC.CreateCompatibleDC()# 創建bigmap準備保存圖片saveBitMap = win32ui.CreateBitmap()# 為bitmap開辟空間saveBitMap.CreateCompatibleBitmap(mfcDC, w, h)# 高度saveDC,將截圖保存到saveBitmap中saveDC.SelectObject(saveBitMap)# 截取從左上角(0,0)長寬為(w,h)的圖片saveDC.BitBlt((0, 0), (w, h), mfcDC, (x, y), win32con.SRCCOPY)saveBitMap.SaveBitmapFile(saveDC, filename)win32gui.DeleteObject(saveBitMap.GetHandle())saveDC.DeleteDC()mfcDC.DeleteDC()win32gui.ReleaseDC(hwnd, hwndDC)def record(self):global ii = 0prossthread = FileThread() # 視頻合成線程prossthread.start()if self.recording:self.videoWriter = cv2.VideoWriter('t/TestVideo.avi', cv2.VideoWriter_fourcc(*'XVID'),self.fps,self.size) # *'XVID'MPEG-4編碼 *'mp4v' *'PIMI' MPEG-1編碼 *'I420'(無損壓縮avix = self.xy = self.yw = self.size[0]h = self.size[1]print("creatwriter")while self.recording:t1 = time.process_time()self.window_capture("t/haha{0}.png".format(i), x, y, w, h)namelist.append("t/haha{0}.png".format(i))i += 1self.recorded = Trueprint(str(i) + '\t' + str(time.process_time() - t1))print("截屏結束,繼續處理中")if not self.recording and self.recorded:self.recorded2 = Trueprossthread.join(200) # 等待原始視頻合成處理完畢self.videoWriter.release() # 釋放資源print("視頻幀率修正中...")# 根據真實幀率處理原始視頻videoWriter2 = cv2.VideoWriter('t/output' + str(time.time()) + '.mp4', cv2.VideoWriter_fourcc(*'mp4v'),real_fps,self.size) # *'XVID'MPEG-4編碼 *'mp4v' *'PIMI' MPEG-1編碼 *'I420'(無損壓縮avivideoCapture = cv2.VideoCapture('t/TestVideo.avi')success, frame = videoCapture.read()#從原始視頻中逐幀讀取while success:success, frame = videoCapture.read()videoWriter2.write(frame) # 重寫視頻,修正幀率videoWriter2.release()print("視頻導出成功")self.recorded = Falseself.recorded2 = Falsenamelist.clear()i = 0 # 重置為0幀,為下一次錄屏做準備```hhh看注釋應該都懂了的,我也懶得解釋了…(打好多字好類( ̄ ‘i  ̄;)
其中涉及了一個修正幀率的步驟,因為不知道截屏總時間又要不占用截屏功能很難實時計算出幀率,我也是迫不得已。。
為避免線程堵塞,我又為啟動錄屏函數和后臺處理圖片(生成視頻)函數創建了新線程:
class StartRecord(Thread): # 開始錄屏線程def __init__(self):super().__init__()def run(self):record.record()class FileThread(Thread): # 圖片處理線程(生成原始視頻)def __init__(self):super().__init__()def run(self):while 1:if namelist:frame = namelist.pop(0)img2 = cv2.imread(frame)record.videoWriter.write(img2)os.remove(frame)if not namelist and record.recorded2:print("處理完畢")record.videoWriter.release()break好了,現在我們把上面的各種類調用一下
(總體代碼)
好,本教程到此結束了(才怪)
怎么能不說說用法呢?
運行打印出listening,就可以按下鍵盤的Alt+C鍵,命令行會輸出當前截取的圖片數以及每一幀截取的時間(后臺線程也會同時將圖片寫入視頻文件中),再次按下Alt+C鍵可以終止錄屏,等待后臺線程處理完成,再根據計算的幀率和暫時輸出的原始視頻文件重新生成幀率對應的視頻文件。輸出完成后可以繼續重新錄屏,錄全屏的話幀率會有點低,可以修改上述代碼中的self.size = (500, 500) # 截屏寬度,改變這個可以自定義錄屏范圍 self.x = 0,self.y = 0 # 截屏開始點,改變這個可以自定義錄屏范圍,范圍小一點可以有較大的幀率
關于用到的幾個模塊的安裝:
關于用到的幾個模塊的安裝:
其中pywin32最難安裝了(我搗騰了好久)最終在
里下載了對應包才搞好,其他的都可以Google一下就有。。。。
pywin32:
這里只提供python3.7對應版本(GitHub上下載是真的慢。。。)
opencv:
pip install opencv-pythonpynput:
pip install pynput關于打包,opencv的打包后運行會報錯把python目錄下的
opencv_videoio_ffmpeg412_64.dll樣的dll文件打包進去就行(這個包是真的大)
吐槽一下
win32ui與PyQt5會沖突,我的工具包就是用pyqt5做的界面,然后如果我把這個截屏(錄屏)代碼導入我的主程序中時,pyqt5在調用窗口處理函數(如hide()show())時就會卡頓。。。。
所以我的小工具就用不上這個錄屏代碼了╥﹏╥…現在是用了ffmpeg的流式視頻處理功能直接錄屏了,而且性能超超超強,占用比QQ錄屏占用低一半以上,錄屏質量也大幅提高(支持無損錄屏!),ffmpeg教程還是以后在寫吧。。。先放幾張我在我的小工具里面用ffmpeg錄屏的圖hh(還能錄gif!,良不良心?)
同時jamtools還支持自定義幀率、鼠標錄制、輸出格式、編碼等,用H.264編碼還可以調整錄屏的碼率,安裝插件還能只錄制系統聲音!(這些都被我集成了~嘻)
ps(2020.4.9):目前已經集截屏(支持滾動截屏)、錄屏、識屏、文字提取(批量/截屏)、翻譯、格式轉換(各種媒體的裁剪拼接轉碼提取等!)、控制(錄制鍵鼠動作并自定義重復播放!就是按鍵精靈吶)、聊天(一個沙雕聊天機器人。。)還支持所有界面劃屏提字翻譯!而且完全免費無廣告!網上大多數錄屏軟件都是付費的。。或者有廣告。。而且只有70多M (暫時是0.7.5版)。。
點擊文末鏈接或在在公眾號機械醬的小黑屋可以獲取!
軟件更新請留意公眾號‘機械醬的小黑屋’
(混個積分)嘻嘻~( ̄▽ ̄)"
本文源碼
本文源碼打包的可運行文件(.exe)
本文中提到的自己做的工具包JamTools:(截屏、錄屏、文字識別、翻譯、圖像識別、右鍵畫屏提字翻譯、格式轉換、按鍵精靈、聊天機器人等功能)歡迎體驗(禁止用于二次開發、售賣等用途,版權歸本作者所有!)
(tips:CSDN這個版本已經太舊啦,可以到下面github鏈接上面下載最新的安裝包)
JamTools github鏈接:https://github.com/fandesfyf/JamTools
一個分割線:
(20200321更新)最近發現了pynput最新版(1.6.8)已經有現成的快捷鍵接口了,可以直接注冊全局快捷鍵.
示例用法:
具體請看pynput最新的1.6.8官方文檔
本文作者:機械醬&Fandes
總結
以上是生活随笔為你收集整理的python全局键盘监听(pynput快捷键);利用pywin32快速截屏并生成视频的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Layui-经典模块化前端框架
- 下一篇: Simhash算法详解及python实现