LoginSignup
1
1

複数の.MTSファイルを.MOVや.MP4に一括で変換する

Last updated at Posted at 2023-07-25

背景

AVCHD 内の.MTS ファイルを mp4 に一括変換したかったのですが、フリーソフトにろくなもんがないため、chatGPT に教えてもらいながら python でそれを実行できるコードを書きました

ffmpeg(v6)を使用しているので、ffmpeg が対応してるコーデックならなんでも変換できるはず(未検証)

簡単な機能説明

・指定ディレクトリ内の.MTS ファイルを.mp4 に変換して別の指定ディレクトリに置く
・その際ファイル名は動画ファイルの撮影日時を使用(2023-07-25-14-32.mp4 みたいな)
・コマンドラインで簡単めに実行できるといい

前提

Mac で動くことを確認してます(一応 windows でも動くはず)
python のバージョンは3.11.4です

セットアップ

  1. 任意の場所にmp4-converter.pyを作成する
  2. 下記のコードを貼り付け後保存
import os
import argparse
import datetime
import platform
from tqdm import tqdm
import subprocess

input_formats = ["MTS", "AVI", "MOV", "MP4", "MKV", "WMV"]
output_formats = ["mp4", "avi", "mov", "mkv", "wmv"]

def run_ffmpeg_command(command):
    process = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, universal_newlines=True)
    for line in process.stdout:
        yield line
    process.wait()

# 完了音
def play_notification_sound():
    if platform.system() == "Darwin":
        # Mac環境の場合はosaScriptを使って通知音を鳴らす
        try:
            subprocess.run(['osascript', '-e', 'display notification "すべてのファイルの変換が完了しました" with title "FFmpeg Conversion" sound name "Glass"'])
        except Exception as e:
            print(f"Error while trying to play notification sound: {e}")
    elif platform.system() == "Windows":
        try:
            import winsound
            # Windows環境の場合はwinsoundを使ってビープ音を鳴らす
            winsound.Beep(440, 500)
        except Exception as e:
            print(f"Error while trying to play notification sound: {e}")

def convert_to_mp4(input_directory, output_directory, extension="MTS",output_extension="mp4", quality="medium"):
    output_directory = os.path.expanduser(output_directory) # ホームディレクトリを展開
    os.makedirs(output_directory, exist_ok=True)
    files = [file for file in os.listdir(input_directory) if file.endswith(f".{extension}")]

    total_files = len(files)
    converted_count = 0

    if not os.path.exists(output_directory):
        os.makedirs(output_directory)

    for file in tqdm(files, desc="進捗", unit="ファイル"):  # tqdmを使って進捗バーを表示
        input_file = os.path.join(input_directory, file)
        creation_time = datetime.datetime.fromtimestamp(os.path.getmtime(input_file))   # ファイルの作成日時を取得
        output_file = os.path.join(output_directory, f"{get_datetime_string(creation_time)}.{output_extension}")
        crf = "18" if quality == "high" else "23"  # 高画質: CRF 18, 中画質: CRF 23

        # 既に同じ名前のファイルが存在する場合、連番をつける
        count = 1
        while os.path.exists(output_file):
            output_file = os.path.join(output_directory, get_datetime_string(creation_time) + f"-{count}.mp4")
            count += 1

        command = f"ffmpeg -i {input_file} -c:v libx264 -crf {crf} -loglevel warning -preset slow -c:a aac -strict experimental {output_file}"
        os.system(command)

        converted_count += 1
        print(f"変換完了: {converted_count}/{total_files}")

def get_datetime_string(dt):
    return dt.strftime("%Y-%m-%d-%H-%M")

if __name__ == "__main__":
    parser = argparse.ArgumentParser(description="動画ファイルを指定のフォーマットに変換できます")
    parser.add_argument("input_directory", help="入力ディレクトリのパス")
    parser.add_argument("output_directory", help="出力ディレクトリのパス")
    parser.add_argument("--extension", choices=input_formats, default="MTS", help="変換する拡張子 (デフォルト: MTS)")
    parser.add_argument("--output_extension", choices=output_formats, default="mp4", help="変換先の拡張子 (デフォルト: mp4)")
    parser.add_argument("--quality", choices=["high", "medium"], default="medium", help="変換品質を選択 (デフォルト: medium)")
    args = parser.parse_args()

    convert_to_mp4(args.input_directory, args.output_directory, args.extension, args.output_extension, args.quality)

    play_notification_sound()

おわり

使い方

mp4-converter.pyをおいたディレクトリにcdして実行します。

最低限のコマンドはこちら

python3 mp4-converter.py {変換したいファイルがあるディレクトリのパス} {変換したファイルの格納先パス}

ただこれだと.MTS ファイルを mp4 に中画質で変換するコマンドなので、コード見てやりたいふうに変えてください。
例えば.mp4 を.mov に高画質で変換したい場合、以下のコマンドになります。(成功するかはわからない)

python3 mp4-converter.py {変換したいファイルがあるディレクトリのパス} {変換したファイルの格納先パス} mp4 mov high

実行には結構かかるので、気長に待ちましょう。
正常に実行されている場合このような画面になります。
スクリーンショット 2023-07-25 21.50.28.png

ModuleNotFoundError: No module named '~~~~'のようなエラーが出た場合
pip3 install ~~~~でモジュールをダウンロードしてください

終わりに

chatGPT は神

参考

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1