Python視頻處理模塊之moviepy的用法教程
楔子
隨著自媒體時代,現(xiàn)在對視頻的處理變得越來越常見。我們可以使用 Adobe 的一些專業(yè)工具,但是效率不高;如果只是對視頻進行一些簡單的處理,或者視頻的數(shù)量非常多的話,那么使用專業(yè)軟件顯然就不太適合了。
而 Python 有一個專門用于處理視頻的第三方庫:moviepy,可以非常方便地對視頻進行一些簡單處理,下面我們就來看一看。
首先是安裝:
pip?install?moviepy?-i?https://pypi.tuna.tsinghua.edu.cn/simple
個人推薦安裝的時候使用清華源,因為moviepy需要依賴另一個庫:imageio_ffmpeg,這個庫里面包含了一個 50 多 MB 的 ffmpeg 二進制文件,如果網絡不行的話,直接從pypi上拉取會花很長時間。當然安裝moviepy的時候,imageio_ffmpeg 就順帶安裝了。
從這里我們也可以看到,moviepy 底層依賴 ffmpeg,而ffmpeg是跨平臺的,所以 moviepy 也可以在任意平臺上使用。
moviepy 的簡單使用
我們來看 moviepy 都提供了哪些功能,不過在使用之前我們需要一個視頻,就使用 you-get 工具從 bilibili 下載一個吧。

下面就使用這個下載的視頻進行演示。
視頻截取
如果一個視頻比較長,我們可以截取感興趣的片段。
from?moviepy?import?editor #?調用?`VideoFileClip(文件名)`?即可將視頻加載進來 #?并且支持不同的視頻格式,比如?flv、mp4?等等 video_clip?=?editor.VideoFileClip( ????"空城計,但是7Ki7Ki醬醬.mp4") #?調用subclip方法,傳入起始時間和結束時間 #?即可截取視頻中的指定部分 """ video_clip.subclip():? ???截取視頻全部,相當于沒做處理 video_clip.subclip(10):? ???從視頻的?`第10秒`?截取到?`結尾` video_clip.subclip(10,?-2):? ???從視頻的?`第10秒`?截取到結尾的?`前兩秒` video_clip.subclip((1,?35),?(3,?10)):? ???從視頻的?`第1分35秒`?截取到?`第3分10秒`? video_clip.subclip((1,?2,?18),?(2,?1,?34)):? ???從視頻的?`第1小時2分18秒`?截取到?`第2小時1分34秒` """ #?subclip?會返回一個新的?VideoFileClip?對象 #?所以它支持鏈式操作 video_clip?=?video_clip.subclip(30)
音量調整
一個視頻,我們也可以調整它的音量。
from?moviepy?import?editor video_clip?=?editor.VideoFileClip( ????"空城計,但是7Ki7Ki醬醬.mp4") #?調整音量,變?yōu)樵瓉淼?.5 #?同樣會返回一個新的對象 video_clip?=?video_clip.volumex(0.5)
在視頻上添加文字
如果你想在視頻里面寫上一些內容,moviepy 也是支持的。
from?moviepy?import?editor
video_clip?=?editor.VideoFileClip(
????"空城計,但是7Ki7Ki醬醬.mp4")
#?做一個文本剪貼板,自定義樣式、顏色。
text_clip?=?editor.TextClip("7ki7ki?棒棒",
????????????????????????????fontsize=40,?color="blue")
#?讓文本在屏幕的正中間顯示
#?持續(xù)10秒,設置透明度為?0.6
"""
屏幕左上角的坐標為?(0,?0),右下角的坐標為?(屏幕寬度,?屏幕高度)
set_position((800,?500)):?
????顯示在800,?500的位置上
set_position(("center",?"center")):?
????顯示在屏幕的正中央
set_position((0.4,?0.6),?True):?
????顯示在距離左邊百分之40、距離上邊百分之60的位置上
set_duration(10):?持續(xù)10秒
set_opacity(0.6):?設置透明度為0.6
"""
text_clip?=?text_clip.set_position(("center",?"center")).\
????set_duration(10).set_opacity(0.8)
#?然后把?`文本剪貼板`?貼在視頻上
video_clip?=?editor.CompositeVideoClip([video_clip,?text_clip])如果你是 Windows 系統(tǒng),不出意外的話,當你在執(zhí)行 editor.TextClip() 的時候,會報出如下錯誤:

這個錯誤是由于你的電腦上缺少 ImageMagick 造成的,我們需要去官網下載對應操作系統(tǒng)的 ImageMagick。
官網:http://www.imagemagick.org/script/download.php
下載完之后,安裝在指定的目錄,然后修改site-packages\moviepy\config_defaults.py,在文件的尾部有如下內容:
import?os
FFMPEG_BINARY?=?os.getenv('FFMPEG_BINARY',?'ffmpeg-imageio')
IMAGEMAGICK_BINARY?=?os.getenv('IMAGEMAGICK_BINARY',?'auto-detect')
#?把?`IMAGEMAGICK_BINARY?=?`?后面的內容
#?換成?ImageMagick?安裝路徑下?magick.exe?的絕對路徑:
import?os
FFMPEG_BINARY?=?os.getenv('FFMPEG_BINARY',?'ffmpeg-imageio')
IMAGEMAGICK_BINARY?=?r'E:\ImageMagick-7.0.10-Q16\magick.exe'替換完之后,再執(zhí)行就沒有問題了。
我們將上面的幾個部分,組合起來演示一下:
from?moviepy?import?editor
video_clip?=?editor.VideoFileClip(
????"空城計,但是7Ki7Ki醬醬.mp4")
video_clip?=?(
????#?截取?5?到?20?秒
????video_clip.subclip(5,?20).
????#?設置音量為原來的?0.8
????volumex(0.8)
)
text_clip?=?(
????editor.TextClip("7ki7ki",
???????????????????fontsize=40,?color="blue").
????set_position(("center",?"center")).
????set_duration(10).
????set_opacity(0.8)
)
#?把?`文本剪貼板`?貼在視頻上
video_clip?=?editor.CompositeVideoClip([video_clip,?text_clip])
#?然后將視頻導出
video_clip.write_videofile("空城計,但是7Ki7Ki醬醬_2.mp4")
執(zhí)行代碼,會看到以下輸出:

表示正在調用 ffmpeg 處理視頻,而視頻處理完畢大概需要十幾秒鐘的時間。處理完畢之后,我們打開看一下。

我們看到此時文字就添加進去了,并且該視頻只有15秒,也就是我們截取的 5 到 20 秒的部分。
總結一下整個流程,首先使用 VideoFileClip 對視頻進行讀取,得到 VideoFileClip 對象,記作 video_clip。我們可以對這個 video_clip 進行任意的操作(剪切、合并、調整亮度、速度、和其它的 video_clip 拼接在一起等等)。
并且需要注意的是,這些操作是可以鏈式調用的,因為每一次操作都會得到一個新的 video_clip,不會影響原來的。我們上面演示了視頻的讀取、以及指定部分的截取、音量的調整、以及添加文字等等,下面還會介紹更多操作。
最后我們調用 video_clip 的 write_videofile 方法,可以將處理之后的視頻寫入本地。當然也可以使用 pygame,或者 jupyter notebook 進行展示。為了方便,我們后面就使用 jupyter notebook。
但是要清楚,moviepy 處理視頻使用的是 ffmpeg,生成文字使用的是 ImageMagick。
獲取視頻屬性
一個視頻,肯定有大小、寬高、fps、時長等屬性,那么 moviepy 要如何獲取這些屬性呢。
from?moviepy?import?editor video_clip?=?editor.VideoFileClip(r"空城計,但是7Ki7Ki醬醬.mp4") #?獲取寬度和高度 print(video_clip.size) print(video_clip.w,?video_clip.h) """ [2160,?1080] 2160?1080 """ #?獲取?fps print(video_clip.fps) """ 30.0 """ #?獲取時長,單位是秒 print(video_clip.duration) """ 110.92 """ #?獲取大小,可以直接使用?os?模塊 import?os #?大概?13MB size?=?os.stat(r"空城計,但是7Ki7Ki醬醬.mp4").st_size print(size) print(size?/?1024?**?2) """ 13324402 12.70713996887207 """
視頻合成
視頻合成有兩種方式:
1)多個視頻按照先后順序拼接起來,比如一個一分鐘和一個兩分鐘的視頻組合起來,變成三分鐘。
2)多個視頻在同一個畫面上顯示。
先來看看第一種:
from?moviepy?import?editor video_clip?=?editor.VideoFileClip(r"D:\satori\空城計,但是7Ki7Ki醬醬.mp4") #?截取10到20秒 video_clip1?=?video_clip.subclip(10,?20) #?截取結尾的前兩秒 video_clip2?=?video_clip.subclip(-2) #?然后前后拼接起來 video_clip?=?editor.concatenate_videoclips([video_clip1,?video_clip2]) #?使用jupyter進行展示,設置一個寬度 video_clip.ipython_display(width=360)

執(zhí)行完之后,視頻就展示在 jupyter 上了,而且是兩個視頻拼接在一起的,總共 12 秒鐘。此外 concatenate_videoclips 中還可以指定一個transition參數(shù)(也是一個VideoFileClip對象),作為銜接之間的過渡。
還是比較簡單的,假設我們有 5 個視頻,如果只是簡單的前后拼接就可以這么做。
from?moviepy?import?editor
videos?=?["1.mp4",?"2.mp4",?"3.flv",
??????????"4.mp4",?"5.flv"]
video_clips?=?[]
for?video?in?videos:
????video_clips.append(editor.VideoFileClip(video))
editor.concatenate_videoclips(
????video_clips).write_videofile("xxx.mp4")這里值得一提的是,多個 video_clip 進行拼接,并不需要這些 video_clip 之間有相同的尺寸、時長什么的,僅僅是將它們按照順序拼接起來而已。
另外,當你用 jupyter 進行展示時,視頻不要過長,否則報錯。當然你也可以給 ipython_display 函數(shù)傳遞一個 maxduration 參數(shù),讓它支持顯示更大時長的視頻文件。但是注意:如果文件過大,在 jupyter 上可能會耗光你的內存。
然后是第二種拼接
有多個視頻,可以讓它們在同一個畫面上顯示。
from?moviepy?import?editor #?margin:?設置外邊距 video_clip?=?editor.VideoFileClip( ????r"D:\satori\空城計,但是7Ki7Ki醬醬.mp4").margin(10) #?截取?10?到?20?秒 video_clip1?=?video_clip.subclip(10,?20) #?x?軸鏡像 video_clip2?=?video_clip1.fx(editor.vfx.mirror_x) #?y?軸鏡像 video_clip3?=?video_clip1.fx(editor.vfx.mirror_y) #?resize:?等比縮放 video_clip4?=?video_clip1.resize(0.5) #?列表里面有兩個列表,所以會將屏幕上下等分 #?上半部分顯示?video_clip1,?video_clip2 #?下半部分顯示video_clip3,?video_clip4 video_clip?=?editor.clips_array([[video_clip1,?video_clip2], ?????????????????????????? ?[video_clip3,?video_clip4]]) video_clip.ipython_display(width=600)

所以 concatenate_videoclips 是將多個視頻前后拼接,而 clips_array 則是將多個視頻同時顯示在一個畫面里面。
修改視頻屬性
from?moviepy?import?editor video_clip?=?editor.VideoFileClip( ????r"D:\satori\空城計,但是7Ki7Ki醬醬.mp4").subclip(10,?20) video_clip?=?( ????#?調整尺寸,保持比例 ????video_clip.fx(editor.vfx.resize,?width=460) ????????#?倍數(shù)播放 ????????.fx(editor.vfx.speedx,?2) ????????#?畫面調暗 ????????.fx(editor.vfx.colorx,?0.5) ) video_clip.ipython_display(width=600)

雖然截取了 10 秒鐘,但是 2 倍數(shù)播放,所以變成了 5 秒鐘。
視頻音頻合成
假設有一個視頻 A 和一個視頻 B,現(xiàn)在要將視頻 B 的音頻和視頻 A 組合起來,怎么做呢?
from?moviepy?import?editor
video_clipA?=?editor.VideoFileClip(r"A.mp4")
video_clipB?=?editor.VideoFileClip(r"B.mp4")
#?獲取?B?的音頻
audioB?=?video_clipB.audio
"""
#?如果已經是音頻格式,那么也可以直接加載
audioB?=?editor.AudioFileClip("b.mp3")
"""
#?將?B?的音頻和?A?組合起來
video_clipA?=?video_clipA.set_audio(audioB)以上就是Python視頻處理模塊之moviepy的用法教程的詳細內容,更多關于Python視頻處理模塊moviepy的資料請關注腳本之家其它相關文章!
相關文章
python的dict,set,list,tuple應用詳解
這篇文章主要介紹了python的dict,set,list,tuple應用詳解,需要的朋友可以參考下2014-07-07
python使用多線程查詢數(shù)據(jù)庫的實現(xiàn)示例
這篇文章主要介紹了python使用多線程查詢數(shù)據(jù)庫的實現(xiàn)示例,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2020-08-08
pytest解讀fixtures之Teardown處理yield和addfinalizer方案
這篇文章主要為大家介紹了pytest解讀fixtures之Teardown處理yield和addfinalizer的方案實例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2022-06-06
使用Pandas對數(shù)據(jù)進行篩選和排序的實現(xiàn)
這篇文章主要介紹了使用Pandas對數(shù)據(jù)進行篩選和排序的實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2019-07-07

