Python 音視頻剪輯快速入門教程
一、引言
在這個短視頻和自媒體大行其道的年代,音視頻剪輯成為了大佬們的必備工具,現(xiàn)在有很多音視頻剪輯的軟件,如剪映、Camtasia、愛拍剪輯、Adobe Premiere、Final Cut Pro、Vegas、快剪輯、愛剪輯、會聲會影等,大部分都好用,收費和免費的都有。
但某些情況下,用這些 GUI 的剪輯軟件有時不怎么方便,如:
- 批量處理一批短視頻(類似增加片頭、片尾或 Logo 等同質(zhì)性工作)、要將一批圖片按照一定規(guī)則配音組織成視頻等,如果還用現(xiàn)成的 GUI工具,不但枯燥無味,浪費時間,而且批量一個個處理下來不一定都非常精確(如在剪輯尾部 3 秒增加 Logo 標記或語音)
- 基于某些目的進行視頻的個性化定制處理,如基于視頻的畫面進行直方圖均衡變換的灰度調(diào)整
這些情況下使用 GUI 工具進行處理會比較麻煩甚至無法支持,最希望的是能自己通過代碼或腳本快速定制任務(wù)處理,將這些枯燥繁雜的工作快速準確的完成處理。這個時候 Python 的 Moviepy 庫就可以大有可為了,下面老猿就為大家介紹一下 Moviepy 進行音視頻剪輯的能力。
二、Moviepy 簡介
MoviePy 是一個用于視頻編輯的 Python 模塊,可用于進行視頻的基本操作(如剪切、拼接、標題插入)、視頻合成(也稱非線性編輯)、視頻處理或創(chuàng)建高級效果。
它可以讀寫最常見的視頻格式,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,指示當剪輯與其他剪輯混合時要隱藏哪些部分)。
三、Moviepy 安裝
目前 moviepy 庫最新版本是 1.0.3,安裝非常簡單,使用 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;
3、如果沒有安裝最新版本,可以執(zhí)行版本升級,指令:
pip install -i https://pypi.tuna.tsinghua.edu.cn/simple moviepy --upgrade
四、音視頻的加載和保存
一般音視頻都是從文件讀入的,視頻文件的裝載使用類 VideoFileClip 的構(gòu)造方法,音頻文件的裝載使用類 AudioFileClip 的構(gòu)造方法,兩者都可以帶多個參數(shù),但最簡單的調(diào)用方法就是傳入一個文件名作為參數(shù)調(diào)用即可。
視頻可以輸出成其他格式視頻、GIF 動畫、一系列圖片,對應(yīng)輸出函數(shù)分別為 write_videofile、write_gif、write_images_sequence,可以只帶一個輸出文件名參數(shù)。
注意:輸出方法是 VideoFileClip 的父類 VideoClip 的方法。
另外視頻文件通過屬性 audio 獲取視頻的音頻。音頻可以使用 write_audiofile 輸出成其他格式音頻,該方法是 AudioFileClip 的父類 AudioClip 的方法。
當音頻或視頻輸出需要轉(zhuǎn)換格式時,注意一定要帶 codec 參數(shù)。
下面代碼加載一個視頻和一個音頻,然后輸出成各種文件:
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') #視頻轉(zhuǎn)成avi格式輸出 clipV.audio.write_audiofile(r"F:\video\temp\rahdms.wav", codec='pcm_s16le') #視頻中的音頻轉(zhuǎn)成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") #音頻輸出到其他文件
五、音視頻數(shù)據(jù)的訪問
音視頻剪輯在 Moviepy 中為 AudioClip、VideoClip 對象,對音視頻剪輯數(shù)據(jù)的訪問主要是通過 AudioClip、VideoClip 的父類 Clip 的相關(guān)屬性進行的:
- 剪輯時長 duration
- 剪輯幀率 fps
- 訪問指定時刻位置的視頻幀或音頻幀的 get_frame 方法,語法:get_frame(self, t)
- 調(diào)整剪輯時長的 set_duration 方法,語法:set_duration(self, t, change_end=True)
- 調(diào)整剪輯幀率的 set_fps 方法,語法:set_fps(self, fps)
- 獲取剪輯的部分范圍的子剪輯的 subclip 方法,語法:subclip(self, t_start=0, t_end=None)
- 注意 subclip 方法用于從調(diào)用剪輯中取指定的剪輯段構(gòu)造一個新剪輯對象返回,原剪輯保持不變。
下面代碼加載一個視頻和一個音頻,然后輸出剪輯的時長和幀率,并取兩個剪輯的前 2 秒輸出到對應(yīng)文件:
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秒轉(zhuǎn)成avi格式輸出 clipA.subclip(0, 2).write_audiofile(r"F:\video\temp\fansNote.wav", codec='pcm_s16le') #音頻前2秒轉(zhuǎn)成wav格式輸出
六、音視頻變換
音視頻的變換老猿將其分為 4 類,包括顏色變換、時間線變換、大小變換、內(nèi)容變換。所有變換都是基于 Clip 類的 fl 方法來進行的,其他方法最終都要調(diào)用 fl 方法來完成剪輯變換。不過在 Clip 類內(nèi)還提供了時間線的變換方法 fl_time,這是因為對音頻和視頻都可以基于時間線進行變換。
1、Clip 的 fl 方法
- fl 方法是一個通用的剪輯處理方法,它返回一個新剪輯,新剪輯的所有幀是當前調(diào)用剪輯對象的幀經(jīng)過函數(shù) fun 變換處理后的幀
- 調(diào)用語法:fl(self, fun, apply_to=None, keep_duration=True)
- 示例代碼:
下面的代碼將一個 h 像素高剪輯的視頻內(nèi)容幀的下半部部分剪輯掉,newclip 剪輯的高度變?yōu)?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 方法是基于時間線的變換,變換返回一個新剪輯,新剪輯是調(diào)用剪輯的一個淺拷貝,但新剪輯的時間線被調(diào)整,實際上這個方法就是對剪輯進行一個基于時間特效的處理,如快播、慢播、倒序播放等
- 調(diào)用語法: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、剪輯顏色變換
剪輯的顏色或亮度變換函數(shù)包括:
- blackwhite 將彩色視頻變成灰度視頻,語法:blackwhite(clip, RGB = None,
- preserve_luminosity=True)
- colorx 將剪輯中每個幀的每個像素的 RGB 值與參數(shù) factor 相乘,使得明度增大(參數(shù) factor 大于 1)或降低(參數(shù)factor 小于 1),語法:colorx(clip, factor)
- fadein 使剪輯在開始播放后的指定時間內(nèi)從某種顏色(默認為黑色)逐漸顯示出來,語法:fadein(clip, duration, initial_color=None)
- fadeout 函數(shù)使剪輯在剪輯快結(jié)束前的指定時間內(nèi)逐漸淡隱于某種顏色(默認為黑色),語法:fadeout(clip, duration, final_color=None)
- invert_colors 將像素對應(yīng)顏色進行反轉(zhuǎn),語法: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)
下面代碼在剪輯首尾各設(shè)了 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)
4、剪輯大小變換
剪輯大小變換函數(shù)包括:
- crop 函數(shù)從剪輯中獲取一個矩形區(qū)域的剪輯內(nèi)容作為新的剪輯,語法:crop( clip, x1=None, y1=None, x2=None, y2=None, width=None, height=None, x_center=None, y_center=None)
- margin 函數(shù)在剪輯的四周增加一個外邊框,語法:margin(clip, mar=None, left=0, right=0, top=0, bottom=0, color=(0, 0, 0), opacity = 1.0)
- resize 函數(shù)用于調(diào)整剪輯的大小,包括縮小或放大,語法:resize(clip, newsize=None, height=None, width=None, apply_to_mask=True)
示例代碼:
下面的代碼將剪輯的 260 行像素以上的部分去除,值保留 260 行以下的像素內(nèi)容對應(yīng)的視頻,并將新剪輯增加一個 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")
5、剪輯內(nèi)容變換
剪輯內(nèi)容變換函數(shù)包括:
- headblur 函數(shù)將剪輯指定位置內(nèi)容打馬賽克,語法:headblur(clip,fx,fy,r_zone,r_blur=None)
- mask_and 函數(shù)用于將兩個遮罩剪輯的所有像素的 RGB 值各取最小值作為新剪輯的像素 RGB 值,語法:mask_and(clip, other_clip)
- mask_or 函數(shù)與 mask_and 相對應(yīng),用于將兩個遮罩剪輯的所有像素的 RGB 值各取最大值作為新剪輯的像素 RGB 值,語法:mask_or(clip, other_clip)
- mirror_x 函數(shù)分別將剪輯內(nèi)容左右顛倒,語法:mirror_x(clip, apply_to=“mask”)
- mirror_y 函數(shù)分別將剪輯內(nèi)容上下顛倒,語法:mirror_y(clip, apply_to=“mask”)
- rotate 函數(shù)用于將剪輯逆時針旋轉(zhuǎn)指定的角度或弧度語法:rotate(clip, angle, unit=“deg”, resample=“bicubic”, expand=True)
- scroll 函數(shù)是實現(xiàn)在屏幕上水平或垂直滾動播放剪輯的內(nèi)容,語法:scroll(clip, w=None, h=None, x_speed=0, y_speed=0, x_start=0, y_start=0, apply_to=“mask”)
- supersample 函數(shù)返回一個新剪輯,新剪輯每個幀的像素值被替換為該幀前后時段范圍內(nèi)的多個等間距幀的算術(shù)平均值,語法:supersample(clip, d, nframes)
部分示例代碼:
下面的代碼實現(xiàn)視頻左右顛倒和上下顛倒:
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)
下面的案例隨時間線變換將視頻內(nèi)容旋轉(zhuǎn)不同的角度,且將剪輯的的高和寬度調(diào)整為原剪輯對角線的大小,剪輯的畫面內(nèi)容不會丟失,旋轉(zhuǎn)角度由 angleF 函數(shù)確認:
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、概述
音視頻除了變換和取剪輯片段以外,還可以創(chuàng)造新剪輯,相關(guān)方法包括:
- 將多個剪輯進行拼接或嵌入成同屏播放的新剪輯
- 從圖片文件生成剪輯
- 生成一個指定顏色作為背景的剪輯
- 自己構(gòu)造數(shù)據(jù)生成剪輯
2、將多個剪輯拼接
視頻的拼接使用方法 concatenate_videoclips,調(diào)用語法:
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 函數(shù),調(diào)用語法如下:
clips_array(array, rows_widths=None, cols_widths=None, bg_color = None)
參數(shù)array為視頻剪輯數(shù)組。
下面的案例代碼將 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、將一系列圖像構(gòu)造成視頻
前面第三部分介紹的 write_images_sequence 方法用于將剪輯輸出到一系列圖像文件中,而 ImageSequenceClip 則基本上與 write_images_sequence 過程可逆,用于將一系列圖像生成剪輯。
ImageSequenceClip 是 VideoClip 的直接子類,其構(gòu)造方法語法為:
__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
是從一個圖像文件或內(nèi)存中圖像數(shù)組數(shù)據(jù)生成的視頻剪輯,對應(yīng)視頻任何時候都是顯示該圖像
DataVideoClip 是 VideoClip 的直接子類,它的視頻剪輯的連續(xù)幀都是從一系列數(shù)據(jù)集經(jīng)過函數(shù)處理生成的,因此 DataVideoClip 其實就是通過數(shù)據(jù)集經(jīng)函數(shù)處理構(gòu)造的視頻剪輯
ColorClip 是僅顯示同一種顏色的剪輯
TextClip 用于生成文本剪輯,對應(yīng)剪輯內(nèi)容來自于指定文本或文本文件
部分示例代碼:
生成一副紅色背景的靜態(tài)視頻:
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')
生成一文字構(gòu)成的視頻:
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)
八、小結(jié)
本文介紹了 Python Moviepy 音視頻剪輯庫的安裝、主要功能以及部分示例代碼,可以看到 Moviepy 能從文件或音視頻流中裝載音視頻剪輯,并對裝載的音視頻剪輯進行各種變換和合成,代碼開發(fā)簡單易懂,很容易掌握,感興趣的朋友不妨嘗試一下。
更多關(guān)于 Moviepy 的介紹請大家參考《Python音視頻剪輯庫MoviePy1.0.3中文教程導(dǎo)覽及可執(zhí)行工具下載》。
到此這篇關(guān)于用 Python 快速入門音視頻剪輯的文章就介紹到這了,更多相關(guān)Python音視頻剪輯內(nèi)容請搜索本站以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持本站!
版權(quán)聲明:本站文章來源標注為YINGSOO的內(nèi)容版權(quán)均為本站所有,歡迎引用、轉(zhuǎn)載,請保持原文完整并注明來源及原文鏈接。禁止復(fù)制或仿造本網(wǎng)站,禁止在非www.sddonglingsh.com所屬的服務(wù)器上建立鏡像,否則將依法追究法律責(zé)任。本站部分內(nèi)容來源于網(wǎng)友推薦、互聯(lián)網(wǎng)收集整理而來,僅供學(xué)習(xí)參考,不代表本站立場,如有內(nèi)容涉嫌侵權(quán),請聯(lián)系alex-e#qq.com處理。