LoginSignup
1
0

More than 1 year has passed since last update.

動画ファイルを簡単にチャプター付きで結合します

Last updated at Posted at 2022-04-19

動画ファイルを簡単(再エンコードしないで)に結合して結合部分にチャプターを自動生成するスクリプトを、python を使って書いてみました

要件定義

  1. mp4, mkv ファイルを再エンコードしないで結合したい
  2. 楽したい!(使いまわしができるように)
  3. Windows10 環境で動く
  4. python, ffmpeg, mkvmerge などのインストールはできる前提
  5. すでにチャプターがついているファイルはそのチャプターを利用したい
  • こんな感じで要件を確定させて、実際にどのツールを使っていくのか?を検討していきます

検討結果(=機能リスト)

  1. Windows10でのみ検証しています(Linuxでも少しの修正で動くはず)
  2. チャプターを簡単に作成するため最終的なファイルフォーマットを mkv にする
  3. 結合するファイルのファイル名をチャプター名として利用
  4. mkvファイルで、すでにチャプターがついている場合はそのまま利用する
  5. 結合元のソースファイルは、mp4 or mkv のみ
  6. 結合するファイルの順番は python の Sort関数順
  7. ワイルドカードで結合ファイルを選択するので、結合するファイル名の先頭部分は同一にする必要がある
  8. Codec(A,V), 画素数, アスペクト比等は、結合するファイルで統一されているのが望ましい
  9. ファイルフォーマットが異なる場合はある程度統一します(再エンコーディングしますので要時間)
  10. pythonのコーディング久しぶりなのでコードが美しくないのはご容赦ください

動作の流れ

  1. ソースファイルを mkv に統一
    • ffmpeg 利用
    • mp4 to mkv
  2. 動画フォーマットを統一
    • ffprobe で確認して必要であれば ffmpeg を利用します
    # 動画ファイルの情報をjsonで出力します
    bat.write('"%s" "%s" -loglevel quiet -show_streams -print_format json > %s\n' 
        % (ffprobe, c, ffprobejson))
    bat.close()
    # jsonファイルを確認して想定しているサイズと異なる場合は再エンコードのフラグをたてます
    json_f = open(ffprobejson, "r")
    json_data = json.load(json_f)
    json_f.close()
    reenc = False
    for stream in json_data['streams']:
        if stream['codec_type'] == 'video':
            print(stream['codec_type'])
            if stream['codec_name'] != codec_name_v:
                print(stream['codec_name'])
                reenc = True 
            if stream['width'] != width:
                print(stream['width'])
                reenc = True 
            if stream['height'] != height:
                print(stream['height'])
                reenc = True
  1. チャプターを追加
    • 既存のチャプターを確認(mkvextract 利用)
    # チャプターが存在するとチャプター内容がファイル出力されます
    bat.write('"%s" "%s" chapters -s "%s"\n'
        % (mkvextract, mkv, chkchapfile))
    bat.close()
    # ファイルが生成されればチャプター付きなのでそのまま利用します
  1. 結合前のmkv状態で、00:00:00部分にチャプターを追加
    • mkvmerge 利用(チャプターデータのファイルを生成してからmkvmergeで追加します)
    metafile = open(metafilename, 'w+')
    metafile.write('CHAPTER01=00:00:00.000\n')
    metafile.write('CHAPTER01NAME=%s\n' % bname)
    metafile.close()
    bat.write('"%s" --chapters "%s" -o "%s" "%s"\n'
        % (mkvmerge, metafilename, mkn, mkv))
    bat.close()
  1. mkvファイルを結合
    • mkvmerge 利用

ポイント

  • mkvmerge で mkvファイルを結合するときにチャプターが残る仕様を活用しています
  • 外部ツールを起動する場合に subprocess(ライブラリ)経由で batファイルを使っています

初期設定

  • pythonファイルの先頭部分を修正してください

mkvmergeを起動するバッチファイル(ファイルが作成できる場所であればどこでも可)

batfilename = 'H:\mp4mkvmerge_.bat'

チャプターを作成するときの作業用ファイル(ファイルが作成できる場所であればどこでも可)

metafilename = 'H:\metadata.txt'

mkvmerge.exe の場所
ffmpeg.exe の場所
ffprobe.exe の場所
mkvextract.exe の場所

mkvmerge = 'C:\Program Files\MKVToolNix\mkvmerge.exe'
ffmpeg = 'C:\Program Files\ffmpeg\bin\ffmpeg.exe'
ffprobe = 'C:\Program Files\ffmpeg\bin\ffprobe.exe'
mkvextract = 'C:\Program Files\MKVToolNix\mkvextract.exe'

作業用の空ディレクトリ(存在している必要あり)
作業用ファイル名

tempDir = 'C:\TEMP'
mergefilename = '000.mkv'
chkmp4filename = 'chk.mp4'
chkmkvfilename = 'chk.mkv'
chkchapterfilename = 'chap.txt'

結合時に異なるフォーマットの場合に揃えるパラメータ(タブレット向き?)

codec_name_v = 'hevc'
codec_name_a = 'aac'
width = 1280
height = 720
sample_rate = '48000'
reenc_codec_v = 'hevc_nvenc'
reenc_codec_a = 'aac'
reenc_bitrate = '1200k'

サンプル

python mp4mkvmerge.py "C:\Videos" "DORAMA" "DORAMA #01-12 END" "C:\DELETE"

  1. C:\Videos ディレクトリにある DORAMAで始まるファイル(DORAMA*.mp4, DORAMA*.mkv)を(ファイル名を pythonの標準sort順で)結合します
  2. DORAMA #01.mp4 と DORAMA #01.mkv が存在する場合は同一とみなし DORAMA #01.mkv を結合対象とします
  3. 処理が終わったら、C:\Videos\DORAMA #01-12 END.mkv ファイルが生成されます
  4. 結合前のファイルは、C:\DELETE フォルダに移動されます

ソースコード

カスタマイズ

  • Windows の batファイルを生成しているところをシェルスクリプトに変更すればLinux対応できます
  • 再エンコード の ffmpegパラメータは好きなようにカスタマイズしてください(筆者は NVEncC64 を使っているので適当ですいません)
1
0
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
0