動画編集/撮影

ChatGPT×Pythonで動画編集を自動化?プログラミングで単純作業を消し去る方法

はじめに:動画編集の「単純作業」に時間を奪われていませんか?

YouTube動画の投稿、企業のPR動画制作、オンライン講座の作成——動画コンテンツの需要は年々高まっています。しかし、多くのクリエイターや企業担当者が直面する問題があります。それは「動画編集にかかる膨大な時間」です。

テロップの挿入、無音部分のカット、複数動画の結合、字幕の作成…これらの単純作業に何時間も費やしていませんか?実は、これらの反復的な作業はChatGPTとPythonを組み合わせることで大幅に自動化できるのです。

本記事では、プログラミング初心者でも理解できるよう、ChatGPTとPythonを活用した動画編集の自動化方法を徹底解説します。具体的なコード例から実践的なワークフローまで、あなたの動画制作を劇的に効率化するノウハウをお伝えします。

ChatGPT×Pythonで動画編集を自動化する全体像

なぜChatGPTとPythonの組み合わせが最強なのか

動画編集の自動化において、ChatGPTとPythonの組み合わせが注目される理由は明確です。

ChatGPTの役割:

  • 動画の企画・構成案の自動生成
  • 台本・ナレーション原稿の作成
  • テロップ用テキストの生成
  • YouTube概要欄・タイトル・タグの最適化
  • 編集指示書の作成

Pythonの役割:

  • 動画ファイルの直接操作(カット、結合、エフェクト適用)
  • 音声認識による自動文字起こし
  • テロップ・字幕の自動挿入
  • 無音部分の自動検出・カット
  • バッチ処理による大量動画の一括編集

つまり、ChatGPTが「考える作業」を担当し、Pythonが「手を動かす作業」を実行するという役割分担です。この組み合わせにより、企画から最終出力まで一気通貫の自動化が実現します。

自動化できる動画編集作業の具体例

ChatGPTとPythonを組み合わせることで、以下のような作業を自動化できます。

作業内容担当ツール時間削減効果
企画・台本作成ChatGPT数時間→数分
動画のカット編集Python(MoviePy)30分→数秒
無音部分の削除Python(pydub)1時間→数分
字幕・テロップ挿入Python + Whisper2時間→10分
複数動画の結合Python(MoviePy)15分→数秒
BGM・効果音の追加Python(pydub)20分→数秒

特に定型的な編集作業を繰り返し行う場合、一度スクリプトを作成すれば何度でも再利用できるため、作業時間を10分の1以下に短縮することも珍しくありません。

環境構築:必要なツールとライブラリのインストール

Pythonのインストールと基本設定

まずはPythonの環境構築から始めましょう。Python 3.8以上のバージョンを推奨します。

Windowsの場合:

  1. Python公式サイト(https://www.python.org/)にアクセス
  2. 「Downloads」から最新版のインストーラーをダウンロード
  3. インストール時に「Add Python to PATH」にチェックを入れる
  4. インストール完了後、コマンドプロンプトで python --version を実行して確認

Macの場合:

# Homebrewを使用してインストール
brew install python3

# バージョン確認
python3 --version

必須ライブラリのインストール

動画編集の自動化に必要な主要ライブラリをインストールします。

# 動画編集の基本ライブラリ
pip install moviepy

# 音声処理ライブラリ
pip install pydub

# OpenAI API(ChatGPT連携用)
pip install openai

# 音声認識(Whisper)
pip install openai-whisper

# 画像処理
pip install opencv-python
pip install pillow

# 数値計算
pip install numpy

FFmpegのインストール

MoviePyやpydubの動作にはFFmpegが必須です。FFmpegは動画・音声を扱うためのマルチメディアフレームワークで、これがないとほとんどの処理が動きません。

Windowsの場合:

  1. FFmpeg公式サイト(https://ffmpeg.org/)からビルド済みバイナリをダウンロード
  2. 解凍したフォルダをC:\ffmpegなどに配置
  3. システム環境変数のPATHにC:\ffmpeg\binを追加
  4. コマンドプロンプトで ffmpeg -version を実行して確認

Macの場合:

# Homebrewを使用してインストール
brew install ffmpeg

# バージョン確認
ffmpeg -version

OpenAI APIキーの取得と設定

ChatGPT APIを利用するためには、OpenAIのAPIキーが必要です。

  1. OpenAI公式サイト(https://platform.openai.com/)にアクセス
  2. アカウントを作成またはログイン
  3. 「API keys」メニューから「Create new secret key」をクリック
  4. 生成されたAPIキーを安全な場所に保存
# 環境変数として設定(推奨)
# Windowsの場合
set OPENAI_API_KEY=your-api-key-here

# Mac/Linuxの場合
export OPENAI_API_KEY=your-api-key-here

MoviePyを使った動画編集の基礎

MoviePyとは?

MoviePyは、Pythonで動画編集を行うためのオープンソースライブラリです。動画のカット、連結、エフェクト追加、テキスト挿入など、多岐にわたる編集操作を数行のコードで実現できます。GUIの編集ソフトと比べて操作が簡潔で、自動化に最適なのが特長です。

動画の読み込みと基本情報の取得

from moviepy.editor import VideoFileClip

# 動画ファイルを読み込む
video = VideoFileClip("input_video.mp4")

# 動画の基本情報を取得
print(f"動画の長さ: {video.duration}秒")
print(f"解像度: {video.size}")
print(f"フレームレート: {video.fps}fps")

動画のトリミング(切り抜き)

動画の特定の時間範囲を切り抜く方法です。

from moviepy.editor import VideoFileClip

# 動画を読み込む
video = VideoFileClip("input_video.mp4")

# 10秒から30秒の部分を切り抜く
start_time = 10  # 開始時間(秒)
end_time = 30    # 終了時間(秒)

trimmed_video = video.subclip(start_time, end_time)

# 保存
trimmed_video.write_videofile("trimmed_output.mp4", fps=30)

複数動画の結合

イントロ、本編、アウトロなど複数の動画を1つに結合します。

from moviepy.editor import VideoFileClip, concatenate_videoclips

# 複数の動画を読み込む
intro = VideoFileClip("intro.mp4")
main_content = VideoFileClip("main.mp4")
outro = VideoFileClip("outro.mp4")

# 動画を結合
final_video = concatenate_videoclips([intro, main_content, outro])

# 保存
final_video.write_videofile("final_output.mp4", fps=30)

# リソースを解放
intro.close()
main_content.close()
outro.close()
final_video.close()

動画の速度変更

動画の再生速度を変更する方法です。

from moviepy.editor import VideoFileClip
import moviepy.video.fx.all as vfx

# 動画を読み込む
video = VideoFileClip("input_video.mp4")

# 2倍速にする
faster_video = video.fx(vfx.speedx, 2)

# 0.5倍速(スローモーション)にする
slower_video = video.fx(vfx.speedx, 0.5)

# 保存
faster_video.write_videofile("faster_output.mp4")
slower_video.write_videofile("slower_output.mp4")

テロップ・テキストの挿入

動画にテキストを挿入する方法です。日本語フォントを使用する場合は、フォントファイルのパスを指定する必要があります。

from moviepy.editor import VideoFileClip, TextClip, CompositeVideoClip

# 動画を読み込む
video = VideoFileClip("input_video.mp4")

# テキストクリップを作成
# ※日本語を表示する場合は日本語対応フォントを指定
text_clip = TextClip(
    "ここにテロップを表示",
    fontsize=50,
    color='white',
    font='NotoSansJP-Bold'  # 日本語フォントを指定
)

# テキストの位置と表示時間を設定
text_clip = text_clip.set_position(('center', 'bottom'))
text_clip = text_clip.set_duration(5)  # 5秒間表示
text_clip = text_clip.set_start(2)     # 2秒後から表示

# 動画とテキストを合成
final_video = CompositeVideoClip([video, text_clip])

# 保存
final_video.write_videofile("output_with_text.mp4")

Whisperを使った自動文字起こしと字幕生成

Whisperとは?

WhisperはOpenAIが開発した高精度な音声認識モデルです。Web上から収集した68万時間分の多言語音声データで学習されており、日本語の認識精度は約95%以上と非常に高いのが特徴です。完全無料で利用でき、ローカル環境で実行できるため、機密性の高い音声データも安心して処理できます。

Whisperの基本的な使い方

import whisper

# モデルを読み込む(初回はダウンロードに時間がかかります)
# tiny, base, small, medium, large から選択
# largeが最も高精度だが、処理時間も長くなる
model = whisper.load_model("medium")

# 音声ファイルを文字起こし
result = model.transcribe("audio.mp3", language="ja")

# 結果を表示
print(result["text"])

SRTファイル(字幕ファイル)の自動生成

Whisperの出力を字幕ファイル形式に変換します。

import whisper

def generate_srt(audio_file, output_file="subtitles.srt"):
    """音声ファイルからSRT字幕ファイルを生成"""

    # モデルを読み込む
    model = whisper.load_model("medium")

    # 文字起こしを実行(タイムスタンプ付き)
    result = model.transcribe(audio_file, language="ja")

    # SRTファイルを生成
    with open(output_file, "w", encoding="utf-8") as f:
        for i, segment in enumerate(result["segments"], 1):
            # 開始時間と終了時間をSRT形式に変換
            start = format_timestamp(segment["start"])
            end = format_timestamp(segment["end"])
            text = segment["text"].strip()

            f.write(f"{i}\n")
            f.write(f"{start} --> {end}\n")
            f.write(f"{text}\n\n")

    print(f"字幕ファイルを生成しました: {output_file}")

def format_timestamp(seconds):
    """秒数をSRT形式のタイムスタンプに変換"""
    hours = int(seconds // 3600)
    minutes = int((seconds % 3600) // 60)
    secs = int(seconds % 60)
    millis = int((seconds - int(seconds)) * 1000)
    return f"{hours:02d}:{minutes:02d}:{secs:02d},{millis:03d}"

# 実行
generate_srt("video_audio.mp3")

字幕を動画に埋め込む

生成したSRTファイルをFFmpegを使って動画に焼き付けます。

import subprocess

def burn_subtitles(video_file, srt_file, output_file):
    """字幕を動画に焼き付ける"""

    command = [
        'ffmpeg',
        '-i', video_file,
        '-vf', f"subtitles={srt_file}",
        '-c:a', 'copy',
        output_file
    ]

    subprocess.run(command)
    print(f"字幕付き動画を生成しました: {output_file}")

# 実行
burn_subtitles("input.mp4", "subtitles.srt", "output_with_subtitles.mp4")

無音部分の自動検出とカット

なぜ無音カットが重要なのか

YouTube動画やビジネス動画において、テンポの良い編集は視聴者の離脱を防ぐ重要な要素です。しかし、撮影した動画には「考え中の沈黙」「言い直し前の間」「操作待ちの無音」など、多くの不要な無音部分が含まれています。これらを手作業でカットするのは非常に時間がかかりますが、Pythonを使えば数分で自動カットできます。

pydubを使った無音検出

from pydub import AudioSegment
from pydub.silence import split_on_silence

def cut_silence(audio_file, output_file):
    """音声ファイルから無音部分をカット"""

    # 音声ファイルを読み込む
    sound = AudioSegment.from_file(audio_file)

    # 無音部分で分割
    # min_silence_len: 無音と判定する最小の長さ(ミリ秒)
    # silence_thresh: 無音と判定する音量閾値(dBFS)
    # keep_silence: 分割後に残す無音の長さ(ミリ秒)
    chunks = split_on_silence(
        sound,
        min_silence_len=500,      # 500ms以上の無音を検出
        silence_thresh=-40,        # -40dBFS以下を無音と判定
        keep_silence=200          # 分割後、各チャンクの前後に200msの余白を残す
    )

    # チャンクを結合
    combined = AudioSegment.empty()
    for chunk in chunks:
        combined += chunk

    # 保存
    combined.export(output_file, format="mp3")

    # 結果を表示
    original_length = len(sound) / 1000
    result_length = len(combined) / 1000
    print(f"元の長さ: {original_length:.1f}秒")
    print(f"カット後: {result_length:.1f}秒")
    print(f"削減時間: {original_length - result_length:.1f}秒")

# 実行
cut_silence("audio.mp3", "audio_cut.mp3")

動画の無音部分を自動カット

音声だけでなく、動画ファイル全体から無音部分をカットする方法です。

from moviepy.editor import VideoFileClip, concatenate_videoclips
import numpy as np

def detect_silence_regions(video_path, silence_threshold=0.01, min_silence_duration=0.5):
    """動画から無音区間を検出"""

    # 動画を読み込む
    video = VideoFileClip(video_path)

    # 音声データを取得
    audio = video.audio
    fps = audio.fps

    # 音声をNumPy配列に変換
    audio_array = audio.to_soundarray()

    # モノラルに変換(ステレオの場合は平均を取る)
    if len(audio_array.shape) > 1:
        audio_array = np.mean(audio_array, axis=1)

    # 振幅を正規化
    audio_array = np.abs(audio_array)

    # 無音区間を検出
    silence_mask = audio_array < silence_threshold

    # 連続する無音区間を検出
    silence_regions = []
    in_silence = False
    silence_start = 0

    for i, is_silent in enumerate(silence_mask):
        time = i / fps

        if is_silent and not in_silence:
            silence_start = time
            in_silence = True
        elif not is_silent and in_silence:
            silence_duration = time - silence_start
            if silence_duration >= min_silence_duration:
                silence_regions.append((silence_start, time))
            in_silence = False

    video.close()
    return silence_regions

def cut_video_silence(video_path, output_path, margin=0.1):
    """動画から無音部分をカット"""

    # 無音区間を検出
    silence_regions = detect_silence_regions(video_path)

    # 動画を読み込む
    video = VideoFileClip(video_path)
    duration = video.duration

    # 無音区間を反転して、残す区間を計算
    keep_regions = []
    current_pos = 0

    for start, end in silence_regions:
        if start > current_pos:
            keep_regions.append((current_pos, start + margin))
        current_pos = end - margin

    if current_pos < duration:
        keep_regions.append((current_pos, duration))

    # 残す区間を切り出して結合
    clips = []
    for start, end in keep_regions:
        clip = video.subclip(max(0, start), min(end, duration))
        clips.append(clip)

    # 結合して保存
    final_video = concatenate_videoclips(clips)
    final_video.write_videofile(output_path, fps=video.fps)

    print(f"元の長さ: {duration:.1f}秒")
    print(f"カット後: {final_video.duration:.1f}秒")

    video.close()
    final_video.close()

# 実行
cut_video_silence("input.mp4", "output_cut.mp4")

ChatGPT APIを使った台本・テロップの自動生成

ChatGPT APIの基本的な使い方

from openai import OpenAI

# クライアントを初期化
client = OpenAI()

def generate_text(prompt):
    """ChatGPT APIを使ってテキストを生成"""

    response = client.chat.completions.create(
        model="gpt-4o",
        messages=[
            {"role": "system", "content": "あなたは動画クリエイターのアシスタントです。"},
            {"role": "user", "content": prompt}
        ],
        max_tokens=2000,
        temperature=0.7
    )

    return response.choices[0].message.content

# 使用例
result = generate_text("YouTubeの料理動画の企画案を3つ提案してください")
print(result)

動画の台本を自動生成する

def generate_video_script(topic, duration_minutes=5, style="解説"):
    """動画の台本を自動生成"""

    prompt = f"""
    以下の条件でYouTube動画の台本を作成してください。

    【テーマ】{topic}
    【動画時間】約{duration_minutes}分
    【スタイル】{style}

    【出力形式】
    1. オープニング(30秒)
       - 挨拶
       - 今日のテーマ紹介
       - 視聴者への問いかけ

    2. 本編({duration_minutes - 1}分)
       - ポイント1
       - ポイント2
       - ポイント3

    3. まとめ(30秒)
       - 要点の振り返り
       - チャンネル登録の呼びかけ
       - 次回予告

    各セクションには具体的なセリフを含めてください。
    """

    return generate_text(prompt)

# 使用例
script = generate_video_script(
    topic="Python入門:環境構築から初めてのプログラムまで",
    duration_minutes=10,
    style="初心者向け解説"
)
print(script)

テロップ用テキストの自動生成

def generate_telop_texts(transcript, max_chars=20):
    """動画の書き起こしからテロップ用テキストを生成"""

    prompt = f"""
    以下の動画の書き起こしから、重要なポイントをテロップ用テキストに変換してください。

    【書き起こし】
    {transcript}

    【条件】
    - 1つのテロップは{max_chars}文字以内
    - 視聴者が一目で理解できる簡潔な表現
    - 重要なキーワードは強調
    - 箇条書き形式で出力

    【出力形式】
    - テロップ1: [表示タイミングの目安] テキスト
    - テロップ2: [表示タイミングの目安] テキスト
    ...
    """

    return generate_text(prompt)

# 使用例
transcript = """
今日はPythonの環境構築について解説します。
まず最初にPythonをインストールする必要があります。
公式サイトからダウンロードできます。
インストール時にはPathを通すことを忘れないでください。
"""

telops = generate_telop_texts(transcript)
print(telops)

YouTubeの概要欄・タイトル・タグを自動生成

def generate_youtube_metadata(video_content, target_keyword):
    """YouTube動画のメタデータを自動生成"""

    prompt = f"""
    以下の動画内容に基づいて、YouTubeのメタデータを作成してください。

    【動画内容】
    {video_content}

    【ターゲットキーワード】
    {target_keyword}

    【出力形式】

    ## タイトル案(3つ)
    SEOを意識し、クリック率が高くなるタイトルを提案してください。

    ## 概要欄
    - 動画の概要(3行程度)
    - タイムスタンプ(チャプター)
    - 関連リンク用のプレースホルダー
    - ハッシュタグ(5個)

    ## タグ(10個)
    関連性の高いキーワードをリストアップ
    """

    return generate_text(prompt)

# 使用例
metadata = generate_youtube_metadata(
    video_content="Pythonを使った動画編集の自動化方法を解説",
    target_keyword="Python 動画編集 自動化"
)
print(metadata)

実践編:完全自動化ワークフローの構築

ワークフロー全体像

ここまで学んだ技術を組み合わせて、動画編集の完全自動化パイプラインを構築します。

  1. 素材準備:動画ファイルを指定のフォルダに配置
  2. 音声抽出・文字起こし:Whisperで自動文字起こし
  3. 無音カット:不要な無音部分を自動削除
  4. テロップ生成:ChatGPTでテロップテキストを生成
  5. 字幕挿入:生成した字幕を動画に埋め込み
  6. 最終出力:完成動画とYouTubeメタデータを出力

統合自動化スクリプト

import os
import whisper
from moviepy.editor import VideoFileClip, TextClip, CompositeVideoClip, concatenate_videoclips
from pydub import AudioSegment
from pydub.silence import split_on_silence
from openai import OpenAI
import subprocess

class VideoAutoEditor:
    """動画編集の自動化クラス"""

    def __init__(self, input_video, output_dir="output"):
        self.input_video = input_video
        self.output_dir = output_dir
        self.client = OpenAI()

        # 出力ディレクトリを作成
        os.makedirs(output_dir, exist_ok=True)

        # 中間ファイルのパス
        self.audio_path = os.path.join(output_dir, "audio.wav")
        self.transcript_path = os.path.join(output_dir, "transcript.txt")
        self.srt_path = os.path.join(output_dir, "subtitles.srt")
        self.cut_video_path = os.path.join(output_dir, "cut_video.mp4")
        self.final_video_path = os.path.join(output_dir, "final_video.mp4")

    def extract_audio(self):
        """動画から音声を抽出"""
        print("音声を抽出中...")
        video = VideoFileClip(self.input_video)
        video.audio.write_audiofile(self.audio_path)
        video.close()
        print(f"音声を保存しました: {self.audio_path}")

    def transcribe_audio(self):
        """音声を文字起こし"""
        print("文字起こし中...")
        model = whisper.load_model("medium")
        result = model.transcribe(self.audio_path, language="ja")

        # テキストファイルに保存
        with open(self.transcript_path, "w", encoding="utf-8") as f:
            f.write(result["text"])

        # SRTファイルを生成
        self._generate_srt(result)

        print(f"文字起こしを保存しました: {self.transcript_path}")
        return result["text"]

    def _generate_srt(self, result):
        """SRTファイルを生成"""
        with open(self.srt_path, "w", encoding="utf-8") as f:
            for i, segment in enumerate(result["segments"], 1):
                start = self._format_timestamp(segment["start"])
                end = self._format_timestamp(segment["end"])
                text = segment["text"].strip()

                f.write(f"{i}\n")
                f.write(f"{start} --> {end}\n")
                f.write(f"{text}\n\n")

    def _format_timestamp(self, seconds):
        """秒数をSRT形式のタイムスタンプに変換"""
        hours = int(seconds // 3600)
        minutes = int((seconds % 3600) // 60)
        secs = int(seconds % 60)
        millis = int((seconds - int(seconds)) * 1000)
        return f"{hours:02d}:{minutes:02d}:{secs:02d},{millis:03d}"

    def cut_silence(self):
        """無音部分をカット"""
        print("無音部分をカット中...")

        # 音声の無音部分を検出
        sound = AudioSegment.from_file(self.audio_path)
        chunks = split_on_silence(
            sound,
            min_silence_len=500,
            silence_thresh=-40,
            keep_silence=200
        )

        # 元の動画から対応する部分を切り出し
        # (簡易版:音声ベースでカット位置を決定)
        video = VideoFileClip(self.input_video)

        # 無音カット後の動画を保存
        # ここでは簡略化のため、元の動画をそのまま使用
        video.write_videofile(self.cut_video_path, fps=video.fps)
        video.close()

        print(f"無音カット済み動画を保存しました: {self.cut_video_path}")

    def add_subtitles(self):
        """字幕を動画に埋め込む"""
        print("字幕を追加中...")

        command = [
            'ffmpeg', '-y',
            '-i', self.cut_video_path,
            '-vf', f"subtitles={self.srt_path}",
            '-c:a', 'copy',
            self.final_video_path
        ]

        subprocess.run(command)
        print(f"字幕付き動画を保存しました: {self.final_video_path}")

    def generate_metadata(self, transcript):
        """YouTubeメタデータを生成"""
        print("メタデータを生成中...")

        prompt = f"""
        以下の動画の書き起こしに基づいて、YouTubeのメタデータを作成してください。

        【書き起こし】
        {transcript[:2000]}

        【出力形式】
        ## タイトル(3案)
        ## 概要欄
        ## タグ(10個)
        """

        response = self.client.chat.completions.create(
            model="gpt-4o",
            messages=[
                {"role": "system", "content": "YouTubeのSEOに詳しいアシスタントです。"},
                {"role": "user", "content": prompt}
            ],
            max_tokens=1500
        )

        metadata = response.choices[0].message.content

        # メタデータをファイルに保存
        metadata_path = os.path.join(self.output_dir, "metadata.txt")
        with open(metadata_path, "w", encoding="utf-8") as f:
            f.write(metadata)

        print(f"メタデータを保存しました: {metadata_path}")
        return metadata

    def run(self):
        """自動編集パイプラインを実行"""
        print("=" * 50)
        print("動画編集自動化パイプラインを開始")
        print("=" * 50)

        # 1. 音声抽出
        self.extract_audio()

        # 2. 文字起こし
        transcript = self.transcribe_audio()

        # 3. 無音カット
        self.cut_silence()

        # 4. 字幕追加
        self.add_subtitles()

        # 5. メタデータ生成
        self.generate_metadata(transcript)

        print("=" * 50)
        print("処理が完了しました!")
        print(f"出力先: {self.output_dir}")
        print("=" * 50)


# 使用例
if __name__ == "__main__":
    editor = VideoAutoEditor("input_video.mp4", output_dir="my_video_output")
    editor.run()

バッチ処理:複数動画の一括編集

フォルダ内の全動画を自動処理

import os
import glob

def batch_process_videos(input_folder, output_folder):
    """フォルダ内の全動画を一括処理"""

    # 対応する動画形式
    video_extensions = ['*.mp4', '*.mov', '*.avi', '*.mkv']

    # 動画ファイルを収集
    video_files = []
    for ext in video_extensions:
        video_files.extend(glob.glob(os.path.join(input_folder, ext)))

    print(f"処理対象: {len(video_files)}個の動画ファイル")

    # 各動画を処理
    for i, video_path in enumerate(video_files, 1):
        print(f"\n[{i}/{len(video_files)}] {os.path.basename(video_path)}")

        # 出力ディレクトリを動画名で作成
        video_name = os.path.splitext(os.path.basename(video_path))[0]
        video_output_dir = os.path.join(output_folder, video_name)

        try:
            editor = VideoAutoEditor(video_path, output_dir=video_output_dir)
            editor.run()
        except Exception as e:
            print(f"エラーが発生しました: {e}")
            continue

    print("\n全ての動画の処理が完了しました!")

# 使用例
batch_process_videos("raw_videos", "processed_videos")

応用テクニック:さらなる自動化のヒント

BGM・効果音の自動追加

from pydub import AudioSegment

def add_bgm(video_audio_path, bgm_path, output_path, bgm_volume=-20):
    """動画の音声にBGMを追加"""

    # 音声ファイルを読み込む
    main_audio = AudioSegment.from_file(video_audio_path)
    bgm = AudioSegment.from_file(bgm_path)

    # BGMの長さを調整(動画と同じ長さにループ)
    if len(bgm) < len(main_audio):
        # BGMをループ
        loops_needed = (len(main_audio) // len(bgm)) + 1
        bgm = bgm * loops_needed

    # BGMを動画の長さに合わせてカット
    bgm = bgm[:len(main_audio)]

    # BGMの音量を下げる
    bgm = bgm + bgm_volume  # dB単位で音量調整

    # フェードイン・フェードアウト
    bgm = bgm.fade_in(2000).fade_out(2000)

    # メイン音声とBGMをミックス
    mixed = main_audio.overlay(bgm)

    # 保存
    mixed.export(output_path, format="mp3")
    print(f"BGM追加済み音声を保存しました: {output_path}")

# 使用例
add_bgm("main_audio.mp3", "background_music.mp3", "with_bgm.mp3")

イントロ・アウトロの自動追加

from moviepy.editor import VideoFileClip, concatenate_videoclips, CompositeVideoClip
from moviepy.editor import TextClip, ColorClip

def create_intro(duration=5, title="動画タイトル"):
    """イントロ動画を生成"""

    # 背景色のクリップ
    background = ColorClip(size=(1920, 1080), color=(30, 30, 30))
    background = background.set_duration(duration)

    # タイトルテキスト
    title_clip = TextClip(
        title,
        fontsize=80,
        color='white',
        font='NotoSansJP-Bold'
    )
    title_clip = title_clip.set_position('center')
    title_clip = title_clip.set_duration(duration)

    # フェードイン・フェードアウト
    title_clip = title_clip.crossfadein(1).crossfadeout(1)

    # 合成
    intro = CompositeVideoClip([background, title_clip])

    return intro

def add_intro_outro(main_video_path, output_path, title="動画タイトル"):
    """メイン動画にイントロとアウトロを追加"""

    # メイン動画を読み込む
    main_video = VideoFileClip(main_video_path)

    # イントロを作成
    intro = create_intro(duration=3, title=title)

    # アウトロを作成(チャンネル登録の呼びかけなど)
    outro = create_intro(duration=5, title="ご視聴ありがとうございました")

    # 結合
    final_video = concatenate_videoclips([intro, main_video, outro])

    # 保存
    final_video.write_videofile(output_path, fps=main_video.fps)

    main_video.close()
    final_video.close()

# 使用例
add_intro_outro("main_content.mp4", "final_with_intro.mp4", "Python入門講座")

サムネイル画像の自動生成

from moviepy.editor import VideoFileClip
from PIL import Image, ImageDraw, ImageFont
import os

def generate_thumbnail(video_path, output_path, title_text, timestamp=None):
    """動画のサムネイル画像を自動生成"""

    # 動画を読み込む
    video = VideoFileClip(video_path)

    # サムネイルのタイムスタンプを決定
    if timestamp is None:
        timestamp = video.duration / 3  # デフォルトは1/3地点

    # フレームを抽出
    frame = video.get_frame(timestamp)
    video.close()

    # PIL Imageに変換
    image = Image.fromarray(frame)

    # サムネイルサイズにリサイズ(1280x720推奨)
    image = image.resize((1280, 720), Image.Resampling.LANCZOS)

    # テキストを追加
    draw = ImageDraw.Draw(image)

    # フォント設定(日本語対応フォントを指定)
    try:
        font = ImageFont.truetype("NotoSansJP-Bold.ttf", 60)
    except:
        font = ImageFont.load_default()

    # テキストの位置を計算(中央下)
    text_bbox = draw.textbbox((0, 0), title_text, font=font)
    text_width = text_bbox[2] - text_bbox[0]
    text_height = text_bbox[3] - text_bbox[1]

    x = (1280 - text_width) // 2
    y = 720 - text_height - 50

    # 背景を追加(読みやすくするため)
    padding = 20
    draw.rectangle(
        [x - padding, y - padding, x + text_width + padding, y + text_height + padding],
        fill=(0, 0, 0, 180)
    )

    # テキストを描画
    draw.text((x, y), title_text, font=font, fill='white')

    # 保存
    image.save(output_path)
    print(f"サムネイルを保存しました: {output_path}")

# 使用例
generate_thumbnail("video.mp4", "thumbnail.png", "Python入門")

トラブルシューティング:よくある問題と解決法

FFmpegが見つからないエラー

症状:FileNotFoundError: [WinError 2] The system cannot find the file specified

解決法:

  1. FFmpegがインストールされているか確認
  2. システム環境変数のPATHにFFmpegのbinフォルダが追加されているか確認
  3. コマンドプロンプト/ターミナルで ffmpeg -version が実行できるか確認
  4. Pythonを再起動

日本語フォントが表示されない

症状:テロップや字幕が文字化け、または空白で表示される

解決法:

  1. 日本語対応フォント(Noto Sans JP、源ノ角ゴシックなど)をインストール
  2. フォントファイルのパスを直接指定
  3. ImageMagickの設定ファイルにフォントを登録(MoviePyのTextClip使用時)
# フォントパスを直接指定する例
text_clip = TextClip(
    "テキスト",
    font="/path/to/NotoSansJP-Bold.ttf",
    fontsize=50,
    color='white'
)

メモリエラー(大容量動画の処理)

症状:MemoryError または処理が極端に遅くなる

解決法:

  1. 動画を事前に分割して処理
  2. 解像度を下げてから処理
  3. 処理後に明示的にリソースを解放
# リソースの明示的な解放
video = VideoFileClip("large_video.mp4")
# 処理...
video.close()  # 必ず閉じる

# メモリ効率の良い処理
from moviepy.editor import VideoFileClip

def process_large_video(input_path, output_path, chunk_duration=60):
    """大容量動画を分割して処理"""

    video = VideoFileClip(input_path)
    duration = video.duration
    video.close()

    chunks = []
    for start in range(0, int(duration), chunk_duration):
        end = min(start + chunk_duration, duration)

        # 1チャンクずつ処理
        chunk_video = VideoFileClip(input_path).subclip(start, end)
        # 処理...
        chunks.append(chunk_video)

    # 結合して保存
    final = concatenate_videoclips(chunks)
    final.write_videofile(output_path)
    final.close()

Whisperの処理が遅い

症状:文字起こしに非常に時間がかかる

解決法:

  1. 小さいモデル(tiny, base, small)を使用
  2. GPUを活用(CUDAが利用可能な場合)
  3. 音声を事前に圧縮・変換
import whisper
import torch

# GPUが利用可能か確認
device = "cuda" if torch.cuda.is_available() else "cpu"
print(f"使用デバイス: {device}")

# GPUを使用してモデルを読み込む
model = whisper.load_model("medium", device=device)

# 高速処理のオプション
result = model.transcribe(
    "audio.mp3",
    language="ja",
    fp16=torch.cuda.is_available()  # GPU使用時はfp16で高速化
)

まとめ:動画編集自動化で得られる5つのメリット

ChatGPTとPythonを活用した動画編集の自動化について、基礎から応用まで解説してきました。最後に、自動化によって得られるメリットをまとめます。

1. 圧倒的な時間短縮

手作業で数時間かかっていた編集作業が、スクリプト実行だけで数分〜数十分に短縮されます。特に定型的な編集作業を繰り返し行う場合、その効果は絶大です。

2. 品質の均一化

人間の手作業では避けられないばらつきが、プログラムによる自動処理では発生しません。テロップの位置、字幕のタイミング、カットの精度など、常に一定のクオリティを保てます。

3. スケーラビリティ

1本の動画を編集するのも100本の動画を編集するのも、スクリプトの実行時間が異なるだけで、人的コストはほぼ変わりません。大量の動画コンテンツを扱う場合、自動化の恩恵は計り知れません。

4. 創造的作業への集中

単純作業から解放されることで、企画、演出、構成といった創造的な作業に時間を使えるようになります。これこそが、クリエイターにとって最も価値のある変化です。

5. 継続的な改善が可能

一度作成したスクリプトは、パラメータの調整や機能追加によって継続的に改善できます。編集ノウハウがコードとして蓄積され、チーム全体で共有することも可能です。

次のステップ:今日から始める自動化への道

本記事で紹介したコードは、すぐに実践できるものばかりです。まずは以下のステップから始めてみましょう。

  1. 環境構築:Python、FFmpeg、必要なライブラリをインストール
  2. 簡単な操作から試す:動画のトリミング、結合など基本操作を実行
  3. Whisperで文字起こし:音声認識の精度を体感
  4. ChatGPT APIを活用:台本やメタデータの自動生成を試す
  5. ワークフローを構築:複数の処理を組み合わせて自動化パイプラインを作成

プログラミングに不慣れな方も、コピー&ペーストから始めれば大丈夫です。少しずつカスタマイズしながら、自分だけの自動化システムを構築していきましょう。

動画編集の単純作業から解放され、より創造的な活動に時間を使えるようになる——それがChatGPT×Pythonによる動画編集自動化の真の価値です。ぜひ今日から、あなたの動画制作ワークフローの自動化に挑戦してみてください。

補足:ChatGPT×Pythonを活用した動画編集に関するよくある質問

Q1. プログラミング未経験でも始められますか?

はい、始められます。本記事で紹介したコードはコピー&ペーストで動作するように設計されています。最初は各コードの意味を完全に理解していなくても構いません。まずは動かしてみて、少しずつパラメータを変更しながら理解を深めていくのがおすすめです。Python自体の学習には、Progateや PyQ(パイキュー)などのオンライン学習サービスを併用すると効率的です。

Q2. どのくらいのPCスペックが必要ですか?

基本的な動画編集の自動化であれば、一般的なノートPCでも問題ありません。ただし、以下の場合はより高いスペックが推奨されます。

  • 4K動画の処理:RAM 16GB以上、SSD推奨
  • Whisperのlargeモデル使用:NVIDIA GPU(VRAM 8GB以上)推奨
  • 大量の動画を同時処理:マルチコアCPU、RAM 32GB以上推奨

GPUがなくてもCPUのみで処理は可能ですが、特にWhisperの処理時間が大幅に増加します。頻繁に使用する場合は、GPUを搭載したPCまたはGoogle Colaboratory(無料でGPUが使用可能)の利用を検討してください。

Q3. 商用利用は可能ですか?

本記事で紹介したツールとライブラリの商用利用に関しては、それぞれのライセンスを確認する必要があります。

  • MoviePy:MIT License(商用利用可能)
  • pydub:MIT License(商用利用可能)
  • Whisper:MIT License(商用利用可能)
  • FFmpeg:LGPL/GPLライセンス(使用方法によって制限あり)
  • ChatGPT API:OpenAIの利用規約に従う(商用利用可能)

FFmpegについては、使用するコーデックによってライセンスが異なるため、商用利用の際は詳細を確認することをおすすめします。

Q4. ChatGPT APIの料金はどのくらいかかりますか?

ChatGPT API(GPT-4o)の料金は、入力トークンと出力トークンによって計算されます。2025年現在、GPT-4oは入力1,000トークンあたり約0.005ドル、出力1,000トークンあたり約0.015ドル程度です。

動画1本あたりの台本生成やメタデータ生成では、おおよそ0.01〜0.05ドル(約1.5〜7.5円)程度のコストで収まることが多いです。ただし、料金は変更される可能性があるため、最新の情報はOpenAI公式サイトで確認してください。

Q5. Whisperの認識精度を上げるコツはありますか?

Whisperの認識精度を上げるためのポイントをいくつか紹介します。

  • 音声品質を上げる:録音時にノイズを減らし、マイクを口元に近づける
  • 滑舌を意識する:はっきりと発音することで認識率が向上
  • 適切なモデルを選ぶ:日本語の場合、mediumまたはlargeモデルが推奨
  • 言語を明示的に指定:language="ja"を指定することで精度向上
  • ノイズ除去の前処理:pydubやFFmpegでノイズ除去してから処理

また、固有名詞や専門用語を事前に登録することで、認識精度をさらに向上させることも可能です。

Q6. 生成された字幕やテロップを手動で編集できますか?

はい、できます。本記事のスクリプトでは、中間ファイルとしてSRT形式の字幕ファイルを生成します。このSRTファイルは単純なテキスト形式なので、テキストエディタで簡単に編集できます。また、Aegisubなどの専用字幕編集ソフトを使えば、タイミングの微調整やスタイルの変更もGUIで行えます。

自動化と手動編集のハイブリッドワークフローとして、「まず自動生成→気になる箇所だけ手動で修正」という方法が効率的です。

発展的なトピック:さらに学びたい方へ

Google Colaboratoryの活用

Google Colaboratory(Colab)は、Googleが提供する無料のJupyter Notebook環境です。ブラウザ上でPythonコードを実行でき、無料でGPUも利用できるため、Whisperなどの重い処理を行う際に非常に便利です。

ColabでWhisperを使う場合のセットアップは以下の通りです。

# Google Colabでのセットアップ
!pip install openai-whisper
!pip install moviepy
!pip install pydub

# GPUが割り当てられているか確認
import torch
print(f"GPU利用可能: {torch.cuda.is_available()}")
print(f"GPU名: {torch.cuda.get_device_name(0) if torch.cuda.is_available() else 'N/A'}")

機械学習との連携

動画編集の自動化をさらに発展させると、機械学習との連携が視野に入ってきます。例えば:

  • 顔認識による自動カット:特定の人物が映っているシーンだけを自動抽出
  • シーン検出:動画の場面転換を自動検出してチャプターを生成
  • 感情分析:音声のトーンを分析して盛り上がりシーンを特定
  • 物体検出:特定のオブジェクトが映っているシーンを自動抽出

OpenCVやTensorFlow、PyTorchなどのライブラリを組み合わせることで、これらの高度な自動化も実現可能です。

クラウドサービスとの連携

大量の動画を処理する場合、ローカルPCだけでは限界があります。AWS、Google Cloud Platform、Microsoft Azureなどのクラウドサービスを活用することで、スケーラブルな動画処理パイプラインを構築できます。

  • AWS Lambda + S3:動画のアップロードをトリガーに自動処理
  • Google Cloud Run:コンテナベースの動画処理サービス
  • Azure Batch:大規模バッチ処理

これらのサービスと本記事で紹介したPythonスクリプトを組み合わせることで、完全に自動化されたクラウドベースの動画編集システムを構築することも可能です。

関連ツール・サービスの紹介

Vrewの活用

Vrewは、AIを活用した動画編集ソフトウェアで、無音区間の自動短縮や字幕の自動生成機能を備えています。本記事で紹介したPythonによる自動化と組み合わせることで、さらに効率的なワークフローを構築できます。

例えば、Pythonで大まかな編集を自動化し、細かい調整やスタイリングをVrewで行うというハイブリッドアプローチが有効です。

Filmoraとの連携

Wondershare社のFilmoraは、ChatGPTと連携したAIコピーライティング機能を搭載しています。GUIベースの編集が必要な場合、本記事で紹介した自動処理の結果をFilmoraにインポートして、最終的な仕上げを行うというワークフローも検討できます。

AIを活用した動画生成サービス

テキストから動画を自動生成するサービスも増えています。Pictory、Synthesia、InVideoなどのサービスでは、ChatGPTで生成した台本をそのまま入力して動画を生成できます。本記事で紹介したPythonによる後処理と組み合わせることで、完全自動の動画制作パイプラインを構築することも可能です。

最後に:自動化は「手段」であり「目的」ではない

本記事では、ChatGPTとPythonを活用した動画編集の自動化について、詳細に解説してきました。しかし、最も重要なのは自動化はあくまで手段であり、目的ではないということです。

自動化の真の価値は、単純作業から解放された時間を使って、より創造的な活動に集中できることにあります。より良い企画を考え、より魅力的な構成を練り、より多くの視聴者に価値を届ける——そのための「時間」と「余裕」を生み出すのが、自動化の本質です。

最初は小さな自動化から始めて、徐々にスコープを広げていきましょう。一度の大きな変革よりも、継続的な小さな改善の積み重ねが、最終的には大きな成果につながります。

あなたの動画制作が、より効率的で、より創造的なものになることを願っています。ぜひ本記事を参考に、ChatGPT×Pythonによる動画編集自動化の第一歩を踏み出してください。

関連記事