Python/MoviePyで動画編集【カット・トリミング・テキスト挿入】をする!

動画編集を日々何かしらのソフトを使って行っている人もいるだろうけど、プログラミングの力を使って動画を編集することもできる。そこで今回はPythonを使ってカットやトリミングなどの動画編集をしていきたい。どんなことができるのかやっていこうではありませんか。

Pythonで動画編集する方法

動画編集する方法はいくつかあると思うけど、今回はMoviePyっていうやつを使っていきます。

MoviePyをインストールする

MoviePyという動画編集をすることのできるライブラリがあるのでこれを使ってやっていこう。まずはインストール。

$ pip install moviepy

インストールに成功したら準備は完了だからコードを書いていこう。

動画をカットする

動画の一部分をカットするっていうコードを書いていこうと思う。使う動画はなんでもいいけど今回はこの犬の動画をカットしていきたい。

これは14秒ある動画なんだけど、この動画の一部分をカットしたいです。5秒から10秒の間をカットして保存してやろう。(コードは色々べた書きだけどまあいいだろう・・・)

from moviepy.editor import VideoFileClip

# 編集したい動画のパスを指定し、カットする開始秒数と終了秒数を指定。
video = VideoFileClip("/Users/U/Downloads/dog-mov.mp4").subclip(5, 10)
# 編集した動画を保存するパスを指定
video.write_videofile("/Users/U/Downloads/dog-mov-edited.mp4",fps=29)

これを実行すると指定してパスにカットされた5秒から10秒の間の動画が保存される。カットされた動画はこれですね。

ちゃんと5秒間カットされていますね。ちょっとしたコードでカットできるのは使いようによっては楽かもしれない。

動画をトリミングする

次は動画のトリミングをやってみよう。動画のこの部分だけ欲しいっていう時に使えるやつですね。時間じゃなくてこの範囲だけっていう指定して切り取るやつ。この猫の動画の猫の部分だけを四角くトリミングしたい。

トリミングの際にはコードでどの地点からどの程度の長さでトリミングするのか?っていう指定をしなくてはいけないんだけど、イメージとしてはこんな感じだろうか。

X1,Y1っていうトリミングの開始地点の座標を指定して、そこからどの程度の長さで切り取るのかっていうのはX2、Y2。コードでそのまま指定するとこんな感じになる。cropで切り取る範囲を指定しているね。

from moviepy.editor import VideoFileClip

# トリミングしたい動画のパスと座標指定
video = (VideoFileClip("/Users/U/Downloads/cat-edited.mp4").crop(x1=0,y1=500,x2=1800,y2=1000))
# 保存先のパス指定
video.write_videofile("/Users/U/Downloads/cat-cropped.mp4",fps=29)

実行してみて保存された動画を見てみるとこんな風に切り取られました。

猫の部分だけが切り取られていて良い感じ。ただ座標の指定がちょっと難しいかもしれないですね、動画の座標大体このぐらいだろ・・・っていう感じで調整してやったけどあんまりうまくいかん。

動画にテキストを入れる

TextClipというものを使えば、動画内にテキストを入れることができる。Cat!!っていう文言を真ん中に入れてみた。

TextClip()で文字や文字の色、サイズ、位置などを調整しています。文字色や文言なんかは簡単に変えることができるから便利ですね。

v = VideoFileClip("/Users/U/Downloads/cat.mp4").subclip(5, 10)
# テキストの作成
txt_clip = TextClip("Cat!!",fontsize=200,color="white").set_position("center").set_duration((0,5))
result = CompositeVideoClip([v, txt_clip])
#保存
result.write_videofile("/Users/U/Downloads/cat-texted.mp4",fps=29)

位置や時間はset_positionset_durationで設定することができるから、好きなタイミングや位置で表示することができる。ちなみにドキュメント見てみると結構指定できる引数が多いですね。

VideoClip

日本語指定したら動画内に文字が表示されなかったんだけど、デフォルトのフォントがCourierになっているからだろうか。Courierのことはよく知らないが、print(TextClip.list('font'))として使えるフォントを見てみるとこんな感じか。

['AvantGarde-Book', 'AvantGarde-BookOblique', 'AvantGarde-Demi', 'AvantGarde-DemiOblique', 'Bookman-Demi', 'Bookman-DemiItalic', 'Bookman-Light', 'Bookman-LightItalic', 'Courier', 'Courier-Bold', 'Courier-BoldOblique', 'Courier-Oblique', 'fixed', 'Helvetica', 'Helvetica-Bold', 'Helvetica-BoldOblique', 'Helvetica-Narrow', 'Helvetica-Narrow-Bold', 'Helvetica-Narrow-BoldOblique', 'Helvetica-Narrow-Oblique', 'Helvetica-Oblique', 'NewCenturySchlbk-Bold', 'NewCenturySchlbk-BoldItalic', 'NewCenturySchlbk-Italic', 'NewCenturySchlbk-Roman', 'Palatino-Bold', 'Palatino-BoldItalic', 'Palatino-Italic', 'Palatino-Roman', 'Symbol', 'Times-Bold', 'Times-BoldItalic', 'Times-Italic', 'Times-Roman']

これが使えるフォントみたいだけど、日本語対応しているものあるのかなこれ。ImageMagickと関係しているのだろうか、convert -list fontとかで検索するとghostscriptを参照しているのかな、うーんよく分からん。日本語フォント追加すれば使えそうな気もするけど・・・

動画の字幕の生成は

すまん、動画の字幕の生成もやろうかなと思ったんだけど、ちょっと考えてみると割と長い道のりになりそうなのでやめました。多分こんな流れになるだろうけど、字幕ファイルの生成がしんどそうだなあ・・・と思ってしまい。。。

  1. 動画から音声を抽出する
  2. 抽出した音声をGCPのSpeech-to-Textなどを使ってテキスト化する
  3. テキスト化したものから字幕ファイルを生成する
  4. 字幕ファイルと動画を結合する

字幕で表示するテキストができたとしても、それを動画に合わせるためには適切な部分でカットして表示しないといけないですよね。その適切なカットされた字幕をうまいこと作って動画とくっつけるのが面倒そうだと・・・

Speech-to-Textじゃなくてテキストを音声に変換するText-to-Speechはこっちの記事でやりましたね。音声をテキストに変換するのも似たような感じでできると思います。

動画の字幕生成を作ってやるぜー!っていう強い気持ちがある人に任せました。

まとめ

Pythonで使えるMoviePyっていうものを見てみたけど、カットやトリミングなら結構簡単にできますね。ドキュメントが英語しかないからちょっと読むのが辛いけど・・・

今回やったカットやトリミング、テキストの挿入のコードはこんな感じ。ちょっと汚いがcut()、trimming()、insertText()にしといた。

from moviepy.editor import *

def cut(target, to):
  # 編集したい動画のパスを指定し、カットする開始秒数と終了秒数を指定。
  video = VideoFileClip(target).subclip(5, 10)
  # 編集した動画を保存するパスを指定
  video.write_videofile(to,fps=29)  

def trimming(target, to, coordinate):
  # トリミングしたい動画のパスと座標指定
  video = (VideoFileClip(target).crop(x1=coordinate['x1'],y1=coordinate['y1'],x2=coordinate['x2'],y2=coordinate['y2']))
  video.write_videofile(to,fps=29)

def insertText(target, to):
  v = VideoFileClip(target).subclip(5, 10)
  txt_clip = TextClip("Cat!!",fontsize=200,color="white").set_position("center").set_duration((0,5))
  result = CompositeVideoClip([v, txt_clip]) 
  result.write_videofile(to,fps=29)

cut("/Users/U/Downloads/cat.mp4", "/Users/U/Downloads/cat-edited.mp4")
trimming("/Users/U/Downloads/cat-edited.mp4", "/Users/U/Downloads/cat-cropped.mp4",{
  'x1': 0,
  'y1': 500,
  'x2': 1800,
  'y2': 1000
})

insertText("/Users/U/Downloads/cat.mp4", "/Users/U/Downloads/cat-texted.mp4")

動画編集をプログラムのコードである程度できるようになったら、使いようによっては楽に動画編集できるようになりそうですよね。そういえば前にPremiereProで音声のテキスト化っていうテロップを自動生成する機能が使えるようになりましたね。

自動テロップならVrewを使うのもいいかもしれない。

動画編集を楽にやりたいなら、こっちの記事も確認してみておくれ。

おすすめの記事