moviepy音視頻剪輯:多個視頻合成一個視頻

一、視頻合成概述

視頻合成,也稱爲非線性編輯,實際上是在一個新剪輯中播放幾個剪輯。

請注意視頻剪輯通常帶有音頻和遮罩(放到視頻軌道上的圖片視頻音樂我們通常都稱爲素材,遮罩作用於素材上,用來遮擋或顯示素材的部分內容。通常黑白相間的圖片或者視頻都可以作爲遮罩使用,遮罩白色部分顯示素材內容,遮罩黑色部分遮擋消除素材內容),它們也是剪輯。當您將這些剪輯組合在一起時,通過將剪輯的原聲和遮罩組合在一起,將自動生成最終剪輯的原聲和遮罩。所以大多數時候你不需要擔心混音和麪具。

兩種簡單的剪輯合成方法是將它們拼接起來(在一個長剪輯中一個接一個地播放它們)或將它們堆疊起來(在一個大剪輯中並排播放)。

二、視頻的拼接

2.1、拼接方法和語法

視頻的拼接使用方法concatenate_videoclips,調用語法:

concatenate_videoclips(clips, method="chain", transition=None, bg_color=None, ismask=False, padding = 0)
語法釋義:
  • clips:多個視頻剪輯的列表,列表中的每個元素都是VideoFileClip類型的對象
  • method:拼接方法,有2種取值
  1. “chain”:生成一個簡單輸出多個剪輯連續幀的剪輯,不論這些剪輯是否相同大小(分辨率)都不進行修正。如果參數列表中的剪輯都沒有遮罩,則最終拼接的剪輯也沒有遮罩,否則最終剪輯的遮罩就是所有參數剪輯遮罩的拼接,如果對應參數指定剪輯沒有遮罩則使用完全不透明的剪輯作爲遮罩。如果參數對應的多個剪輯有不同大小又想將拼接剪輯直接輸出到文件,需要使用“compose”方法
  2. “compose”:如果參數對應的剪輯不具有相同分辨率,最終分辨率將是使所有剪輯都不必調整大小的分辨率。因此,最終剪輯具有參數列表中最高剪輯的高度和最寬剪輯的寬度。所有尺寸較小的剪輯將顯示爲居中。如果mask=True,則邊界爲透明,否則爲由“bg-color”指定的顏色。所有輸入剪輯的最高FPS爲最終連接剪輯的FPS
  • transition: transition指定一個將在列表的每兩個剪輯之間播放的剪輯 ,即結果剪輯不但會將參數對應剪輯拼接,而且會在兩個剪輯拼接中間插入一個由transition指定的過場剪輯
  • bg_color:僅在method="compose"時使用,設置背景色,如果要一個透明剪輯,則設置爲None,否則爲一個代表RGB顏色的三元組,如(0,0,0)代表黑色,也即透明色
  • padding:僅在method=“compose"時使用,兩個連續剪輯間的間隔時間,注意如果該參數爲賦值,後面的剪輯和前一剪輯的播放有一段時間重疊,這種負數的padding參數,會製造出後一個剪輯逐漸變暗退出的效果。一個非0的padding值會自動將method置爲"compose”
  • 返回值:最終拼接的剪輯

2.2、案例

fileList = ['F:\\video\\1.mp4', 'F:\\video\\2.mp4','F:\\video\\3.mp4']
tmpClip = []
for fileName in fileList:
    print(f"準備加載視頻文件:{fileName} ")
    clip = mpe.VideoFileClip(fileName)
    print(f"加載視頻文件:{fileName} 完成,時長爲{clip.duration}秒 ")
    tmpClip.append(clip)
    print(f"視頻文件:{fileName} 已經加載並緩存")

print("進行內存視頻拼接...")
destClip = mpe.concatenate_videoclips(tmpClip)
print("內存視頻拼接完成,準備輸出到文件.")
destClip.write_videofile("F:\\video\\dest.mp4")
print("輸出到文成功!")

2.3、兩種拼接方法的使用

經實際驗證,“chain”方法確實可以將不同分辨率的視頻拼接起來,但在播放時,很可能除了與第一個視頻分辨率相同的視頻能正常播放外,其他視頻播放可能出現花屏或扭曲,無法正常觀看。對這種情況有兩種處理方式:

  1. 對於不同視頻分辨率的視頻進行拼接時使用“compose”方法,compose方法會自動調整視頻的分辨率(取所有視頻的最大寬度和最高高度作爲新分辨率)以確保所有視頻都能正常播放,只是播放時,原視頻的實際分辨率小於調整後的分辨率的,屏幕上會有留白空間,這些留白空間可以通過bg_color來設定顯示的顏色;
  2. 通過代碼調整源視頻的分辨率,使得所有源視頻加載後變成相同的分辨率,這樣拼接時就是相同分辨率了。源視頻加載後調整成相同分辨率的方法包括兩種,一種是加載後,針對視頻剪輯調用VideoFileClip的resize方法,另外一種是使用VideoFileClip的構造方法時,使用參數target_resolution指定加載視頻同時需要調整到的分辨率(請參考《moviepy音視頻剪輯:使用VideoFileClip、AudioFileClip和write_videofile、write_audiofile進行音視頻的加載和輸出》)。注意這兩個方法的參數可以都是視頻需要設置的分辨率,但兩者的分辨率的寬和高的位置在列表中是相反的。

三、視頻的堆疊(同屏顯示)

3.1、語法

視頻的堆疊使用了的clips_array函數,調用語法如下:

clips_array(array, rows_widths=None, cols_widths=None, bg_color = None)
參數說明:
  • array:用於存放剪輯的二維列表,每個列表的元素都是一個列表,每個元素的列表代表在屏幕上同行顯示的多個剪輯,一維列表中有多少個元素就表示在屏幕上顯示多少行,每行視頻有多個視頻並列。
  • rows_widths:不同行的像素寬度,如果設置爲None則自動設置
  • cols_widths:不同列的像素寬度,如果設置爲None則自動設置
  • bg_color:爲蒙版和未蒙版區域填充顏色。這些設置爲None,這些區域將透明,處理速度會慢一些
  • 返回值:合成後的剪輯

3.2、樣例

print(f"視頻將排列成{lines}行{columns}列")
clipArrays = []
tmpClipArray = []
column = 0
for clip in tmpClip:
    tmpClipArray.append(clip)
    column += 1
    if column == columns:
        clipArrays.append(tmpClipArray)
        column = 0
        tmpClipArray = []
destClip = mpe.clips_array(clipArrays)

跟老猿學Python、學5G!

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