Convert video frames to png images using FFmpeg

Convert video frames to png images using FFmpeg


foreword

A code example that uses ffmpeg multi-process to convert a large number of mp4 files into corresponding multi-frame png/jpg/bmp and other image files, where png is stored in a folder with the same name as the video.


1. Core commands

ffmpeg -i *.mp4 -s 256x256 -r 25 %8d.png

Where -i refers to the input address
-s specifies the image resolution
-r specifies the number of frames

2. Code example

The core idea is to use multiprocessing to read the list of MP4 files, and change the naming method for storage

import os
import argparse
from typing import List, Dict
from multiprocessing import Pool
import subprocess
from subprocess import Popen, PIPE
from glob import glob
from tqdm import tqdm, trange


def clip_vid2png(source_dir: os.PathLike, output_dir: os.PathLike, num_workers: int):
    os.makedirs(output_dir, exist_ok=True)
    # os.makedirs(os.path.join(output_dir, '_videos_raw'), exist_ok=True)
    import pdb;pdb.set_trace()
    video_queue = construct_video_queue(source_dir)
    task_kwargs = [dict(
        video_path=vd,  # 视频路径
        png_path= os.path.join(output_dir, os.path.basename(vd))# 图像存储路径
     ) for vd in video_queue]
    pool = Pool(processes=num_workers)
    tqdm_kwargs = dict(total=len(task_kwargs), desc=f'Clips videos into {
      
      output_dir}')

    for _ in tqdm(pool.imap_unordered(task_proxy_clip, task_kwargs), **tqdm_kwargs):
        pass

    print('Clip is finished')


def construct_video_queue(source_dir: os.PathLike) -> List[Dict]:
    video_queue = sorted(glob(os.path.join(source_dir, "*.mp4")))
    return video_queue

def task_proxy_clip(kwargs):
    return clip_video(**kwargs)

def clip_video(video_path, png_path):
    os.makedirs(png_path, exist_ok=True)
    command = [
            "ffmpeg",
            "-loglevel", "quiet", 
            "-i",
            f"{
      
      video_path}", 
            "-s", "256x256",
            "-r", "25",
            f"{
      
      png_path}/%08d.png"
        ]
    return_code = subprocess.call(command)
    return return_code


if __name__ == "__main__":
    parser = argparse.ArgumentParser(description="clip video to png")
    parser.add_argument('-s', '--source_dir', type=str, default=None, help='Path to the directory with the dataset')
    parser.add_argument('-o', '--output_dir', type=str, default=None, help='Where to save the videos?')
    parser.add_argument('-w', '--num_workers', type=int, default=4, help='Number of workers for downloading')
    args = parser.parse_args()

    clip_vid2png(
        args.source_dir,
        args.output_dir,
        args.num_workers,
    )

Guess you like

Origin blog.csdn.net/weixin_43357695/article/details/129252595