FFmpegを使って短い動画を連結する

環境:Python 3.13.11, FFmpeg 8.0.1, WAN2.2, Z-Image Turbo

WAN2.2で生成した短い動画をとりあえず通しで見てみたいことがあったので、簡単に連結する仕組みを作りました。

640 x 480 24fps
Z-Image Turboで生成した油絵風の絵をWAN2.2で3秒の動画にし、それらを連結して音楽を乗せた動画。

動画の入っているフォルダにPythonスクリプトとバッチファイルを置き、これを起動することで名前順に連結した動画ファイルを生成する、という単純なものを作る。

movies/
├─ 001.mp4
├─ 002.mp4
├─ 003.mp4
├─ concat.py
└─ concat.bat   ← ダブルクリック

FFmpegをインストールする

動画編集では定番のFFmpegを使います。Windows環境ならwingetを使うインストールがお手軽。インストーラを使う必要がなく、PATHも自動設定される。

ターミナルから

winget install ffmpeg

インストール後の確認

ffmpeg -version

動画を連結する

concat.py

Pythonファイルの中身のコード。※ChatGPTに書いてもらいました。

from pathlib import Path
import subprocess
import shutil
import sys

# このスクリプト自身が置かれているフォルダのパス
BASE_DIR = Path(__file__).parent

# 出力される結合後の動画ファイル
OUTPUT_FILE = BASE_DIR / "output.mp4"

# ffmpeg の concat 用に使う「ファイル一覧テキスト」
LIST_FILE = BASE_DIR / "concat_list.txt"

# ----------------------------------------
# ffmpeg が PATH に存在するかチェック
# ----------------------------------------
if not shutil.which("ffmpeg"):
    input("ffmpeg が見つかりません。Enterで終了")
    sys.exit(1)

# ----------------------------------------
# このフォルダ内の mp4 ファイルを取得
# output.mp4(出力ファイル)は除外
# ----------------------------------------
mp4_files = sorted(
    f for f in BASE_DIR.glob("*.mp4")
    if f.name != OUTPUT_FILE.name
)

# mp4 が1つもなければ終了
if not mp4_files:
    input("mp4 ファイルが見つかりません。Enterで終了")
    sys.exit(1)

# ----------------------------------------
# ffmpeg concat 用のリストファイルを作成
# ----------------------------------------
with open(LIST_FILE, "w", encoding="utf-8") as f:
    for mp4 in mp4_files:
        # ffmpeg concat デマルチプレクサ用の書式
        # file 'パス'
        f.write(f"file '{mp4.as_posix()}'\n")

# ----------------------------------------
# ffmpeg 実行コマンド
# ----------------------------------------
cmd = [
    "ffmpeg",
    "-y",                # 上書き確認なし
    "-f", "concat",      # concat デマルチプレクサを使用
    "-safe", "0",        # 絶対パスを許可
    "-i", str(LIST_FILE),# 入力:作成したリストファイル
    "-c", "copy",        # 再エンコードせずそのまま結合
    str(OUTPUT_FILE)     # 出力ファイル
]

# ffmpeg 実行
subprocess.run(cmd)

# ----------------------------------------
# 作業用リストファイルを削除
# ----------------------------------------
LIST_FILE.unlink(missing_ok=True)

concat.bat

ダブルクリックして実行するバッチファイルの中身。concat.pyを呼び出している。

@echo off
chcp 65001 > nul
cd /d %~dp0

echo MP4 連結中...
python concat.py

echo.
echo 完了
pause

音楽を加える

音源(mp3ファイル)もffmpegでつけることができる。同じようにフォルダ直下にbatとpyファイルを置くことにした。

movies/
 ├─ add_audio.bat
 ├─ add_audio.py
 ├─ video.mp4     ← 固定
 └─ audio.mp3     ← 固定

add_audio.py

Pythonファイルの中身のコード。※ChatGPTに書いてもらいました。

import sys
import subprocess
from pathlib import Path

video_path = Path(sys.argv[1]).resolve()
audio_path = Path(sys.argv[2]).resolve()

if not video_path.exists():
    raise FileNotFoundError(f"Video not found: {video_path}")

if not audio_path.exists():
    raise FileNotFoundError(f"Audio not found: {audio_path}")

output_path = video_path.with_name(f"{video_path.stem}_with_audio.mp4")

cmd = [
    "ffmpeg",
    "-y",

    # ★ BGMを無限ループ
    "-stream_loop", "-1",
    "-i", str(audio_path),

    "-i", str(video_path),

    "-map", "1:v:0",
    "-map", "0:a:0",

    "-c:v", "copy",
    "-c:a", "aac",

    # ★ 動画の長さで打ち切り
    "-shortest",

    str(output_path)
]

subprocess.run(cmd, check=True)

print("Done:", output_path)

add_audio.bat

ダブルクリックして実行するバッチファイルの中身。add_audio.pyを呼び出している。

@echo off
setlocal

REM ===== 固定ファイル名 =====
set VIDEO=output.mp4
set AUDIO=music.mp3

REM batのあるディレクトリへ移動
cd /d "%~dp0"

python add_audio.py "%VIDEO%" "%AUDIO%"

pause
タイトルとURLをコピーしました