PythonとMoviePyで動画ファイルの指定時間ごとの分割を自動化
PythonとMoviePyで動画ファイルの指定時間ごとの分割を自動化 OpenCVなどで動画の処理を行う際に、1分毎の変化や10分毎に結果を見たいときに一連の動画から指定した時間毎に分割して切り出したいことがあります。 […]
Filter by Category
PythonとMoviePyで動画ファイルの指定時間ごとの分割を自動化 OpenCVなどで動画の処理を行う際に、1分毎の変化や10分毎に結果を見たいときに一連の動画から指定した時間毎に分割して切り出したいことがあります。 […]
OpenCVで複数の動画を連結する 複数の動画素材を結合したり、GoProで長時間撮影した時に約4GB毎に分割される動画ファイルを結合して一つの動画を書き出す方法です。 コードはGitHubリポジトリにあげています。 開 […]
名前に現在時刻を入れたファイルが連番かどうか判定(後半) 前回からの続きです。 前回は連番になっていたらまとめてリスト化しましたが、今回はまとめたファイルを動画に変換して書き出します。 コードはGitHubリポジトリにあ […]
名前に現在時刻を入れたファイルが連番かどうか判定(前半) なにかアクションがあった際に生成されるファイル名に現在時刻が入ったファイルが、連番になっているかどうかを判別して連番になっていたらまとめてリスト化する方法です。手 […]
フォルダ内のファイルを複数毎にzip形式に圧縮 ファイルをまとめてzip形式に圧縮してしまうと容量が増えてしまうので、メールなどで送るために複数個に分けて圧縮ファイルを作りたいときがあります。ファイル数がそれほど多くない […]
OpenCVなどで動画の処理を行う際に、1分毎の変化や10分毎に結果を見たいときに一連の動画から指定した時間毎に分割して切り出したいことがあります。動画編集ソフトを使っても良いですが動画の切り出しという単調な作業の繰り返しで人的ミスも発生しやすくなるため、できれば自動化させたい処理の一つです。本記事では動画の分割作業をPythonとMoviePyで自動化する方法を解説します。
コードはGitHubリポジトリにあげています。
PC: MacBook Pro (14, 2021)
OS: macOS Monterey 12.0.1
Python: 3.9.1
moviepy: 1.0.3
import os
import glob
import sys
from moviepy.video.io.VideoFileClip import VideoFileClip
from moviepy.video.io.ffmpeg_tools import ffmpeg_extract_subclip
def split_video(file_path: str, duration: int) -> None:
# ファイル名から拡張子を取得
file_name, file_extension = os.path.splitext(os.path.basename(file_path))
# 分割したビデオの保存先ディレクトリを作成
output_dir = f"{file_name}_split"
os.makedirs(output_dir, exist_ok=True)
# 動画の長さを取得し、動画ファイルを適切に閉じる
with VideoFileClip(file_path) as video:
total_duration = int(video.duration)
# 指定した間隔でビデオを分割
start_time = 0
end_time = duration
while start_time < total_duration:
# 実際の終了時間が動画の総時間を超えないように調整
end_time = min(end_time, total_duration)
# 分割範囲を指定してビデオを切り出し
output_path = os.path.join(output_dir, f"{file_name}_{start_time}_{end_time}{file_extension}")
ffmpeg_extract_subclip(file_path, start_time, end_time, targetname=output_path)
# 次の分割範囲を更新
start_time += duration
end_time = start_time + duration
def split_videos_in_directory(directory: str, duration: int) -> None:
# ディレクトリ内のすべてのMP4ファイルを取得
video_files = glob.glob(os.path.join(directory, "*.mp4"))
for video_file in video_files:
# 動画ファイル毎に分割処理
split_video(video_file, duration)
# メイン処理
if __name__ == "__main__":
if len(sys.argv) < 2:
print("ディレクトリパスを引数として指定してください。")
sys.exit(1)
directory_path = sys.argv[1]
if not os.path.isdir(directory_path):
print("指定されたパスはディレクトリではありません。")
sys.exit(1)
# コマンドライン引数からdurationを取得し、指定がない場合は600秒をデフォルト値とする
try:
duration = int(sys.argv[2]) if len(sys.argv) > 2 else 600
except ValueError:
print("Durationは整数である必要があります。")
sys.exit(1)
split_videos_in_directory(directory_path, duration)
コードの量が少し多いですが大きく分けると以下の3つの処理に分けられます。
import os
import glob
import sys
from moviepy.video.io.VideoFileClip import VideoFileClip
from moviepy.video.io.ffmpeg_tools import ffmpeg_extract_subclip
ライブラリ、モジュールのインポート
def split_video(file_path: str, duration: int) -> None:
# ファイル名から拡張子を取得
file_name, file_extension = os.path.splitext(os.path.basename(file_path))
# 分割したビデオの保存先ディレクトリを作成
output_dir = f"{file_name}_split"
os.makedirs(output_dir, exist_ok=True)
# 動画の長さを取得し、動画ファイルを適切に閉じる
with VideoFileClip(file_path) as video:
total_duration = int(video.duration)
# 指定した間隔でビデオを分割
start_time = 0
end_time = duration
while start_time < total_duration:
# 実際の終了時間が動画の総時間を超えないように調整
end_time = min(end_time, total_duration)
# 分割範囲を指定してビデオを切り出し
output_path = os.path.join(output_dir, f"{file_name}_{start_time}_{end_time}{file_extension}")
ffmpeg_extract_subclip(file_path, start_time, end_time, targetname=output_path)
# 次の分割範囲を更新
start_time += duration
end_time = start_time + duration
取得したファイルを指定した時間毎に分割して保存する関数
def split_videos_in_directory(directory: str, duration: int) -> None:
# ディレクトリ内のすべてのMP4ファイルを取得
video_files = glob.glob(os.path.join(directory, "*.mp4"))
for video_file in video_files:
# 動画ファイル毎に分割処理
split_video(video_file, duration)
ディレクトリ内のファイル(mp4のみ)を取得して処理する関数
取得したファイルを1件づつ先述の動画を分割する関数に渡す
# メイン処理
if __name__ == "__main__":
if len(sys.argv) < 2:
print("ディレクトリパスを引数として指定してください。")
sys.exit(1)
directory_path = sys.argv[1]
if not os.path.isdir(directory_path):
print("指定されたパスはディレクトリではありません。")
sys.exit(1)
# コマンドライン引数からdurationを取得し、指定がない場合は600秒をデフォルト値とする
try:
duration = int(sys.argv[2]) if len(sys.argv) > 2 else 600
except ValueError:
print("Durationは整数である必要があります。")
sys.exit(1)
split_videos_in_directory(directory_path, duration)
引数にはディレクトリのパスと分割する時間をフレームレートで指定
フレームレートの指定がない場合は600フレームを指定(30フレームの動画の場合10分)
ディレクトリのパスとフレームレートに異常がある場合はエラーを発生させる
群馬県でPythonを使ったAIやソフトウェアを開発している株式会社ファントムが運営しています。
メーリングリストに登録するとファントムの最新情報をお届けします
お客様のメールアドレスを共有することはありません