MoviePyを使い、動画から一定間隔でフレームを抽出する方法を見ていきます。iter_framesを使うとできます。動画編集と組み合わせたいときにこの方法は便利です。
目次
動画を1秒や0.5秒など一定間隔でフレーム数を切り出す方法としていくつかあります。例えば、
今回はMoviePyを使って似たようなことを行う方法です。Decordが読み込みに特化したライブラリであるのに対し、MoviePyは編集もできるため、読み込み+編集して書き出しのようなユースケースだとそもそもMoviePyが向いています。今回行うのはMoviePyを読み込み部分で使う方法です。
公式サイトからインストールしましょう
https://zulko.github.io/moviepy/
YouTubeから動画をダウンロードします。たまたま聞いてたやつを例にとります。yt-dlpを使っています。
from yt_dlp import YoutubeDL
def download_youtube(url):
ydl_opts = {
"format": "best",
"paths": {
"home": "video"
}
}
with YoutubeDL(ydl_opts) as ydl:
result = ydl.download([url])
if __name__ == '__main__':
download_youtube('https://www.youtube.com/watch?v=HJ7sjZwy-uY')
MoviePyのiter_framesという関数を使います。抽出するFPSを指定できるので、それで取り出し間隔を調整します。
import moviepy.editor as mpe
import os
from PIL import Image
def extract_frames(file_path, fps=1):
clip = mpe.VideoFileClip(file_path)
out_dir = f"frames/{os.path.splitext(os.path.basename(file_path))[0]}_fps{fps}"
os.makedirs(out_dir, exist_ok=True)
for i, frame in enumerate(clip.iter_frames(fps=fps)):
with Image.fromarray(frame) as img:
img.save(out_dir+f"/frame_{i:04}.jpg", quality=92)
if __name__ == "__main__":
extract_frames("video/北朝鮮 「<画面音楽:新映像>朝鮮人民軍歌 (조선인민군가)」 KCTV 2023⧸02⧸08 日本語字幕付き [HJ7sjZwy-uY].mp4",
fps=1)
FPSを0.5、1、2と変えて抽出した結果を示します。
うまくいっているようです。