moviepy音視頻剪輯:視頻剪輯基類VideoClip的屬性及方法詳解

☞ ░ 前往老猿Python博文目錄

一、概述

在《moviepy音視頻剪輯:moviepy中的剪輯基類Clip詳解》和《moviepy音視頻剪輯:moviepy中的剪輯基類Clip的屬性和方法詳解》介紹了剪輯相關類及類關係。可以看到視頻剪輯類VideoClip是其中非常重要的一個剪輯類,它主要有六個直接子類(VideofileClip、 ImageSequenceClip、CompositeVideoClip、ImageClip、DataVideoClip、UpdatedVideoClip)和兩個間接子類(ColorClip, TextClip)。

二、VideoClip的構造方法和屬性

2.1、構造方法

2.1.1、構造方法語法:

__init__(self, make_frame=None, ismask=False, duration=None, has_constant_size=True)

2.1.2、參數釋義

  • make_frame:幀的構建方法,幀的構建方法用於根據時間構建幀,該方法是get_frame獲取幀時調用的方法。幀的構建可以從已有剪輯中獲取或變換,也可以代碼自己填充;
  • ismask:是否作爲遮罩使用
  • duration:構建剪輯的時長
  • has_constant_size:表示是否所有幀大小都是相同,如果是動態圖像,該值必須爲False,該值用於增加遮罩時使用,如果固定大小,遮罩大小就是剪輯的大小,如果不是,則遮罩大小需要加遮罩的視頻幀取對應幀的大小。

2.2、size屬性

剪輯的大小和分辨率,是一個二元組,內容爲:(寬度,高度),單位是像素,直接通過屬性名訪問。

2.3、w,h屬性

w,h屬性即剪輯的寬和高,單位是像素,實際這兩個屬性就是從size屬性獲取的。屬性訪問直接通過屬性名訪問。

2.4、ismask屬性

布爾類型表示剪輯是否爲遮罩,該屬性在構造方法中傳入。

2.5、make_frame屬性

幀的構建方法,通過構造方法傳入或set_make_frame方法設置,幀的構建方法用於根據時間構建幀,該方法是get_frame獲取幀時調用的方法。幀的構建可以從已有剪輯中獲取或變換,也可以代碼自己填充。

2.6、mask屬性

當一個視頻幀有遮罩時,使用該屬性記錄遮罩的剪輯。如果爲None,則視頻剪輯完全不透明。可以通過add_mask、set_opacity等方法來構建剪輯的遮罩,也可以通過set_mask來將已有的剪輯設置爲視頻剪輯的遮罩。

2.7、aspect_ratio屬性

aspect_ratio屬性爲剪輯的縱橫比,實際上就是剪輯的寬/高。注意該屬性爲浮點數,只讀,通過屬性名訪問。

三、VideoClip的訪問方法

3.1、save_frame方法

save_frame方法調用語法如下:
save_frame(self, filename, t=0, withmask=True)

該方法用於將t指定時刻位置的幀保存到指定圖像文件,t 表示方法可以是如下四種之一:

  1. 秒,爲一個浮點數數字,如75.35
  2. 分鐘和秒組成的元組,如(1,15.35)
  3. 時、分、秒組成的元組,如(0,1,15.35)
  4. 用冒號分隔的時間字符串,如‘0:1:15.35’

如果withmask爲True,對應幀的遮罩會被寫入圖片的alpha通道層,僅對PNG圖像有效。

注:

圖像的alpha通道一般用作不透明度參數。如果一個像素的alpha通道數值爲0%,那它就是完全透明的(也就是看不見的),而數值爲100%則意味着一個完全不透明的像素(傳統的數字圖像)。在0%和100%之間的值則使得像素可以透過背景顯示出來,就像透過玻璃(半透明性),它使數碼合成變得容易。alpha通道值可以用百分比、整數或者像RGB參數那樣用0到1的實數表示。

3.2、write_videofile方法

write_videofile方法用於將視頻剪輯輸出到文件,調用語法如下:

write_videofile(self, filename, fps=None, codec=None,
                        bitrate=None, audio=True, audio_fps=44100,
                        preset="medium",
                        audio_nbytes=4, audio_codec=None,
                        audio_bitrate=None, audio_bufsize=2000,
                        temp_audiofile=None,
                        rewrite_audio=True, remove_temp=True,
                        write_logfile=False, verbose=True,
                        threads=None, ffmpeg_params=None,
                        logger='bar')

參數說明如下:
  • filename:視頻文件名,只要是ffmpeg支持的視頻文件如 .ogv, .mp4, .mpeg, .avi, .mov等都可以
  • fps:幀率,每秒編碼的幀數
  • codec:用於圖像編碼的編解碼器,可以是ffmpeg支持的任何編解碼器。如果文件名的擴展名爲“.mp4”、“.ogv”、“.webm”,則會相應地設置編解碼器,但如果不喜歡默認值,則仍可以進行設置。對於其他擴展名,必須相應地設置輸出文件名。一些常用的編解碼器如下:
  • ‘libx264’:視頻壓縮效果好的一款編解碼器,MP4的缺省編解碼器,視頻質量通過bitrate參數調節
  • ‘mpeg4’:一種可選的MP4編解碼器,可以替代’libx264’,可以獲得更好的視頻質量
  • ‘rawvideo’:完美的視頻質量,但文件會巨大,對應視頻文件爲’.avi’
  • ‘png’:完美的視頻質量,對應視頻文件爲’.avi’,但文件大小比’rawvideo’小
  • ‘libvorbis’:是一種完全開放、免費的編解碼器,有不錯的視頻格式,但是要不廣,對應視頻文件爲’.ogv’
  • ‘libvpx’:一種很適合在HTML5中使用的網絡視頻輕量級編開源解碼器,對應視頻文件爲’.webm’
  • bitrate:輸出視頻的比特率,也即碼率BPS(Bits Per Second),指每秒傳送的數據位數
  • audio:可以爲True、False或文件名,如果True且剪輯附加了音頻,則音頻將作爲視頻的音頻保存,如果爲False則不保存音頻,如果爲音頻文件名則將此音頻文件將作爲視頻的音頻
  • audio_fps:聲音的採樣頻率
  • preset:設置FFMPEG用於優化壓縮的時間。字符串類型,可選值有:ultrafast、superfast、veryfast、faster、fast、medium、slow、slower、veryslow、 placebo。請注意,這不會影響視頻的質量,隻影響視頻文件的大小。所以如果趕時間而文件大小不是很重要可以設置爲ultrafast
  • audio_nbytes:音頻的採用的位數,對應基於字節爲單位就是聲道數;
  • audio_codec:音頻解碼器,例如’.mp3’的’libmp3lame’、‘ogg’的’libvorbis’、 ‘m4a’的’libfdk_aac’、 ‘pcm_s16le’ 16位聲音和’pcm_s32le’的32位聲音。默認值爲“libmp3lame”,除非視頻擴展名爲“ogv”或“webm”,在這2種情況下,默認值爲“libvorbis”。
  • audio_bitrate:音頻比特率,字符串形式,如“50k”、“500k”、“3000k”,用於將確定輸出文件中音頻的大小/質量。請注意,這主要是一個指示性目標,輸出文件的比特率不一定會按此設置。
  • audio_bufsize:音頻緩衝區大小
  • temp_audiofile:如果輸出由音頻,則該參數用於指定要生成併合併到電影中的臨時音頻文件的名稱,如果沒有指定則用缺省模式的臨時文件名
  • rewrite_audio:這個參數目前沒有作用,估計是爲了兼容以前的版本
  • remove_temp:是否刪除臨時文件
  • write_logfile:如果爲True,將爲音頻和視頻輸出記錄日誌文件。日誌文件將以“.log”結尾,包含輸出文件的名稱
  • verbose:已經廢棄使用,留下來是爲了兼容性,以前用於打開/關閉消息。現在使用logger=None。
  • threads:用於ffmpeg的線程數,可以加快多核計算機上視頻輸出的速度
  • ffmpeg_params:需額外傳遞的其他ffmpeg參數,用列表傳遞,形如:[’-option1’,‘value1’,’-option2’,‘value2’]
  • logger:字符串類型,"bar"表示進度條、None 表示不設置、或任何程序日誌記錄器的名字

3.3、write_images_sequence方法

write_images_sequence方法用於將剪輯輸出到一系列文件中,調用語法如下:

write_images_sequence(self, nameformat, fps=None, verbose=True,withmask=True, logger='bar')
參數說明如下:
  • nameformat:輸出格式和文件名規則,指定了文件系列序號的數字格式和圖片類型擴展名的文件名,例如文件名的“frame%03d.png”表示文件名開頭爲“frame”,後面“%03d”表示文件順序號以3位數字來順序編號,文件名後綴“png”表示編碼格式爲PNG。文件名格式還可以帶路徑方式,如“目錄名\f%04d.jpeg”等。但要求目錄名必須已存在,另外如果輸出的文件數比設置的序列號範圍要多,則會自動往上加1擴展,直到所有內容都輸出完成
  • fps:每秒輸出幀數,如果沒指定則按剪輯的fps進行輸出
  • withmask:是否將遮罩作爲圖像的alpha通道輸出,僅對png圖像格式有效
  • verbose:是否輸出處理信息
  • logger:字符串類型,"bar"表示進度條、None 表示不設置、或任何程序日誌記錄器的名字

3.4、write_gif方法

write_gif將剪輯轉換成gif動畫輸出到文件中,調用語法:

def write_gif(self, filename, fps=None, program='imageio',
                  opt='nq', fuzz=1, verbose=True,
                  loop=0, dispose=False, colors=None, tempfiles=False,
                  logger='bar'):
參數說明如下:
  • program:用於轉換的軟件,可以是“imageio”(這將通過imageio使用FreeImage庫),或者是“ImageMagick”,或者是“ffmpeg”
  • opt:應用優化的選項,如果program參數是’imageio’,opt必須是’wu’(Wu)或“nq”(Neuquant),。如果program=‘ImageMagick’,opt可以是“optimizeplus”或“OptimizeTransparency”
  • fuzz:僅當program='ImageMagick’時需要,通過考慮小於fuzz%的顏色差異實際上是相同的來壓縮GIF文件大小
  • loop:表示GIF文件播放時循環播放多少次,如果爲0就一直不停地播放,否則播放設定次數後就停止,該參數由GIF文件頭控制
  • dispose:表示播放動畫時渲染當前幀時,如何處理前一幀,該參數由GIF文件頭控制,moviepy沒有說明該參數怎麼使用,缺省值爲False,老猿查閱了相關資料,才基本確認該參數的作用,但GIF中該控制參數有四個取值,不知道是否都支持,取值及含義如下:
  • 爲0表示繪製一個完整大小的、不透明的GIF幀來替換上一幀,就算連續的兩幀只在局部上有細微的差異,每一幀依然是完整獨立的繪製
  • 爲1表示未被當前幀覆蓋的前一幀像素將繼續顯示,這種方式常用於對GIF動畫進行優化,當前幀只需在上一幀的基礎上做局部刷新,上一幀中沒有被當前幀覆蓋的像素區域將繼續展示。這種方式既能節省內存,也能提高解碼速度
  • 爲2 表示繪製當前幀之前,會先把前一幀的繪製區域恢復成背景色,這種方式常用於優化很多幀背景相同的情況,上一幀的背景色能通過當前幀的透明區域顯示
  • 爲3表示繪製當前幀時,會先恢復到最近一個設置爲False或1的幀,然後再將當前幀疊加到上面,這種方式性能比較差,已經被慢慢廢棄
  • colors:關於這個參數moviepy沒有說明,老猿將該值設置爲一個比較大的值,結果報錯“ValueError: GIF quantize param must be 2…256”,最後查閱資料確認該參數表示色彩量化使用的調色板索引,取值爲2到256。GIF最高支持8位256色,那麼如果原圖是真彩色的,則在生成最終效果圖時,就涉及到真彩色到256的降色。真彩色是24位的,有2的24種顏色,每個像素用3個字節標識一個顏色,R、G、B各佔一個字節,而256色每個像素只用一個字節從調色板中索引一種顏色,調色板最多有256種顏色。將2^24種顏色降爲256種顏色,降色的過程被成爲色彩量化。色彩量化過程分兩步:1、根據圖片定製調色板;2、遍歷像素,對於每一個像素,從調色板中找最接近的顏色,記錄該顏色索引。關於調色板請參考《調色板詳解
  • tempfiles:將每個幀寫入一個文件,而不是將它們傳遞到RAM中。在內存很少的計算機上很有用,只能與ImageMagick或ffmpeg一起使用。

3.5、subfx方法

subfx方法用於對剪輯指定時間段進行變換,返回該段剪輯變換後的剪輯和原剪輯其他段拼接後的新剪輯,剪輯的時長會自動調整。語法如下:
subfx(self, fx, ta=0, tb=None, **kwargs)

參數說明:
  • fx:用於對剪輯進行變換處理的函數名,這些函數可以是自定義函數,也可以是moviepy.video.fx包下的模塊內定義好的可以直接使用的函數,以及其他可能的函數
  • ta:剪輯段開始位置
  • tb:剪輯段結束位置,如果tb爲None,則tb被設置爲原剪輯的duration,如果tb爲負數,則tb被設置爲剪輯的duration + tb
  • kwargs,調用fx函數時需要傳入的關鍵字參數

subfx實際上是調用基類Clip的fx方法來實現的,關於Clip的fx方法請參考《moviepy音視頻剪輯:moviepy中的剪輯基類Clip的屬性和方法詳解》。

3.6、fl_image方法

fl_image方法是對get_frame方法獲取的幀進行變換的方法,本質上是《moviepy音視頻剪輯:moviepy中的剪輯基類Clip詳解》介紹的fl方法在內容變換方面的一種變種。

調用語法:fl_image(self, image_func, apply_to=None)
參數說明:
  • image_func:參數image_func是對剪輯幀進行圖像變換的函數,帶一個參數,參數就是要處理的幀,這個幀直接通過get_frame去獲取,image_func函數的返回值爲經過變換後的幀
  • apply_to:apply_to表示變換是否需要同時作用於剪輯的音頻和遮罩,其值可以爲’mask’、‘audio’、[‘mask’,‘audio’]

對比fl方法的調用方法fl(self, fun, apply_to=None, keep_duration=True):

  • fl_image由於只變換內容,因此不涉及時間的變換,keep_duration就是默認爲True
  • image_func不帶時間參數,這是因爲系統默認調用get_frame(t)來獲取幀,無需image_func帶時間參數
  • fl_image本質上是執行如下語句來完成幀內容的變換:fl(lambda gf, t: image_func(gf(t)), apply_to)
注意:

image_func參數對應的幀數組是隻讀的,不能修改,實際上get_frame(t)返回的所有幀數組都是隻讀的。幀的類型爲numpy.ndarray,而numpy.ndarray直接定義的數據是可修改的,爲什麼幀數據不能修改筆者暫時還沒弄明白(報錯ValueError: assignment destination is read-only),爲了規避該問題,將參數img數據採用如下形式的賦值語句:frame= np.array(img)就可以對新的變量frame進行修改,所有變換可以針對新變量frame進行,返回也必須是新變量frame。

3.7、fill_array方法

fill_array方法是用來進行多個視頻合成時處理幀的,更多是一個moviepy內部使用的方法,但當應用需要對幀進行變換時也可以調用。fill_array將pre_array的寬和高設置爲參數shape對應的數據。

調用語法:fill_array(self, pre_array, shape=(0, 0))
參數說明:
  • pre_array:要處理的數據,結構必須爲類似幀的三維數組,其對應的寬和高在pre_array.shape[0::1]內
  • shape:需要將 pre_array變換到的數組維度,shape實際上對應幀的新的寬和高
說明:

fill_array處理數據時,如果發現shape對應的寬或高大於pre_array本身的寬或高,則擴展pre_array的寬或高,擴展的位置使用[1,1,1]填充。如果shape對應的寬或高小於pre_array本身的寬或高,則對pre_array的寬或高超出的數據進行丟棄處理。

3.8、add_mask方法

add_mask方法就是給剪輯增加遮罩,遮罩的duration是調用者的duration,遮罩是由完全不透明(全1組成的YUV值)的像素構成。調用語法非常簡單:add_mask(self)

add_mask方法就是將給定剪輯完全遮擋,並返回被遮擋後的剪輯。

3.9、on_color方法

on_color方法用於將當前剪輯放置到一個指定顏色背景的可能更大的剪輯上,用於在原始剪輯擴展大小時將空白處設置爲指定顏色。返回值爲處理後的新剪輯。

調用語法如下:
on_color(self, size=None, color=(0, 0, 0), pos=None,   col_opacity=None)
參數說明:
  • size:是(寬度,高度)的二元組,如果沒有設置缺省爲調用剪輯的大小
  • color:設定的背景色RGB顏色組
  • pos:原剪輯對應的剪輯在新剪輯的框架上的位置,請見下面函數set_position的說明
  • col_opacity:以背景色構造的底部剪輯的不透明度,取值爲0到1的浮點數,如果爲0表示完全透明,爲1表示完全不透明,其他表示不透明度的比率。這個參數對新剪輯中原剪輯對應內容沒有作用,僅用於底部背景色構造的剪輯,下圖藍色邊框是透明度爲0.6時背景色案例

在這裏插入圖片描述

3.10、set_make_frame方法

set_make_frame方法用於設置剪輯幀構建的make_frame方法,make_frame方法在get_frame中被調用來返回指定位置的幀內容。set_make_frame方法非常簡單,調用語法如下:set_make_frame(self, mf),參數mf爲剪輯幀的構建方法名,除self外,帶一個t參數。

注意:
  • set_make_frame方法在父類Clip中也有,在此重寫除了實現父類相同的功能外,同時在設置make_frame方法,馬上會調用get_frame更新剪輯的size屬性
  • 修改make_frame改動的不是原剪輯,而是返回一個設置了make_frame方法的原剪輯的拷貝對應的新剪輯,這是moviepy幾乎所有設置方法的特點,一定要用返回的新剪輯覆蓋到操作的剪輯變量!不過開發團隊也準備在後續版本中進行改變,但至少到現在最新的1.03版本這點是沒有變化的。

3.11、set_audio方法

set_audio方法將原剪輯的拷貝剪輯的音頻設置爲參數指定音頻後返回新剪輯。調用語法:set_audio(self, audioclip)

3.12、set_mask方法

set_mask方法將原剪輯的拷貝剪輯的遮罩設置爲參數指定剪輯後返回新剪輯。調用語法:set_mask(self, mask),參數mask是調用對象用於遮罩的剪輯。

3.13、set_opacity方法

set_opacity方法將原剪輯拷貝剪輯遮罩的每個元素的值與參數值相乘後返回,實際上就是調整遮罩剪輯幀的YUV值。調用語法:set_opacity(self, op),其中參數op表示透明度或不透明度,爲任何浮點數,一般設置爲【0,1】區間的一個值。

3.14、set_position方法

set_position方法用於多個剪輯合成一個剪輯時設置調用剪輯實例的拷貝在合成剪輯的位置。

調用語法:

set_position(self, pos, relative=False)

參數說明:
  • pos:剪輯需要放置的位置,可以是如下方式取值:

  • (x,y):x,y用於指定剪輯左上角在合成剪輯的座標位置

  • (“center”,“top”):設定水平居中,垂直位置到頂部,類似的設置還有’bottom’、‘right’、‘left’

  • (factorX,factorY):基於剪輯的大小設置相對位置, factorX和factorY爲(0,1)之間的浮點數,計算位置時是以factorX乘以剪輯的寬,factorY乘以剪輯的高來計算位置,這裏剪輯的寬和高是老猿認爲應該是最終生成剪輯的寬和高

  • x和y的=的值可以是前三種的組合,x和y可以用不同的方式來設置

  • f(t)->(x,y):爲一個通過時間計算該時刻指定剪輯左上角在合成剪輯的座標位置

  • relative:是否相對位置,如果pos使用factorX或factorY時,relative需要設置爲True

3.15、to_ImageClip方法

to_ImageClip方法將剪輯對應時刻t的幀轉換成ImageClip圖像剪輯,圖像剪輯是所有幀都是固定圖像數據的剪輯,所有幀都對應爲圖像數據。

調用語法:

to_ImageClip(self, t=0, with_mask=True, duration=None)

說明:

參數非常簡單,不單獨解釋,但注意圖像剪輯在輸出到文件時需要設置duration和fps值(爲1即可),同時可能在輸出文時要指定codec類型,否則可能播放失敗。

3.16、to_mask方法

to_mask方法返回一個由調用者剪輯實例構建的遮罩剪輯。

調用語法:

to_mask(self, canal=0)

說明:

to_mask方法用於將當前剪輯生成一個遮罩剪輯,處理時如果調用對象本身有遮罩,則直接返回調用剪輯的遮罩,否則根據調用剪輯的數據生成遮罩數據,生成時是將調用剪輯的每一幀數據的具體像素的YUV值中的某個除以255來實現遮罩的效果,具體對YUV哪個數據進行處理由參數canal指定,0代碼Y值、1代表U值、2代表V值。

3.17、to_RGB方法

返回一個由遮罩剪輯生成的非遮罩剪輯。

調用語法:

to_RGB(self)

說明:

該方法的處理過程是,如果調用剪輯不是遮罩,則直接返回自身,否則將剪輯的幀像素YUV各乘以255,再將每個像素的YUV三元組變成一個九元組,其元素是YUV值重複3遍。

這樣變換的原因老猿並不十分清楚,查閱了一些資料,估計是因爲YUV到RGB並不是簡單YUV到RGB的一個轉換,而是到24位真彩色的轉換,因爲一般來說直接採集到的視頻數據是RGB24的格式,其位數是YUV的三倍,當RGB24變爲YUV時其實是進行了降色處理,現在要恢復到RGB24因此需要進行乘以3。

但這裏有些原理沒說清楚,比如RGB24是用三個字節來表示顏色,YUV在這裏也用了三個字節,RGB爲什麼變成了9個字節?這個問題一時無解,先留着。

另外這個方法在moviepy中只是對遮罩進行處理,當帶遮罩的剪輯輸出到文件或將剪輯的幀保存到圖像或gif文件時會調用該方法對剪輯的遮罩進行處理。

3.18、without_audio方法

without_audio方法就是將剪輯拷貝後的聲音去除,除了self不帶其他參數,返回一個去除了聲音的新剪輯。

3.19、afx方法

afx方法對原剪輯淺拷貝後的拷貝剪輯的聲音進行變換,返回新剪輯。

調用語法:

afx(self, fun, *a, **k)

說明:
  • 聲音變換由函數fun進行
  • a和k是fun變換函數需要帶的可變參數和關鍵字參數
  • afx實際上是調用父類Clip的fx方法去執行fun函數的

四、小結

本文詳細介紹了視頻剪輯基類VideoClip的構造方法、屬性和相關處理方法,相關內容參考了moviepy.video.VideoClip.py的文檔字符串以及源代碼,並針對部分疑難點進行了資料查詢和測試,相關內容的探索和寫作斷斷續續持續了一個多星期(_,爲了彌補損失,同時爲了將相關探索內容更快傳播,將一些重要知識點單獨成文發佈了),作爲一個類對象的介紹來說已經比較全面了。

VideoClip很多方法如save_frame、write_videofile、write_images_sequence、write_gif可以用於輸出視頻中的對應數據,而subfx、fl_image、add_mask、on_color、set_opacity等是進行視頻變換的重要方法。

在文中對部分方法舉例進行了運用,但在哪些場景怎麼去使用這些方法沒有系統介紹,將在後面關於運用場景的文章中進行部分方法使用的介紹。

更多moviepy的介紹請參考《PyQt+moviepy音視頻剪輯實戰文章目錄》或《專欄:使用PyQt開發圖形界面Python應用》。

廣告

老猿關於PyQt的付費專欄《使用PyQt開發圖形界面Python應用》只需要9.9元,本專欄《PyQt+moviepy音視頻剪輯實戰》文檔的同樣內容在付費專欄上也有相應內容,總體來說付費專欄介紹更詳細或案例更多。

本節內容對應付費專欄的《moviepy音視頻剪輯:視頻剪輯基類VideoClip詳解》。如果有興趣也願意支持老猿的讀者,歡迎購買付費專欄。

跟老猿學Python、學5G!

☞ ░ 前往老猿Python博文目錄

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章