? ? 前往老猿Python博文目錄 https://blog.csdn.net/LaoYuanPython ?
一、引言
在這個短視頻和自媒體大行其道的年代,音視頻剪輯成為了大佬們的必備工具,現在有很多音視頻剪輯的軟體,如剪映、Camtasia、愛拍剪輯、Adobe Premiere、Final Cut Pro、Vegas、快剪輯、愛剪輯、會聲會影等,大部分都好用,收費和免費的都有,
但某些情況下,用這些 GUI 的剪輯軟體有時不怎么方便,如:
-
批量處理一批短視頻(類似增加片頭、片尾或 Logo 等同質性作業)、要將一批圖片按照一定規則配音組織成視頻等,如果還用現成的 GUI工具,不但枯燥無味,浪費時間,而且批量一個個處理下來不一定都非常精確(如在剪輯尾部 3 秒增加 Logo 標記或語音)
-
基于某些目的進行視頻的個性化定制處理,如基于視頻的畫面進行直方圖均衡變換的灰度調整
這些情況下使用 GUI 工具進行處理會比較麻煩甚至無法支持,最希望的是能自己通過代碼或腳本快速定制任務處理,將這些枯燥繁雜的作業快速準確的完成處理,這個時候 Python 的 Moviepy 庫就可以大有可為了,下面老猿就為大家介紹一下 Moviepy 進行音視頻剪輯的能力,
二、Moviepy 簡介
MoviePy 是一個用于視頻編輯的 Python 模塊,可用于進行視頻的基本操作(如剪切、拼接、標題插入)、視頻合成(也稱非線性編輯)、視頻處理或創建高級效果,
它可以讀寫最常見的視頻格式,MoviePy 能處理的視頻是 ffmpeg 格式的,老猿理解支持的檔案型別至少包括:*.mp4 *.wmv *.rm *.avi *.flv *.webm *.wav *.rmvb 等 ,
MoviePy 使用 ffmpeg 讀取、匯出視頻和音頻檔案,使用 ImageMagick 生成文本和輸出 GIF 檔案,Python 的快速數字庫 Numpy 保證了不同媒體的處理,高級效果和增強使用了 Python 的許多影像處理庫(PIL、Scikit-image、scipy 等),
moviepy 的核心物件是剪輯(clips),包括 AudioClips 和 VideoClips,它們可以修改(剪切、減速、變暗…)或與剪輯混合以形成新剪輯,可以使用 PyGame 或 IPython Notebook 預覽,并可以輸出到對應型別的檔案(如 MP4、GIF、 MP3 等),例如,VideoClips 可以從視頻檔案、影像、文本或自定義影片創建,VideoClips 可以有一個音頻軌道(這是一個 AudioClip)和一個 mask 遮罩(一個特殊的 VideoClip,指示當剪輯與其他剪輯混合時要隱藏哪些部分),
三、Moviepy 安裝
目前 moviepy 庫最新版本是 1.0.3,安裝非常簡單,使用 pip 安裝時,請將站點指向國內的鏡像站點,否則下載很慢或者下載不下來,老猿使用清華的鏡像,指令是:
pip install -i https://pypi.tuna.tsinghua.edu.cn/simple moviepy
注意:
1、moviepy 全小寫,安裝時會自動安裝相關依賴包;
2、建議安裝最新的版本 1.0.3,因為 1.0.2 中有個比較大的 bug;
3、如果沒有安裝最新版本,可以執行版本升級,指令:
pip install -i https://pypi.tuna.tsinghua.edu.cn/simple moviepy --upgrade
四、音視頻的加載和保存
一般音視頻都是從檔案讀入的,視頻檔案的裝載使用類 VideoFileClip 的構造方法,音頻檔案的裝載使用類 AudioFileClip 的構造方法,兩者都可以帶多個引數,但最簡單的呼叫方法就是傳入一個檔案名作為引數呼叫即可,
視頻可以輸出成其他格式視頻、GIF 影片、一系列圖片,對應輸出函式分別為 write_videofile、write_gif、write_images_sequence,可以只帶一個輸出檔案名引數,
注意:輸出方法是 VideoFileClip 的父類 VideoClip 的方法,
另外視頻檔案通過屬性 audio 獲取視頻的音頻,音頻可以使用 write_audiofile 輸出成其他格式音頻,該方法是 AudioFileClip 的父類 AudioClip 的方法,
當音頻或視頻輸出需要轉換格式時,注意一定要帶 codec 引數,
下面代碼加載一個視頻和一個音頻,然后輸出成各種檔案:
from moviepy.editor import *
clipA = AudioFileClip(r"F:\video\fansNote.mp3")
clipV = VideoFileClip(r"F:\video\rahdms.mp4")
clipV.write_videofile(r"F:\video\temp\rahdmsBak.avi",codec='png') #視頻轉成avi格式輸出
clipV.audio.write_audiofile(r"F:\video\temp\rahdms.wav", codec='pcm_s16le') #視頻中的音頻轉成wav格式輸出
clipV.write_gif(r"F:\video\temp\rahdms.gif") #視頻輸出成gif檔案
clipV.write_images_sequence(r"F:\video\temp\fansNote%02d.jpg",0.5) #視頻輸出成圖片,0.5表示2秒輸出一張圖片
clipA.write_audiofile(r"F:\video\temp\fansNoteBak.mp3") #音頻輸出到其他檔案
五、音視頻資料的訪問
音視頻剪輯在 Moviepy 中為 AudioClip、VideoClip 物件,對音視頻剪輯資料的訪問主要是通過 AudioClip、VideoClip 的父類 Clip 的相關屬性進行的:
- 剪輯時長 duration
- 剪輯幀率 fps
- 訪問指定時刻位置的視頻幀或音頻幀的 get_frame 方法,語法:get_frame(self, t)
- 調整剪輯時長的 set_duration 方法,語法:set_duration(self, t, change_end=True)
- 調整剪輯幀率的 set_fps 方法,語法:set_fps(self, fps)
- 獲取剪輯的部分范圍的子剪輯的 subclip 方法,語法:subclip(self, t_start=0, t_end=None)
注意 subclip 方法用于從呼叫剪輯中取指定的剪輯段構造一個新剪輯物件回傳,原剪輯保持不變,
下面代碼加載一個視頻和一個音頻,然后輸出剪輯的時長和幀率,并取兩個剪輯的前 2 秒輸出到對應檔案:
from moviepy.editor import *
clipA = AudioFileClip(r"F:\video\fansNote.mp3")
clipV = VideoFileClip(r"F:\video\rahdms.mp4").subclip(0, 4)
print(f"視頻剪輯時長以及幀率為:{clipV.duration}、{clipV.fps}")
print(f"音頻剪輯時長以及幀率為:{clipA.duration}、{clipA.fps}")
clipV.subclip(0, 2).write_videofile(r"F:\video\temp\rahdms.avi",codec='png') #視頻前2秒轉成avi格式輸出
clipA.subclip(0, 2).write_audiofile(r"F:\video\temp\fansNote.wav", codec='pcm_s16le') #音頻前2秒轉成wav格式輸出
六、音視頻變換
音視頻的變換老猿將其分為 4 類,包括顏色變換、時間線變換、大小變換、內容變換,所有變換都是基于 Clip 類的 fl 方法來進行的,其他方法最終都要呼叫 fl 方法來完成剪輯變換,不過在 Clip 類內還提供了時間線的變換方法 fl_time,這是因為對音頻和視頻都可以基于時間線進行變換,
1、Clip 的 fl 方法
- fl 方法是一個通用的剪輯處理方法,它回傳一個新剪輯,新剪輯的所有幀是當前呼叫剪輯物件的幀經過函式 fun 變換處理后的幀
- 呼叫語法:fl(self, fun, apply_to=None, keep_duration=True)
- 示例代碼:
下面的代碼將一個 h 像素高剪輯的視頻內容幀的下半部部分剪輯掉,newclip 剪輯的高度變為 h/2,
src = VideoFileClip(r"F:\video\抖音-愛拼才會贏.mp4")
h = src.size[1]
fl = lambda gf,t : gf(t)[int(t):int(t)+h/2, :]
newclip = src.fl(fl, apply_to='mask')
newclip.write_videofile(r"F:\video\抖音-愛拼才會贏_re.mp4"
2、Clip 的 fl_time 方法
- fl_time 方法是基于時間線的變換,變換回傳一個新剪輯,新剪輯是呼叫剪輯的一個淺拷貝,但新剪輯的時間線被調整,實際上這個方法就是對剪輯進行一個基于時間特效的處理,如快播、慢播、倒序播放等
- 呼叫語法:fl_time(self, t_func, apply_to=None, keep_duration=False)
- 示例代碼:
下面的代碼將剪輯變成原剪輯的 n 倍速:
clipVideo = VideoFileClip(r"F:\video\WinBasedWorkHard_src.mp4")
end = clipVideo.end
newclip = clipVideo.fl_time(lambda t: t*n, apply_to=['mask','audio'])
3、剪輯顏色變換
剪輯的顏色或亮度變換函式包括:
-
blackwhite 將彩色視頻變成灰度視頻,語法:blackwhite(clip, RGB = None,
preserve_luminosity=True) -
colorx 將剪輯中每個幀的每個像素的 RGB 值與引數 factor 相乘,使得明度增大(引數 factor 大于 1)或降低(引數factor 小于 1),語法:colorx(clip, factor)
-
fadein 使剪輯在開始播放后的指定時間內從某種顏色(默認為黑色)逐漸顯示出來,語法:fadein(clip, duration, initial_color=None)
-
fadeout 函式使剪輯在剪輯快結束前的指定時間內逐漸淡隱于某種顏色(默認為黑色),語法:fadeout(clip, duration, final_color=None)
-
invert_colors 將像素對應顏色進行反轉,語法:invert_colors(clip)
-
um_contrast 用于對剪輯的亮度對比度(luminosity-contrast )進行校正,語法:lum_contrast(clip, lum = 0, contrast=0, contrast_thr=127)
-
gamma_corr 用于對螢屏影像的色彩進行 gamma 修正,語法: gamma_corr(clip, gamma)
部分示例代碼:
下面的代碼是對視頻剪輯加載后,將其明度乘以 2 和除以 2 分別生成 2 個新剪輯:
from moviepy.editor import *
clipVideo1 = VideoFileClip(r"F:\video\yyzg.mp4")
clipVideo2 = clipVideo1.fx(vfx.colorx, 2)
clipVideo1 = clipVideo1.fx(vfx.colorx, 0.5)
下面代碼在剪輯首尾各設了 5 秒的淡入和淡出時間并輸出變更后的新剪輯:
from moviepy.editor import *
clipVideo = VideoFileClip(r"F:\video\WinBasedWorkHard_src.mp4").fx(vfx.fadein,5,(0,0,255)).fx(vfx.fadeout,5,(0,0,0))
clipVideo.write_videofile(r"F:\video\fadeinout.mp4", threads=8)
3、剪輯大小變換
剪輯大小變換函式包括:
- crop 函式從剪輯中獲取一個矩形區域的剪輯內容作為新的剪輯,語法:crop( clip, x1=None, y1=None, x2=None, y2=None, width=None, height=None, x_center=None, y_center=None)
- margin 函式在剪輯的四周增加一個外邊框,語法:margin(clip, mar=None, left=0, right=0, top=0, bottom=0, color=(0, 0, 0), opacity = 1.0)
- resize 函式用于調整剪輯的大小,包括縮小或放大,語法:resize(clip, newsize=None, height=None, width=None, apply_to_mask=True)
示例代碼:
下面的代碼將剪輯的 260 行像素以上的部分去除,值保留 260 行以下的像素內容對應的視頻,并將新剪輯增加一個 3 個像素的藍色邊框:
from moviepy.editor import *
clipVideo = VideoFileClip(r"F:\video\WinBasedWorkHard_src.mp4").fx(vfx.crop,0,260)
clipVideo = clipVideo.fx(vfx.margin, 3, color=(0, 0, 255), opacity=0.5)
clipVideo.write_videofile(r"F:\video\crop.mp4")
4、剪輯內容變換
剪輯內容變換函式包括:
- headblur 函式將剪輯指定位置內容打馬賽克,語法:headblur(clip,fx,fy,r_zone,r_blur=None)
- mask_and 函式用于將兩個遮罩剪輯的所有像素的 RGB 值各取最小值作為新剪輯的像素 RGB 值,語法:mask_and(clip, other_clip)
- mask_or 函式與 mask_and 相對應,用于將兩個遮罩剪輯的所有像素的 RGB 值各取最大值作為新剪輯的像素 RGB 值,語法:mask_or(clip, other_clip)
- mirror_x 函式分別將剪輯內容左右顛倒,語法:mirror_x(clip, apply_to=“mask”)
- mirror_y 函式分別將剪輯內容上下顛倒,語法:mirror_y(clip, apply_to=“mask”)
- rotate 函式用于將剪輯逆時針旋轉指定的角度或弧度語法:rotate(clip, angle, unit=“deg”, resample=“bicubic”, expand=True)
- scroll 函式是實作在螢屏上水平或垂直滾動播放剪輯的內容,語法:scroll(clip, w=None, h=None, x_speed=0, y_speed=0, x_start=0, y_start=0, apply_to=“mask”)
- supersample 函式回傳一個新剪輯,新剪輯每個幀的像素值被替換為該幀前后時段范圍內的多個等間距幀的算術平均值,語法:supersample(clip, d, nframes)
部分示例代碼:
下面的代碼實作視頻左右顛倒和上下顛倒:
from moviepy.editor import *
clip = VideoFileClip(r"F:\video\WinBasedWorkHard_src.mp4").crop(0, 300, 540, 660).subclip(0,15)
newclip1 = clip.fx(vfx.mirror_x)
newclip2 = clip.fx(vfx.mirror_y)
newclip1.write_videofile(r"F:\video\WinBasedWorkHard_mirrorx.mp4", threads=8)
newclip2.write_videofile(r"F:\video\WinBasedWorkHard_mirrory.mp4", threads=8)
下面的案例隨時間線變換將視頻內容旋轉不同的角度,且將剪輯的的高和寬度調整為原剪輯對角線的大小,剪輯的畫面內容不會丟失,旋轉角度由 angleF 函式確認:
from moviepy.editor import *
def angleF(t):
ret = (10*int(t))%360
return ret*-1
if __name__=='__main__':
clip = VideoFileClip(r"F:\video\WinBasedWorkHard_src.mp4",audio=False).crop(0, 300, 540, 840)
newclip = clip.rotate(angleF,expand=True).fx(vfx.resize,(764,764))
七、剪輯合成
1、概述
音視頻除了變換和取剪輯片段以外,還可以創造新剪輯,相關方法包括:
- 將多個剪輯進行拼接或嵌入成同屏播放的新剪輯
- 從圖片檔案生成剪輯
- 生成一個指定顏色作為背景的剪輯
- 自己構造資料生成剪輯
2、將多個剪輯拼接
視頻的拼接使用方法 concatenate_videoclips,呼叫語法:
concatenate_videoclips(clips, method="chain", transition=None, bg_color=None, ismask=False, padding = 0)
其中 clips 為需要拼接的多個視頻,
下面的案例代碼將三個視頻連接成一個視頻:
from moviepy.editor import *
fileList = ['F:\\video\\1.mp4', 'F:\\video\\2.mp4','F:\\video\\3.mp4']
tmpClip = []
for fileName in fileList:
clip = VideoFileClip(fileName)
tmpClip.append(clip)
destClip = concatenate_videoclips(tmpClip)
destClip.write_videofile("F:\\video\\dest.mp4")
3、多個剪輯同屏播放
同屏播放視頻需要使用 clips_array 函式,呼叫語法如下:
clips_array(array, rows_widths=None, cols_widths=None, bg_color = None)
引數array為視頻剪輯陣列,
下面的案例代碼將 tmpClip 保存的多個視頻連接成一個同屏播放視頻,其中 lines、columns 表示一個螢屏分成幾行每行幾個視頻:
from moviepy.editor import *
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)
4、將一系列影像構造成視頻
前面第三部分介紹的 write_images_sequence 方法用于將剪輯輸出到一系列影像檔案中,而 ImageSequenceClip 則基本上與 write_images_sequence 程序可逆,用于將一系列影像生成剪輯,
ImageSequenceClip 是 VideoClip 的直接子類,其構造方法語法為:
__init__(self, sequence, fps=None, durations=None, with_mask=True, ismask=False, load_images=False)
下面代碼將 F:\temp\img 目錄下的所有同樣大小的影像合成一個每秒播放一個影像的剪輯:
imsClip = ImageSequenceClip(r"F:\temp\img",fps=1)
imsClip.write_videofile(r"F:\video\imgs.mp4", threads=threads)
5、其他幾種生成視頻方法簡介
- ImageClip 是 VideoClip 的直接子類,用于生成固定不變的視頻剪輯,ImageClip
是從一個影像檔案或記憶體中影像陣列資料生成的視頻剪輯,對應視頻任何時候都是顯示該影像
DataVideoClip 是 VideoClip 的直接子類,它的視頻剪輯的連續幀都是從一系列資料集經過函式處理生成的,因此 DataVideoClip 其實就是通過資料集經函式處理構造的視頻剪輯
ColorClip 是僅顯示同一種顏色的剪輯
TextClip 用于生成文本剪輯,對應剪輯內容來自于指定文本或文本檔案
部分示例代碼:
生成一副紅色背景的靜態視頻:
colClip = ColorClip((360,360),color = (255,0,0),ismask=False,duration=5).set_fps(1)
colClip.write_videofile(r"F:\video\red.mp4", codec='mpeg4')
生成一文字構成的視頻:
fps = 3
inf = r"text clip test"
txtclip = TextClip(inf ,font='Courier',fontsize=36,color='red',bg_color='white',transparent=True,tempfilename=r'F:\temp\img\txtjpg.png',remove_temp=False).set_duration(15).set_fps(3)
txtclip.write_videofile(r"F:\video\text.avi", codec='rawvideo', threads=threads)
八、小結
本文介紹了 Python Moviepy 音視頻剪輯庫的安裝、主要功能以及部分示例代碼,可以看到 Moviepy 能從檔案或音視頻流中裝載音視頻剪輯,并對裝載的音視頻剪輯進行各種變換和合成,代碼開發簡單易懂,很容易掌握,感興趣的朋友不妨嘗試一下,
更多關于 Moviepy 的介紹請大家參考《Python音視頻剪輯庫MoviePy1.0.3中文教程導覽及可執行工具下載》,
如對文章內容存在疑問或需要相關資料,可在博客評論區留言,或關注:老猿Python 微信公號發訊息咨詢,可通過掃二維碼加微信公眾號,

寫博不易,敬請支持:
如果閱讀本文于您有所獲,敬請點贊、評論、收藏,謝謝大家的支持!
關于老猿的付費專欄
- 付費專欄《https://blog.csdn.net/laoyuanpython/category_9607725.html 使用PyQt開發圖形界面Python應用》專門介紹基于Python的PyQt圖形界面開發基礎教程,對應文章目錄為《 https://blog.csdn.net/LaoYuanPython/article/details/107580932 使用PyQt開發圖形界面Python應用專欄目錄》;
- 付費專欄《https://blog.csdn.net/laoyuanpython/category_10232926.html moviepy音視頻開發專欄 )詳細介紹moviepy音視頻剪輯合成處理的類相關方法及使用相關方法進行相關剪輯合成場景的處理,對應文章目錄為《https://blog.csdn.net/LaoYuanPython/article/details/107574583 moviepy音視頻開發專欄文章目錄》;
- 付費專欄《https://blog.csdn.net/laoyuanpython/category_10581071.html OpenCV-Python初學者疑難問題集》為《https://blog.csdn.net/laoyuanpython/category_9979286.html OpenCV-Python圖形影像處理 》的伴生專欄,是筆者對OpenCV-Python圖形影像處理學習中遇到的一些問題個人感悟的整合,相關資料基本上都是老猿反復研究的成果,有助于OpenCV-Python初學者比較深入地理解OpenCV,對應文章目錄為《https://blog.csdn.net/LaoYuanPython/article/details/109713407 OpenCV-Python初學者疑難問題集專欄目錄 》
- 付費專欄《https://blog.csdn.net/laoyuanpython/category_10762553.html Python爬蟲入門 》站在一個互聯網前端開發小白的角度介紹爬蟲開發應知應會內容,包括爬蟲入門的基礎知識,以及爬取CSDN文章資訊、博主資訊、給文章點贊、評論等實戰內容,
前兩個專欄都適合有一定Python基礎但無相關知識的小白讀者學習,第三個專欄請大家結合《https://blog.csdn.net/laoyuanpython/category_9979286.html OpenCV-Python圖形影像處理 》的學習使用,
對于缺乏Python基礎的同仁,可以通過老猿的免費專欄《https://blog.csdn.net/laoyuanpython/category_9831699.html 專欄:Python基礎教程目錄)從零開始學習Python,
如果有興趣也愿意支持老猿的讀者,歡迎購買付費專欄,
老猿Python,跟老猿學Python!
? ? 前往老猿Python博文目錄 https://blog.csdn.net/LaoYuanPython ?
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/301043.html
標籤:python
上一篇:python二級大題總結
