一区二区三区日韩精品-日韩经典一区二区三区-五月激情综合丁香婷婷-欧美精品中文字幕专区

分享

moviepy:基于 ffmpeg 的視頻處理模塊

 古明地覺O_o 2022-12-08 發(fā)布于北京

楔子


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

而 Python 有一個專門用于處理視頻的第三方庫:moviepy,可以非常方便地對視頻進行一些簡單處理,下面我們就來看一看。

首先是安裝:

pip install moviepy -i https://pypi.tuna./simple

個人推薦安裝的時候使用清華源,因為moviepy需要依賴另一個庫:imageio_ffmpeg,這個庫里面包含了一個 50 多 MB 的 ffmpeg 二進制文件,如果網(wǎng)絡(luò)不行的話,直接從pypi上拉取會花很長時間。當(dāng)然安裝moviepy的時候,imageio_ffmpeg 就順帶安裝了。

從這里我們也可以看到,moviepy 底層依賴 ffmpeg,而ffmpeg是跨平臺的,所以 moviepy 也可以在任意平臺上使用。


moviepy 的簡單使用


我們來看 moviepy 都提供了哪些功能,不過在使用之前我們需要一個視頻,就使用 you-get 工具從 bilibili 下載一個吧。

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

視頻截取

如果一個視頻比較長,我們可以截取感興趣的片段。

from moviepy import editor

# 調(diào)用 `VideoFileClip(文件名)` 即可將視頻加載進來
# 并且支持不同的視頻格式,比如 flv、mp4 等等
video_clip = editor.VideoFileClip(
    "空城計,但是7Ki7Ki醬醬.mp4")

# 調(diào)用subclip方法,傳入起始時間和結(jié)束時間
# 即可截取視頻中的指定部分
"""
video_clip.subclip(): 
   截取視頻全部,相當(dāng)于沒做處理
video_clip.subclip(10): 
   從視頻的 `第10秒` 截取到 `結(jié)尾`
video_clip.subclip(10, -2): 
   從視頻的 `第10秒` 截取到結(jié)尾的 `前兩秒`
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 對象
# 所以它支持鏈?zhǔn)讲僮?/span>
video_clip = video_clip.subclip(30)

音量調(diào)整

一個視頻,我們也可以調(diào)整它的音量。

from moviepy import editor

video_clip = editor.VideoFileClip(
    "空城計,但是7Ki7Ki醬醬.mp4")

# 調(diào)整音量,變?yōu)樵瓉淼?.5
# 同樣會返回一個新的對象
video_clip = video_clip.volumex(0.5)

在視頻上添加文字

如果你想在視頻里面寫上一些內(nèi)容,moviepy 也是支持的。

from moviepy import editor

video_clip = editor.VideoFileClip(
    "空城計,但是7Ki7Ki醬醬.mp4")

# 做一個文本剪貼板,自定義樣式、顏色。
text_clip = editor.TextClip("7ki7ki 棒棒",
                            fontsize=40, color="blue")
# 讓文本在屏幕的正中間顯示
# 持續(xù)10秒,設(shè)置透明度為 0.6
"""
屏幕左上角的坐標(biāo)為 (0, 0),右下角的坐標(biāo)為 (屏幕寬度, 屏幕高度)
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): 設(shè)置透明度為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),不出意外的話,當(dāng)你在執(zhí)行 editor.TextClip() 的時候,會報出如下錯誤:

這個錯誤是由于你的電腦上缺少 ImageMagick 造成的,我們需要去官網(wǎng)下載對應(yīng)操作系統(tǒng)的 ImageMagick。

官網(wǎng):http://www./script/download.php

下載完之后,安裝在指定的目錄,然后修改site-packages\moviepy\config_defaults.py,在文件的尾部有如下內(nèi)容:

import os

FFMPEG_BINARY = os.getenv('FFMPEG_BINARY''ffmpeg-imageio')
IMAGEMAGICK_BINARY = os.getenv('IMAGEMAGICK_BINARY''auto-detect')

# 把 `IMAGEMAGICK_BINARY = ` 后面的內(nèi)容
# 換成 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(520).
    # 設(shè)置音量為原來的 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])

# 然后將視頻導(dǎo)出
video_clip.write_videofile("空城計,但是7Ki7Ki醬醬_2.mp4")

執(zhí)行代碼,會看到以下輸出:

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

我們看到此時文字就添加進去了,并且該視頻只有15秒,也就是我們截取的 5 到 20 秒的部分。

總結(jié)一下整個流程,首先使用 VideoFileClip 對視頻進行讀取,得到 VideoFileClip 對象,記作 video_clip。我們可以對這個 video_clip 進行任意的操作(剪切、合并、調(diào)整亮度、速度、和其它的 video_clip 拼接在一起等等)。

并且需要注意的是,這些操作是可以鏈?zhǔn)秸{(diào)用的,因為每一次操作都會得到一個新的 video_clip,不會影響原來的。我們上面演示了視頻的讀取、以及指定部分的截取、音量的調(diào)整、以及添加文字等等,下面還會介紹更多操作。

最后我們調(diào)用 video_clip 的 write_videofile 方法,可以將處理之后的視頻寫入本地。當(dāng)然也可以使用 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.70713996887
207
"""

視頻合成


視頻合成有兩種方式:

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

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

先來看看第一種:

from moviepy import editor
video_clip = editor.VideoFileClip(r"D:\satori\空城計,但是7Ki7Ki醬醬.mp4")

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

執(zhí)行完之后,視頻就展示在 jupyter 上了,而且是兩個視頻拼接在一起的,總共 12 秒鐘。此外 concatenate_videoclips 中還可以指定一個transition參數(shù)(也是一個VideoFileClip對象),作為銜接之間的過渡。

還是比較簡單的,假設(shè)我們有 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 之間有相同的尺寸、時長什么的,僅僅是將它們按照順序拼接起來而已。

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

然后是第二種拼接

有多個視頻,可以讓它們在同一個畫面上顯示。

from moviepy import editor

# margin: 設(shè)置外邊距
video_clip = editor.VideoFileClip(
    r"D:\satori\空城計,但是7Ki7Ki醬醬.mp4").margin(10)

# 截取 10 到 20 秒
video_clip1 = video_clip.subclip(1020)
# 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(1020)

video_clip = (
    # 調(diào)整尺寸,保持比例
    video_clip.fx(editor.vfx.resize, width=460)
        # 倍數(shù)播放
        .fx(editor.vfx.speedx, 2)
        # 畫面調(diào)暗
        .fx(editor.vfx.colorx, 0.5)
)
video_clip.ipython_display(width=600)

雖然截取了 10 秒鐘,但是 2 倍數(shù)播放,所以變成了 5 秒鐘。


視頻音頻合成


假設(shè)有一個視頻 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
"""
# 如果已經(jīng)是音頻格式,那么也可以直接加載
audioB = editor.AudioFileClip("b.mp3")
"""


# 將 B 的音頻和 A 組合起來
video_clipA = video_clipA.set_audio(audioB)

小結(jié)


以上就是 moviepy 的一些基本用法,通過 moviepy 可以對視頻做一些簡單的批處理。至于視頻(以及音頻)背后的原理就是一門復(fù)雜的學(xué)問了,有興趣的話可以深入研究下,現(xiàn)在短視頻那么火,相關(guān)的技術(shù)人員也比較短缺,所以前景還是很不錯的。

    轉(zhuǎn)藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多

    日本在线不卡高清欧美| 午夜激情视频一区二区| 欧美一级黄片免费视频| 欧美黑人暴力猛交精品| 日本少妇三级三级三级| 又黄又色又爽又免费的视频| 蜜桃av人妻精品一区二区三区| 国产女高清在线看免费观看| 天海翼高清二区三区在线| 老司机精品视频免费入口| 激情图日韩精品中文字幕| 亚洲国产精品一区二区| 丁香七月啪啪激情综合| 欧美国产日本免费不卡| 制服丝袜美腿美女一区二区| 欧美一区二区在线日韩| 夫妻性生活黄色录像视频| 欧美日韩亚洲精品内裤| 国产99久久精品果冻传媒| 人妻少妇av中文字幕乱码高清| 国产欧美一区二区久久| 免费观看潮喷到高潮大叫| 欧美加勒比一区二区三区| 国产免费一区二区不卡| 日本女优一区二区三区免费| 最新69国产精品视频| 亚洲最新中文字幕在线视频| 亚洲专区中文字幕在线| 欧美又大又黄刺激视频| 精品国产丝袜一区二区| 久久综合九色综合欧美| 欧美丝袜诱惑一区二区| 欧美日韩综合在线精品| 一区二区三区日韩在线| 五月婷婷六月丁香在线观看| 国产人妻精品区一区二区三区| 日本免费一级黄色录像| 91人妻丝袜一区二区三区| 亚洲男人天堂网在线视频| 69久久精品亚洲一区二区| 国产欧美亚洲精品自拍|