<commit_before>import os
import subprocess

# First, check that ffmpeg is installed
try:
    subprocess.call(['ffmpeg', '-version'], stdout=open(os.devnull, 'w'), stderr=open(os.devnull, 'w'))
except OSError as e:
    raise ImportError('png_to_mp4: ffmpeg does not seem to be installed: ' + str(e))


def png_to_mp4(sim_dir, mp4_name='results.mp4', mp4_duration=15.0, print_progress=False):
    """ Convert a sequence of png files to a mp4 movie

    :param sim_dir: the directory containing the simulation output
    :param mp4_name: file name for the mp4 (default 'results.mp4')
    :param mp4_duration: required duration in seconds for the mp4 (default 15.0)
    :param print_progress: whether to print running trace of this function (default False)

    :raise Exception: if sim_dir is not a valid directory
    :raise Exception: if mp4_duration is < 1.0
    :raise Exception: if no png files found in sim_dir
    :raise Exception: if ffmpeg does not generate mp4 file
    :raise Exception: if ffmpeg does not generate valid mp4 file (at least 1kb in size)
    """
    # Validate and process input
    if not (os.path.isdir(sim_dir)):
        raise Exception('png_to_mp4: Invalid simulation directory: ' + sim_dir)

    if not mp4_name.endswith('.mp4'):
        mp4_name += '.mp4'

    if mp4_duration < 1.0:
        raise Exception('png_to_mp4: Invalid mp4_duration: ' + str(mp4_duration))

    png_files = list_files_of_type(path_name=sim_dir, extension='.png')

    # "New" behaviour is to pre-convert the png files, so they should already exist
    if len(png_files) == 0:
        raise Exception('png_to_mp4: No png files found in ' + sim_dir)

    # Set how long you want the video to be (in seconds), and set the frame rate accordingly, with a minimum of 1.0
    frame_rate = max(float(len(png_files)) / mp4_duration, 1.0)

    # Send the subprocess call to run ffmpeg. Parameters:
    #   -v 0               Suppress console output so as not to clutter the terminal
    #   -r frame_rate      Set the frame rate calculated above
    #   -f image2          Set the convert format (image sequence to video)
    #   -i %04d.png        Input expected as dir/results.####.png, the output from WriteAnimation above
    #   -c:v libx264       Video codec to use is h264
    #   -crf 0             Set video quality to lossless
    #   -preset slow       Slow encoding at expense of slightly larger file size
    #   -y name.mp4        Output directory and name
    ffmpeg_command = ['ffmpeg',
                      '-v', '0',
                      '-r', str(frame_rate),
                      '-f', 'image2',
                      '-i', '%04d.png',
                      '-c:v', 'libx264',
                      '-crf', '0',
                      '-preset', 'slow',<commit_msg>Use `yuv420p` as many players don't understand the default<commit_after>import os
import subprocess

# First, check that ffmpeg is installed
try:
    subprocess.call(['ffmpeg', '-version'], stdout=open(os.devnull, 'w'), stderr=open(os.devnull, 'w'))
except OSError as e:
    raise ImportError('png_to_mp4: ffmpeg does not seem to be installed: ' + str(e))


def png_to_mp4(sim_dir, mp4_name='results.mp4', mp4_duration=15.0, print_progress=False):
    """ Convert a sequence of png files to a mp4 movie

    :param sim_dir: the directory containing the simulation output
    :param mp4_name: file name for the mp4 (default 'results.mp4')
    :param mp4_duration: required duration in seconds for the mp4 (default 15.0)
    :param print_progress: whether to print running trace of this function (default False)

    :raise Exception: if sim_dir is not a valid directory
    :raise Exception: if mp4_duration is < 1.0
    :raise Exception: if no png files found in sim_dir
    :raise Exception: if ffmpeg does not generate mp4 file
    :raise Exception: if ffmpeg does not generate valid mp4 file (at least 1kb in size)
    """
    # Validate and process input
    if not (os.path.isdir(sim_dir)):
        raise Exception('png_to_mp4: Invalid simulation directory: ' + sim_dir)

    if not mp4_name.endswith('.mp4'):
        mp4_name += '.mp4'

    if mp4_duration < 1.0:
        raise Exception('png_to_mp4: Invalid mp4_duration: ' + str(mp4_duration))

    png_files = list_files_of_type(path_name=sim_dir, extension='.png')

    # "New" behaviour is to pre-convert the png files, so they should already exist
    if len(png_files) == 0:
        raise Exception('png_to_mp4: No png files found in ' + sim_dir)

    # Set how long you want the video to be (in seconds), and set the frame rate accordingly, with a minimum of 1.0
    frame_rate = max(float(len(png_files)) / mp4_duration, 1.0)

    # Send the subprocess call to run ffmpeg. Parameters:
    #   -v 0               Suppress console output so as not to clutter the terminal
    #   -r frame_rate      Set the frame rate calculated above
    #   -f image2          Set the convert format (image sequence to video)
    #   -i %04d.png        Input expected as dir/results.####.png, the output from WriteAnimation above
    #   -c:v libx264       Video codec to use is h264
    #   -crf 0             Set video quality to lossless
    #   -preset slow       Slow encoding at expense of slightly larger file size
    #   -y name.mp4        Output directory and name
    ffmpeg_command = ['ffmpeg',
                      '-v', '0',
                      '-r', str(frame_rate),
                      '-f', 'image2',
                      '-i', '%04d.png',
                      '-c:v', 'libx264',
                      '-pix_fmt', 'yuv420p',
                      '-crf', '0',
                      '-preset', 'slow',
{'fraction_non_alphanumeric': 0.0951538733639901, 'fraction_numerical': 0.022638839759462327, 'mean_word_length': 2.5080645161290325, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6907705', 'n_tokens_mistral': 1778, 'n_tokens_neox': 1683, 'n_words': 629}