需求背景
有一個需求,要在視頻中進行截圖,人工處理的話,就是要求選擇一些比較精彩的鏡頭進行手工截取圖片,這就意味著,每個視頻都要自己去看一遍,然后選擇比較好的鏡頭截圖保存。
但是這種方法有很多弊端:
- 視頻有很多,一個一個地看浪費時間和精力。
- 一個視頻里要截很多圖片,手動截取比較慢。
- 手工截取的圖片如果不注意,會把視頻邊緣的播放器邊框、外部背景給截到,然后會有黑邊、白邊等問題。
于是迫切需要一個自動化的工具,能夠對視頻進行截圖,按照一定的規則截取,比如按照時間間隔、時間點、幀數等等進行截圖,哪怕是截出來的圖片可能鏡頭不是很好,截完圖后再去人工篩選也是比較快的。
利用現在比較火的語言——Python/ target=_blank class=infotextkey>Python進行視頻截圖
Python是比較好上手的一個編程語言了,而且最近一直挺火的,主要是其強大的類庫,省去了大量的造輪子的過程,讓編程更加專注于業務本身,更加專注于實現你的目的。
而且Python這門語言不難,會點計算機知識、會點編程的應該一學都會了。
利用Python進行視頻截圖,是一件相對比較容易實現的事情,而且一旦寫成,一勞永逸,能節省掉后期大量手工截圖花的功夫,有那個時間,喝喝茶、看看劇不是挺好嗎?
這篇文章目的也是為了照顧各種小白,讓大家更好的理解,所以介紹的會比較通俗一些。
好了,那么就讓我們開始吧!
首先安裝Python
這個就不用多說了吧,大家直接去Python官網下載安裝包。
然后安裝即可。實在不會的話,百度一下有很多安裝教程,照葫蘆畫瓢一學就會。這不是本文的核心,因此不做過多展開了。
選擇你喜歡的IDE(開發工具)或者編輯器寫代碼
這里筆者比較推薦使用vscode和pycharm。
vscode是微軟推出的一款強大的編輯器,支持各種語言的開發,以及文本文檔的編寫。其強大的插件機制,讓一款編輯器可以躍身成為一款強大的“IDE”。
pycharm是一款jetbrains公司推出的,專門用于python開發的IDE,非常強大好用。
二者選其一,輕量級的選vscode會比較好。(推薦)
創建video_capture.py
創建一個py腳本文件,取名的話,你可以隨意,我這里取名為:video_capture.py
這個腳本文件就是我們要寫代碼的地方了。
安裝opencv-python這個類庫
opencv這個類庫時需要先安裝才能使用。
按 Win + R組合鍵,調出搜索框,輸入cmd,回車打開命令行。
在命令行中輸入下面這行內容進行安裝:
pip install opencv-python
但是可能會安裝失敗:
這是因為源的問題,改成阿里源就能安裝成功了!
pip install opencv-python -i http://mirrors.aliyun.com/pypi/simple/ --trusted-host mirrors.aliyun.com
嗯,這樣就安裝成功了。
開始寫代碼
如果你看不懂,或者實在不想看,可以直接劃到最后,點擊關注@IT研究僧大師兄,私信我,發送“視頻截圖Python腳本”,我看到后會直接發給你的。
首先,導入cv2:
import cv2
再導入os庫,創建文件要用:
import os
打開視頻文件,這一步是獲取一個視頻截圖的對象。
cap = cv2.VideoCapture(video_path)
獲取視頻的總幀數:
total_frames = int(cap.get(cv2.CAP_PROP_FRAME_COUNT))
獲取視頻的幀率:
fps = cap.get(cv2.CAP_PROP_FPS)
然后就能得到視頻的總時長:
duration = total_frames / fps
拿到總時長的目的,就是為了后面能夠根據時間來截圖。
提前創建好截圖保存的目錄:
try:
os.mkdir(self._output_path)except OSError:
pass
然后一個比較關鍵的地方是計算時間點:
msec = (1000 * start_time + count * 1000 * time_interval)
其中start_time是起始時間的秒數,time_interval是時間間隔的描述,這個用來每隔多少秒進行截圖。
計算得到的msec就是視頻時間點的毫秒數了,然后使用這個時間設置視頻的時間位置:
(1000 * self._start_time + count * 1000 * self._time_interval)
這個函數,就是把視頻的拉到指定時間的位置,就和你自己在播放器上拖動視頻的進度條一樣。
然后讀取視頻的這一幀圖片。
success, image = cap.read()
返回值success是bool值,true或者false,true就表示讀取成功,false就是失敗。
返回值image就是這個時間點的圖片了。
然后就是將這個圖片進行保存,存儲在指定的路徑中。
cv2.imwrite(out_path, image, [int(cv2.IMWRITE_JPEG_QUALITY), 100])
out_path就是要存儲的路徑+文件名,image是當前截取的這張圖片,后面的參數是設置圖片質量,這個設置100就行,最高質量。
這就完成截取圖片了。
簡單嗎?
其實簡單來說,就是分三步:
- 設置視頻時間點。
- 讀取圖片。
- 保存圖片。
是非常簡單了。這樣子,只要加上相應的循環控制條件,從start_time循環到end_time,然后每一個時間間隔time_interval截取一張圖,這樣就能對視頻按時間間隔截取批量的圖片了。
擴展實現:獲取指定時間點的圖片
這個可以想象一下,只要給出視頻的小時數、分鐘數、秒數,比如這種格式:
01:31:40
這就意味著要截取一小時三十一分四十秒處的圖片。
然后將這個時間格式轉化為毫秒數msec,然后通過
cap.set(cv2.CAP_PROP_POS_MSEC, msec)
設置視頻的時間點,然后進行讀取、保存就ok了。
總結
然后通過這個就能夠進行一些額外的擴展,比如獲取指定時間范圍內的視頻截圖?
只要制定開始時間start_time,截止時間end_time,然后對這個范圍內按照時間間隔進行截圖,就ok了。
希望能給你們啟發!