python用moviepy對視頻進行簡單的處理

楔子

隨著自媒體時代,現在對視頻的處理變得越來越常見。我們可以使用Adobe的一些專業工具,但是效率不高;如果隻是對視頻進行一些簡單的處理的話,或者視頻的數量非常多的話,那麼使用專業軟件顯然就不太適合瞭。

而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上下載一個吧。

下面我們就使用這個下載的視頻進行演示。

一個小栗子

我們以一個小栗子,來演示一下使用moviepy是怎麼操作視頻的。

from moviepy import editor

# 調用 `VideoFileClip(文件名)` 即可將視頻加載進來
# 可以讀取各種格式的視頻文件
video_clip = editor.VideoFileClip(r"C:\Users\satori\Desktop\警察蜀黍!!!就是這個人!!!! 翻唱.flv")

# 調用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秒`
"""
video_clip = video_clip.subclip(5, 20)

# 調整音量,變為原來的0.5
video_clip = video_clip.volumex(0.5)

# 做一個文本剪貼板,自定義樣式、顏色。
text_clip = editor.TextClip("hanser, little angel", fontsize=40, color="blue")
# 讓文本在屏幕的正中間顯示,持續10秒,設置透明度為0.8
"""
屏幕左上角為(0, 0),右下角為(屏幕寬度, 屏幕高度)
set_position((800, 500)): 顯示在800, 500的位置上
set_position(("center", "center")): 顯示在屏幕的正中央
set_position((0.4, 0.6), True): 顯示在距離左邊百分之40、距離上邊百分之60的位置上

set_duration(10): 持續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])

# 然後導出視頻,可以是其它的視頻格式
video_clip.write_videofile("1.mp4")

# 下面很重要:
r"""
如果你是在Windows上執行,不出意外的話,當你在執行 editor.TextClip() 的時候,會報出如下錯誤:

OSError: MoviePy Error: creation of None failed because of the following error:

[WinError 2] 系統找不到指定的文件。.

.This error can be due to the fact that ImageMagick is not installed on your computer, 
or (for Windows users) that you didn't specify the path to the ImageMagick binary in file conf.py, 
or that the path you specified is incorrect

這個錯誤是由於你的電腦上缺少ImageMagick造成的,我們需要去http://www.imagemagick.org/script/download.php
這個網站上下載對應操作系統的ImageMagick,我這裡是Windows。可能下載的比較慢,畢竟是外網。
如果覺得速度無法忍受的話,我提供瞭相應瞭網盤鏈接: 鏈接:https://pan.baidu.com/s/1n1xNohD7V-abQbX81UENJQ 提取碼:usl3,可以進行保存下載

下載完畢之後,直接安裝在指定的目錄。
然後修改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'
"""
# 然後執行就沒有問題瞭

我們看到此時文字就添加進去瞭,並且該視頻隻有15秒,也就是我們截取的部分。

那麼moviepy是如何工作的呢?

moviepy使用ffmpeg對視頻、音頻文件進行讀取和導出,使用ImageMagick生成文字等等。

首先我們使用VideoFileClip對視頻進行讀取,得到VideoFileClip對象,我們記作clip。我們可以對這個clip進行任意的操作(剪切、合並、調整亮度、速度、和其它的clip拼接在一起等等)。並且我們需要註意的是,這些操作是可以鏈式調用的,因為每一次操作都會得到一個新的clip,不會影響原來的。我們上面演示瞭視頻的讀取、以及指定部分的截取、音量的調整、以及添加文字等等,我們後面還會介紹更多操作。

並且我們最後調用clip的write_videofile方法,可以將處理之後的視頻寫入本地。當然我們還可以使用pygame,或者jupyter notebook進行展示。為瞭方便,我們後面就使用jupyter notebook。

視頻屬性

我們說一個視頻,肯定有大小、寬高、fps、時長等等屬性,下面我們就來看看如何獲取這些屬性。

from moviepy import editor

# 調用 `VideoFileClip(文件名)` 即可將視頻加載進來
# 可以讀取各種格式的視頻文件
video_clip = editor.VideoFileClip(r"C:\Users\satori\Desktop\警察蜀黍!!!就是這個人!!!! 翻唱.flv")
# 獲取寬度和高度
print(video_clip.size) # [800, 600]
print(video_clip.w, video_clip.h) # 800 600

# 獲取fps
print(video_clip.fps) # 23.976023976023978

# 獲取時長,單位是秒
print(video_clip.duration) # 155.12

# 獲取大小,可以直接使用os模塊
import os
# 大概16兆
print(os.stat(r"C:\Users\satori\Desktop\警察蜀黍!!!就是這個人!!!! 翻唱.flv").st_size) # 16852110
print(os.stat(r"C:\Users\satori\Desktop\警察蜀黍!!!就是這個人!!!! 翻唱.flv").st_size / 1024 ** 2) # 16.07142448425293

視頻合成

視頻合成有兩種方式:

1.多個視頻按照先後順序拼接起來。比如一個一分鐘和一個兩分鐘的視頻組合起來,變成三分鐘。

from moviepy import editor
video_clip = editor.VideoFileClip(r"C:\Users\satori\Desktop\警察蜀黍!!!就是這個人!!!! 翻唱.flv")

# 截取10到20秒
video_clip1 = video_clip.subclip(10, 20)
# 截取1分45秒到結尾的前兩秒
video_clip2 = video_clip.subclip((1, 45), -2)
# 然後前後拼接起來
clip = editor.concatenate_videoclips([video_clip1, video_clip2])
# 使用jupyter進行展示,設置一個寬度
clip.ipython_display(width=360)

此時視頻就展示在jupyter上瞭,而且是兩個視頻拼接在一起的。並且在concatenate_videoclips中還可以指定一個transition參數(也是一個VideoFileClip對象),作為銜接之間的過渡。

還是比較簡單的,假設我們有5個視頻,如果隻是簡單的前後拼接就可以這麼做。

from moviepy import editor


videos = ["1.mp4", "2.mp4", "3.flv", "4.mp4", "5.flv"]
clips = []
for video in videos:
 clips.append(editor.VideoFileClip(video))

editor.concatenate_videoclips(clips).write_videofile("xxx.mp4")

這裡值得一提的是,多個clip進行拼接,並不需要這些clip之間有相同的尺寸、時長什麼的,僅僅是將它們按照順序拼接起來而已。

另外,當你用jupyter進行展示時,視頻不要過長,否則報錯。當然你也可以給ipython_display函數傳遞一個maxduration參數,讓它支持顯示更大時長的視頻文件。但是註意:如果文件過大,在jupyter上可能會耗光你的內存。

2.多個視頻在同一個畫面上顯示

from moviepy import editor
# margin: 設置外邊距
video_clip = editor.VideoFileClip(r"C:\Users\satori\Desktop\警察蜀黍!!!就是這個人!!!! 翻唱.flv").margin(10)

video_clip1 = video_clip.subclip(10, 20)
# editor.vfx.mirror_x: x軸鏡像
video_clip2 = video_clip1.fx(editor.vfx.mirror_x)
# editor.vfx.mirror_y: y軸鏡像
video_clip3 = video_clip1.fx(editor.vfx.mirror_y)
# resize: 等比縮放
video_clip4 = video_clip1.resize(0.8)
# 列表裡面有兩個列表,所以會將屏幕上下等分
# 上半部分顯示video_clip1, video_clip2,下半部分顯示video_clip3, video_clip4
clip = editor.clips_array([[video_clip1, video_clip2], [video_clip3, video_clip4]])
clip.ipython_display(width=600)

所以我們看到concatenate_videoclips是將多個視頻前後拼接,而clips_array是將多個視頻同時顯示在一個畫面裡面。

修改視頻屬性

from moviepy import editor


clip = editor.VideoFileClip(r"C:\Users\satori\Desktop\警察蜀黍!!!就是這個人!!!! 翻唱.flv").subclip(10, 20)

clip = (clip.fx(editor.vfx.resize, width=460) # 調整尺寸,保持比例
  .fx(editor.vfx.speedx, 2) # 調整倍數
  .fx(editor.vfx.colorx, 0.5) # 畫面調暗
  )

視頻音頻合成

假設我們有一個視頻A和一個視頻B,我要將視頻B的音頻和視頻A組合起來,怎麼做呢?

from moviepy import editor


clipA = editor.VideoFileClip(r"A.mp4")
clipB = editor.VideoFileClip(r"B.mp4")

# 獲取B的音頻
audioB = clipB.audio

# 將B的音頻和A組合起來
clipA = clipA.set_audio(audioB)
# 然後保存即可

# 或者我們也可以直接加載一個音頻
audio = editor.AudioFileClip("b.mp3")

以上就是python用moviepy對視頻進行簡單的處理的詳細內容,更多關於python moviepy對視頻處理的資料請關註WalkonNet其它相關文章!

推薦閱讀: