ぷそさんのプログラミング研究所

【動画編集】Pythonで動画に自動で字幕・テロップを入れる方法|moviepy

最近のYouTube動画は全部の言葉に字幕をつける「フルテロップ」が多くなってきていると思います。

しかし,動画編集ソフトで1つずつテロップをつけるのは大変だと思います。

そこで,Pythonを使って,「自動でテロップを付ける方法」をご紹介したいと思います。

こんな人に役立ちます
  • YouTubeでフルテロップ動画を作成している方
  • Pythonで動画編集をしたい方
目次

Pythonで字幕・テロップをつける

まず,この記事を読んでいただくと下のような動画が作れます。

Pythonで字幕・テロップをつけるための準備

Pythonで動画編集をするためには,以下のものが必要になります。

  • 編集する動画素材
  • moviepy
  • imagemagick

moviepyというのは,Pythonで動画編集をするためのモジュールです。

pipcondaで入れることができます。

conda install -c conda-forge moviepy
pip install moviepy

また,imagemagickは,画像を編集するためのソフトウェアであり必須です。

OSによってダウンロード方法は違いますが,無料でインストールできます。

# Macの場合
brew install imagemagick 

これだけで,動画編集ができます!

moviepyの基本的な使い方

まずは,簡単な例で使い方を見ていきましょう。

モジュールの準備

まずは,先程インストールしたmoviepyをインポートします。

from moviepy.editor import *

動画素材の取得

編集したい動画を読み込みます。

# 動画ファイルのパス
movie_path = "test.mp4"
clip = VideoFileClip(movie_path)

フォントの指定

字幕やテロップで使いたいフォントを指定します。

# フォントのパス
font_path = "ヒラギノ角ゴシック W9.ttc" #実際のパスを指定する
font_size = 120

フォントは,Windowsの場合は,‘C:/Windows/Fonts/にあります。

Macの場合は,finder.ttf.ttcと検索すれば出てきます!

できるだけ,太いフォントを選ぶと見やすくなります!

font_sizeは,好きな大きさで大丈夫です。

挿入するテキストの設定

挿入するテキストと,どんな色にするかなどを設定します。

# 入力するテキストの指定
text = "今年は2023年です。"

# テキストの装飾
text_color = "rgb(195,40,110)"
# 縁取り内側
stroke_in_color = "rgb(255,255,255)"
stroke_in_width = 5
# 縁取り外側
stroke_out_color = "rgb(0,0,0)"
stroke_out_width = 15

#テキストの位置
text_Y = 800
# 2重縁取りの場合に必要
delta_Y = 8

2行目:text =

入力するテキストを指定します。

4行目〜11行目

文字の装飾を設定します。

色に関しては,3種類決めます。

text_colorはテキストの色,stroke_in_colorは内側の縁取り,stroke_out_colorは外側の縁取りです。

下の図のような関係になっています。

外側の縁取りが不要の場合には,読み飛ばしていただいて大丈夫です!

また,色の指定方法は,RGB"rgb(195,40,110)"のように指定します。

matplotlibとは異なる点に注意です。

太さに関しては,好きな大きさに決めてもらって大丈夫です!

13行目〜16行目

テキストの位置は,基本的に真ん中としていますが,高さだけは自分で設定します。(自由自在に設定も可能です。)

2重縁取りの場合には補正が必要なので,delta_Yを用意しています。

フォントサイズによって前後するので試行錯誤的に決定します。

テキストの挿入

これまでに設定した内容で挿入を行います。

縁取りが1つの場合はこちら

txtclip = TextClip(text, 
                   font = font_path,
                   fontsize=120, 
                   color=text_color,
                   stroke_color=stroke_in_color,
                   stroke_width=stroke_in_width
                  )

cvc = CompositeVideoClip([clip, txtclip.set_position(("center",text_Y))])

縁取りが2つの場合はこちら

# 縁取り外側
txtclip_out = TextClip(text, 
                   font = font_path,
                   fontsize=font_size, 
                   color=text_color,
                   stroke_color=stroke_out_color,
                   stroke_width=stroke_out_width
                  )
# 縁取り内側
txtclip_in = TextClip(text, 
                   font = font_path,
                   fontsize=font_size, 
                   color=text_color,
                   stroke_color=stroke_in_color,
                   stroke_width=stroke_in_width
                  )

cvc = CompositeVideoClip([clip, txtclip_out.set_position(("center",text_Y)),
                         txtclip_in.set_position(("center",text_Y + delta_Y))])

動画を出力する

挿入が終わったので出力します。

output_clip = cvc.set_duration(clip.duration)
output_clip.write_videofile("test_output.mp4")

ここで,出力される動画は,「元素材と同じ動画長さ」で「テキストはずっと出ている」となります。

ここまでのコードをまとめます。

from moviepy.editor import *

# 動画ファイルのパス
movie_path = "test.mp4"
clip = VideoFileClip(movie_path)

# フォントのパス
font_path = "ヒラギノ角ゴシック W9.ttc"
font_size = 120

# 入力するテキストの指定
text = "今年は2023年です。"

# テキストの装飾
text_color = "rgb(195,40,110)"
# 縁取り内側
stroke_in_color = "rgb(255,255,255)"
stroke_in_width = 5
# 縁取り外側
stroke_out_color = "rgb(0,0,0)"
stroke_out_width = 15

# テキストの位置を決定(Y軸方向だけ)
text_Y = 800
# 若干位置ずれするので補正
delta_Y = 8

# 2重縁取りの場合
# 縁取り外側
txtclip_out = TextClip(text, 
                   font = font_path,
                   fontsize=font_size, 
                   color=text_color,
                   stroke_color=stroke_out_color,
                   stroke_width=stroke_out_width
                  )
# 縁取り内側
txtclip_in = TextClip(text, 
                   font = font_path,
                   fontsize=font_size, 
                   color=text_color,
                   stroke_color=stroke_in_color,
                   stroke_width=stroke_in_width
                  )

cvc = CompositeVideoClip([clip, txtclip_out.set_position(("center",text_Y)),
                         txtclip_in.set_position(("center",text_Y + delta_Y))])

output_clip = cvc.set_duration(clip.duration)
output_clip.write_videofile("test_output.mp4")

好きなタイミングで字幕・テロップを挿入する

実際には,動画の位置によって文言が変わると思うので,その場合の方法についてご紹介します。

まずは,コードから紹介します!

from moviepy.editor import *

# 動画ファイルのパス
movie_path = "test.mp4"
clip = VideoFileClip(movie_path)
# フォントのパス
font_path = "ヒラギノ角ゴシック W9.ttc"
font_size = 120

# テキストの装飾
text_color = "rgb(195,40,110)"
# 縁取り内側
stroke_in_color = "rgb(255,255,255)"
stroke_in_width = 5
# 縁取り外側
stroke_out_color = "rgb(0,0,0)"
stroke_out_width = 25

# テキストの設定
textlists = [["はい!どうもこんちには!", 0, 2],
             ["ぷそさんです", 2, 4],
             ["よろしくお願いします", 4, 6]]

# テキストの位置を決定(Y軸方向だけ)
text_Y = 800
# 若干位置ずれするので補正
delta_Y = 8

CVCs = []
for textlist in textlists:
    # 縁取り外側
    txtclip_out = TextClip(textlist[0], 
                       font = font_path,
                       fontsize=font_size, 
                       color=text_color,
                       stroke_color=stroke_out_color,
                       stroke_width=stroke_out_width
                      )
    # 縁取り内側
    txtclip_in = TextClip(textlist[0], 
                       font = font_path,
                       fontsize=font_size, 
                       color=text_color,
                       stroke_color=stroke_in_color,
                       stroke_width=stroke_in_width
                      )

    cvc = CompositeVideoClip([clip.subclip(textlist[1],textlist[2]), txtclip_out.set_position(("center",text_Y)),
                             txtclip_in.set_position(("center",text_Y + delta_Y))])
    
    CVCs.append(cvc.set_duration(clip.subclip(textlist[1],textlist[2]).duration))

output_clip = concatenate_videoclips(CVCs)
output_clip.write_videofile("test_output.mp4")

ここで重要なのが,20〜22行目textlists =です!

このtextlists =で,挿入するテキストいつ表示するかを決めています。

具体的には,[挿入するテキスト,表示を開始する秒数,表示を終了する秒数]となります。

["はい!どうもこんちには!", 0, 2]の場合は,0秒から2秒の間に「はい!どうもこんにちは!」と表示します。

この部分を入力した分だけ追加すると,好きなタイミングで字幕を表示することができます。

ただし,以下の点に注意してください!

何も文字がない時間(字幕がいらない時間)については,挿入するテキストを空にして指定する必要があります。

例) 2秒から4秒の間はテロップなし

textlists = [["はい!どうもこんにちは!", 0, 2],
             ["", 2, 4]]

こうすることで,好きな時間にテロップを入力することができます。

つまり,実際に使う場合には,textlists =の部分だけ変えれば大丈夫です!

最後に

Pythonで動画編集をする方法はいかがでしたでしょうか!

これを応用すると,完全に自動でテロップを入れることができます!

例えば,音声認識を機械学習で行って,一言ずつテロップを挿入することも出来ると思います!

他にも,こういう字幕をつけたいといった希望がありましたらコメントで教えてください!

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

このブログでは,PythonやLaTeXの使い方などを紹介しています!
仕事でも趣味でもプログラミングをしています。
ブログは2022年8月にスタートしました。
【経歴】東京大学大学院修了→大手IT企業勤務

コメント

コメントする

目次