n行Python代碼系列:兩行代碼實現(xiàn)視頻文件指定時刻畫面輸出

一、引言
最近看到好幾篇類似“n行Python代碼…”的博文,看起來還挺不錯,簡潔、實用,傳播了知識、帶來了閱讀量,撩動了老猿的心,決定跟風(fēng)一把,推一個“n行Python代碼系列”文章。
對于視頻中的精彩畫面,有時希望截圖保存,通過截屏軟件即可實現(xiàn),但截屏軟件只能通過播放軟件定位時間,該時間精確度為秒,對一些特殊需求如科研觀察來說不夠,另外截屏軟件可能會將播放器的一些控制組件也截屏下來。如下面的《粉絲記事本》的MV截取10秒位置的圖片:

本文介紹兩行代碼實現(xiàn)將視頻指定時刻畫面輸出到文件的方法。更多“n行Python代碼系列”文章請參考CSDN老猿Python的免費專欄《n行Python代碼系列》。
二、等時間間隔輸出視頻畫面
from moviepy.editor import *clip = VideoFileClip(r"F:\video\fansNote1M_crop.mp4")clip.save_frame (r"F:\video\fansNote1M.jpg",9.75)
from moviepy.editor import *VideoFileClip(r"F:\video\fansNote1M_crop.mp4").save_frame (r"F:\video\fansNote1M.jpg",9.75)
三、背景知識
3.1、moviepy介紹
要實現(xiàn)視頻剪輯,老猿使用了moviepy庫。
MoviePy是一個用于視頻編輯的Python模塊,可用于進行視頻的基本操作(如剪切、連接、標(biāo)題插入)、視頻合成(也稱非線性編輯)、視頻處理或創(chuàng)建高級效果。
它可以讀寫最常見的視頻格式,包括GIF。MoviePy能處理的視頻是ffmpeg格式的,老猿理解支持的文件類型至少包括:*.mp4 *.wmv *.rm *.avi *.flv *.webm *.wav *rmvb。
MoviePy使用ffmpeg讀取、導(dǎo)出視頻和音頻文件,使用ImageMagick生成文本和輸出GIF文件。Python的快速數(shù)字庫Numpy保證了不同媒體的處理。高級效果和增強使用了Python的許多圖像處理庫(PIL、Scikit-image、scipy等)。
moviepy的核心對象是剪輯(clips),包括AudioClips 和VideoClips。它們可以修改(剪切、減速、變暗…)或與剪輯混合以形成新剪輯,可以使用PyGame或IPython Notebook預(yù)覽,并可以輸出到對應(yīng)類型的文件(如MP4、GIF、 MP3等)。例如,VideoClips可以從視頻文件、圖像、文本或自定義動畫創(chuàng)建。VideoClips可以有一個音頻軌道(這是一個AudioClip)和一個mask(一個特殊的VideoClip,指示當(dāng)剪輯與其他剪輯混合時要隱藏哪些部分)。
3.2、moviepy安裝
MoviePy安裝非常簡單,使用pip安裝時,請將站點指向國內(nèi)的鏡像站點,否則下載很慢或者下載不下來,老猿使用清華的鏡像,指令是:
pip install -i https://pypi.tuna.tsinghua.edu.cn/simple moviepy
注意:
1、moviepy全小寫,安裝時會自動安裝相關(guān)依賴包;
2、建議安裝最新的版本1.0.3,因為1.0.2中有個比較大的bug,請見《在Python中使用moviepy進行視頻剪輯時輸出文件報錯 ‘NoneType’ object has no attribute 'stdout’問題》;
3、如果沒有安裝最新版本,可以執(zhí)行版本升級,指令:
pip install -i https://pypi.tuna.tsinghua.edu.cn/simple moviepy --upgrade
關(guān)于Moviepy更多的介紹,請參考老猿的免費專欄《PyQt+moviepy音視頻剪輯實戰(zhàn)》。
3.3、相關(guān)函數(shù)
上述代碼涉及到的相關(guān)函數(shù)包括VideoFileClip、save_frame。
3.3.1、VideoFileClip
VideoFileClip實際上是一個類,其構(gòu)造方法如下:
__init__(self, filename, has_mask=False, audio=True, audio_buffersize=200000,target_resolution=None, resize_algorithm=‘bicubic’,audio_fps=44100, audio_nbytes=2, verbose=False, fps_source=‘tbr’)`參數(shù)說明:
filename:視頻文件名,可以帶路徑
has_mask:是否有遮罩,如果視頻文件帶遮罩,則設(shè)置has_mask為True。視頻文件一般很少帶遮罩,但有些視頻編碼支持遮罩功能。例如如果moviepy合成了一個帶遮罩的剪輯,則可以使用《moviepy音視頻剪輯:視頻剪輯基類VideoClip的屬性及方法詳解》介紹的VideoClip.write_videofile將剪輯和遮罩、音頻信息一起保存到視頻文件中
audio:如果視頻文件不帶音頻或者不希望加載視頻文件的音頻,可以將audio參數(shù)設(shè)置為False
audio_buffersize:音頻文件讀取緩沖區(qū)大小,字節(jié)為單位,一般用缺省值足夠,如果audio_buffersize比一個音頻幀的大小還要小,會自動使用音頻幀的大小代替
target_resolution:設(shè)置為加載后需要變換到的分辨率,類型為列表或元組,第一個元素為分辨率的高,第二個為寬,如果高或?qū)捰幸粋€為None,則保持現(xiàn)有縱橫比調(diào)整幀的大小。如果保持原分辨率不變,則不需要設(shè)置本參數(shù)或設(shè)置為None。如果設(shè)置了新的分辨率,則在調(diào)用ffmpeg 返回視頻剪輯的幀之前會按新的分辨率調(diào)整幀的大小。這比使用轉(zhuǎn)換為高分辨率流然后再調(diào)整分辨率會快很多
resize_algorithm:要改變加載后的視頻分辨率,可以通過resize_algorithm指定調(diào)整分辨率的算法,缺省值為 “bicubic”,還可以是 “bilinear” 、"fast_bilinear"等。關(guān)于算法的更多信息請參考:https://ffmpeg.org/ffmpeg-scaler.html
audio_fps:聲音的采樣頻率
audio_nbytes:聲音采樣的位數(shù)
verbose:是否在標(biāo)準(zhǔn)輸出設(shè)備上顯示處理信息
fps_source:從視頻的元數(shù)據(jù)metadata哪個數(shù)據(jù)中獲取fps值,默認設(shè)置為’tbr’,但可以設(shè)置為’fps’,這可能有助于導(dǎo)入慢動作視頻,否則可能會出意外。
3.3.2、save_frame函數(shù)
save_frame函數(shù)用于將t指定時刻位置的幀保存到指定圖像文件。調(diào)用語法如下:
save_frame(self, filename, t=0, withmask=True)filename:輸出圖片文件名
t:指定時刻,以輸出75.35秒為例,t的表示方法可以是如下四種之一:
√ 數(shù)字秒,為一個浮點數(shù)數(shù)字,如75.35
√ 分鐘和秒組成的元組,如(1,15.35)
√ 時、分、秒組成的元組,如(0,1,15.35)
√ 用冒號分隔的時間字符串,如‘0:1:15.35’
withmask:如果withmask為True,對應(yīng)幀的遮罩會被寫入圖片的alpha通道層,僅對PNG圖像有效
四、小結(jié)
本文介紹了使用Python+Moviepy 兩行代碼實現(xiàn)將視頻輸指定位置的圖片畫面輸出到圖片文件的方法,并介紹了moviepy的功能及安裝以及相關(guān)處理的關(guān)鍵函數(shù)及語法。

