こしあん
2019-09-29

ffmpeg-pythonで大量の動画(tsファイル)を結合してmp4化する方法


16k{icon} {views}


ごにょごにょしてきた細切れのTSファイルを結合したいときに使えるテクニック。ffmpegの例はいくつか出てきましたが、Pythonラッパーのffmpegの例は全然なかったのでメモしていきます。

必要ライブラリ

  • ffmpeg-python
  • ffmepgのバイナリ ffmpeg-pythonはあくまでラッパーなので、ffmpeg本体が必要です。実行ディレクトリに本体がない場合は「FileNotFound」と怒られます。変換元の動画や音声が存在しないのではなく、本体がないだけなのでご注意を。

ファイル数が少ない場合

ファイルが数個~数十個の場合はこの方法でOKです。

import ffmpeg

videos = ["ts/1.ts", "ts/2.ts", "ts/3.ts", "ts/4.ts", "ts/5.ts"]  # 結合するファイルのパス
ffmpeg.input("concat:" + "|".join(videos)).output("out.mp4", c="copy").run()

tsフォルダ以下に結合したいtsファイルがあるとします。再エンコードは行わないので爆速で進みますし、画質の劣化がありません。

tsファイルのコーデックによりけりなのかもしれませんが、自分がやったケースではそのまま「.mp4」と保存しても特に問題なくいけました(メディアプレーヤーで再生できた)。

ファイル数が多い場合

上記の方法は、コマンドラインに変換して直書きして実行してるだけなので、ファイル数が何百個もある場合「コマンドが長すぎ」とシェル側で怒られてしまいます。その場合は、ファイル一覧をテキストファイルに保存します。

from tqdm import tqdm
import ffmpeg

videos = ["ts/1.ts", "ts/2.ts", "ts/3.ts", "ts/4.ts", "ts/5.ts"]  # 結合するファイルのパス
# 一旦テキストファイルに書き出す
# 書き出さない方法は、あまりにファイル数が多い場合に「コマンド長すぎ」と怒られる
with open("tmp.txt", "w") as fp:
    lines = [f"file '{line}'" for line in videos] # file 'パス' という形式にする
    fp.write("\n".join(lines))
# ffmpegで結合(再エンコードなし)
ffmpeg.input("tmp.txt", f="concat", safe=0).output("out.mp4", c="copy").run()

これでOK

関連

pytube+ffmpeg-pythonでYouTubeからダウンロードした動画の音声+動画を結合する方法
https://blog.shikoan.com/pytube-ffmepg-concat-video-audio/



Shikoan's ML Blogの中の人が運営しているサークル「じゅ~しぃ~すくりぷと」の本のご案内

技術書コーナー

北海道の駅巡りコーナー


One Comment

Add a Comment

メールアドレスが公開されることはありません。 が付いている欄は必須項目です