Pythonで動画に字幕を付ける方法! | Pythonで動画編集をする

2021年9月3日金曜日

Python 動画

t f B! P L

今回の内容

今回はPythonで字幕をつけたいと思います。
動画編集編は、この記事に他にもあるので、ぜひ見に行ってください!

使うライブラリ

今回はffmpegを使わずにcv2やPillowをつかって編集します。
import sys
import numpy as np
import os
import ffmpeg
from PIL import ImageFont, ImageDraw, Image
from pydub import AudioSegment
import cv2
import subprocess

text = "SubTitle"
file_path = "input.mp4"
save_path = "output.mp4"
toTime = 2
fromTime = 10

#動画の情報を取得する
cap = cv2.VideoCapture(file_path)
fps = cap.get(cv2.CAP_PROP_FPS)
width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
fourcc = cv2.VideoWriter_fourcc('m', 'p', '4', 'v')
out = cv2.VideoWriter("tmp.mp4" ,fourcc, fps, (width, height))
i = 0

#一コマ一コマ取り出し、Pillowで画像として編集
while True:
    ret, frame = cap.read()
    if ret:
        frame_rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
        pil_image = Image.fromarray(frame_rgb)
        draw = ImageDraw.Draw(pil_image)
        if i <= fromTime*fps and i >= toTime*fps:
            font = ImageFont.truetype('C:\\Windows\\Fonts\\HGRGE.TTC', 40)
            draw.text((50, 300), text, font=font)
        rgb_image = cv2.cvtColor(np.array(pil_image), cv2.COLOR_RGB2BGR)
        out.write(rgb_image)
        i=i+1
        print(cap.get(cv2.CAP_PROP_FRAME_COUNT),"/",i)
    else:
        break

cap.release()
out.release()

#このままだと音声がないため、音声と合体する
subprocess.run("ffmpeg -i " + file_path + " audio.wav -c copy")
print("音声への変換完了")
s1 = ffmpeg.input("tmp.mp4")
s2 = ffmpeg.input("audio.wav")
s = ffmpeg.output(s1,s2,save_path, vcodec="copy", acodec="aac")
ffmpeg.run(s)
os.remove("audio.wav")
os.remove("tmp.mp4")
print("全て完了")

解説

#一コマ一コマ取り出し、Pillowで画像として編集
while True:
    ret, frame = cap.read()
    if ret:
        frame_rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
        pil_image = Image.fromarray(frame_rgb)
        draw = ImageDraw.Draw(pil_image)
        if i <= fromTime*fps and i >= toTime*fps:
            font = ImageFont.truetype('C:\\Windows\\Fonts\\HGRGE.TTC', 40)
            draw.text((50, 300), text, font=font)
        rgb_image = cv2.cvtColor(np.array(pil_image), cv2.COLOR_RGB2BGR)
        out.write(rgb_image)
        i=i+1
        print(cap.get(cv2.CAP_PROP_FRAME_COUNT),"/",i)
    else:
        break
一コマ一コマ分けるコードの中でも
        frame_rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
        pil_image = Image.fromarray(frame_rgb)
        draw = ImageDraw.Draw(pil_image)
        if i <= fromTime*fps and i >= toTime*fps:
            font = ImageFont.truetype('C:\\Windows\\Fonts\\HGRGE.TTC', 40)
            draw.text((50, 300), text, font=font)
        rgb_image = cv2.cvtColor(np.array(pil_image), cv2.COLOR_RGB2BGR)
        out.write(rgb_image)
この部分です。最初にPillowの画像に変換し、そのあとにその画像を編集します。
draw.textでテキストを挿入できます。
やろうと思えば画像も描画できるので、今度別の記事で紹介したいと思います。
truetypeでフォントも指定できます。


そして、音声とかのコード
#このままだと音声がないため、音声と合体する
subprocess.run("ffmpeg -i " + file_path + " audio.wav -c copy")
print("音声への変換完了")
s1 = ffmpeg.input("tmp.mp4")
s2 = ffmpeg.input("audio.wav")
s = ffmpeg.output(s1,s2,save_path, vcodec="copy", acodec="aac")
ffmpeg.run(s)
os.remove("audio.wav")
os.remove("tmp.mp4")
の部分では最初に動画をwav形式に変換します。(subprocessでやらないとなぜかできない)
そしてから、音声と動画を合体させています。



とりあえずここまで。うまくいかなかったらコメントよろしく!

このブログを検索

要望について

ブログのレイアウトやテーマについての提案をいただきました。現在qooqテーマを適応中です。 語尾を自動でつけるプログラムを作りたいという要望をいただきました。是非紹介したいですがどの言語でどのようなプログラムかなど、お問い合わせフォームで詳しく教えてください!

最近の出来事

最近の出来事
寿司打お勧め75位♪(練習モードだけど)

アンケート

Welcome!

「プログラミング独学ブログ」へようこそ。 Yakinyといいます。幅広い範囲で投稿していますので、ぜひ過去の記事も見てみてください!!コメントも大歓迎です!更新がとまってしまって申し訳ございません

お問い合わせ

名前

メール *

メッセージ *

QooQ