"""make_movie.py

This script is part of the FFMPEG tutorial for  Kimberly.
It generates a list of images files which are then combined into a movie with ffmpeg.

Usage: `python make_movie.py`

Author: Pierre DERIAN
"""
import glob
import subprocess
import sys
from typing import List


def make_framelist(patterns: List) -> List:
    """Generates a list of frames.

    Args:
      patterns: a list of patterns for glob searching.

    Returns: a list of files, sorted.
    """

    # Search all patterns, concatenate results in a list
    framelist = []
    for p in patterns:
        framelist.extend(glob.glob(p))
    # Make sure it is sorted
    framelist.sort()
    print(f'Found {len(framelist)} files matching patterns')
    return framelist


def run_ffmpeg(framelist: List, output_movie: str, framerate: float = 6, crf: int = 12):
    """Run ffmpeg for the given framelist.

    Args:
      framelist: the list of input image files.
      output_movie: the path ot the output movie file.
      framerate: the output framerate.
      crf: the crf value.
    """

    # Generates args
    cat_args = ['cat',] + framelist
    ffmpeg_args = [
        'ffmpeg',
        '-y',
        '-r',  str(framerate),
        '-f', 'image2pipe',
        '-i', '-',
        '-c:v', 'h264',
        '-crf', str(crf),
        '-pix_fmt', 'yuv420p',
        '-movflags', 'faststart',
        output_movie,
    ]
    print(f'Running FFMPEG with: {" ".join(ffmpeg_args)}')
    cat_p = subprocess.Popen(cat_args, stdout=subprocess.PIPE)  # Reads the images, send to the PIPE
    ffmpeg_p = subprocess.Popen(ffmpeg_args, stdin=cat_p.stdout)  # Read from the PIPE, encode the movie
    cat_p.wait()  # Wait until all images are read
    ffmpeg_p.wait()  # Wait until FFMPEG is done.
    print(f'Encoded movie {output_movie}')


if __name__ == "__main__":

    patterns = [
        '../images/scans/202308/20230818/scan_REAL.20230818_18[3-5]*.png',  #second half-hour of 6PM
        '../images/scans/202308/20230818/scan_REAL.20230818_19*.png',  #every image of 7 PM
        '../images/scans/202308/20230818/scan_REAL.20230818_20[01]*.png',  # first 20 min of 8 PM
    ]
    # Generate the list
    framelist = make_framelist(patterns)
    # Render the movie
    run_ffmpeg(framelist, 'output_python.mp4')
