前言 女朋友是一個老師,在工作中經常會遇到需要錄屏記錄自己操作,方便後續開發同學定位。因為錄屏軟體動不動就開始收費,所以她經常更換錄屏軟體。閑暇之餘,我就覺得手癢,感覺可以用萬能的 Python 來解決她的煩惱。 實現思路 我上網搜尋了一下相關知識,錄製視頻基本上都用的圖像處理庫 PIL 的 Ima ...
前言
女朋友是一個老師,在工作中經常會遇到需要錄屏記錄自己操作,方便後續開發同學定位。因為錄屏軟體動不動就開始收費,所以她經常更換錄屏軟體。閑暇之餘,我就覺得手癢,感覺可以用萬能的 Python 來解決她的煩惱。
實現思路
我上網搜尋了一下相關知識,錄製視頻基本上都用的圖像處理庫 PIL 的 ImageGrab 模塊。這個模塊可以用於將當前屏幕的內容或者剪貼板上的內容拷貝到 PIL 圖像記憶體。
既然這個模塊可以獲取當前屏幕上的內容,那麼我一直不間斷地獲取,然後把這些獲取的內容拼起來,那不就是視頻了嗎?
如何錄製?
整體思路是 PIL 模塊中的 ImageGrab 不停的獲得當前屏幕,利用 opencv 寫入視頻流。
Python學習交流Q群:906715085### def video_record(sttime): global name # 當前的時間(當文件名) name = datetime.now().strftime('%Y-%m-%d %H-%M-%S') # 獲取當前屏幕 screen = ImageGrab.grab() # 獲取當前屏幕的大小 width, high = screen.size # MPEG-4編碼,文件尾碼可為.avi .asf .mov等 fourcc = VideoWriter_fourcc('X', 'V', 'I', 'D') # (文件名,編碼器,幀率,視頻寬高) video = VideoWriter('%s.avi' % name, fourcc, 15, (width, high)) print(str(sttime) + '秒後開始錄製----') time.sleep(int(sttime)) print('開始錄製!') global start_time start_time = time.time() while True: if flag: print("錄製結束!") global final_time final_time = time.time() # 釋放 video.release() break # 圖片為RGB模式 im = ImageGrab.grab() # 轉為opencv的BGR模式 imm = cvtColor(np.array(im), COLOR_RGB2BGR) # 寫入 video.write(imm)
錄製視頻的主要代碼只需幾行即可,但是我們需要對錄製操作進行控制,例如開始錄製、結束錄製等。以及獲取屏幕內容之後,需要對內容進行轉碼,然後寫入視頻流。
監聽鍵盤事件
錄製視頻我們是使用的一個 while 迴圈來獲取屏幕信息,開始之後會一直進行。但是我們需要監聽鍵盤事件,來終止這個迴圈,從而終止錄製視頻。這個監聽事件就顯得很重要了,這裡採用的是 pynput 這個強大的三方庫,可以全局監聽鍵盤、滑鼠事件。
我們設定的是用戶在按下鍵盤的 ESC 按鍵後,終止 while 迴圈,從而終止視頻錄製。
# 監聽按鍵 def on_press(key): global flag if key == keyboard.Key.esc: flag = True # 返回False,鍵盤監聽結束! return False
主體控制
因為我們需要不斷地獲取屏幕內容,所以我們最好啟動一個線程來乾這個事情。
th = threading.Thread(target=video_record, args=sstime) th.start() with keyboard.Listener(on_press=on_press) as listener: listener.join()
視頻信息
錄製視頻結束之後,我們也可以獲取視頻的一些相關信息,例如時長、幀率、解析度等。
#視頻信息 def video_info(): # 記得文件名加格式不要錯! video = VideoCapture('%s.avi' % name) 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('幀數=%.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))))
標題 效果
最後,我啟兩個程式,第一個程式啟動錄製之後,我再來操作第二個程式,這樣大家就可以看到這個程式的運行過程。效果就大家自己去看了。
總結
這裡的程式只是一個初版,剛剛實現了錄製屏幕的想法。後續還需要對其進行改進,支持 GUI 界面操作,支持框選特定區域錄製等等。今天的這一篇到這裡來就完了,下一篇見。