예제 #1
0
def process_command_line(argv):
    parser = ArgumentParser()
    parser.add_argument('-files', action='store_true')
    parser.add_argument('-mir', action='store_true')
    parser.add_argument('-queue', action='store_true')
    parser.add_argument('paths', nargs='*')
    parser.add_argument('-not', action='append', dest='exclusions', nargs='*')
    parser.add_argument('-only', action='append', nargs='*')
    parser.add_argument('-encoding-profile', choices=['video_passthrough', 'burn_in', '720p_burn_in', '720p'], default='video_passthrough')

    arguments = parser.parse_args(argv[1:])

    mode_count = 0
    if arguments.files:
        mode_count += 1

    if arguments.mir:
        mode_count += 1

    if arguments.queue:
        mode_count += 1

    if mode_count > 1:
        print("Can't pass more than one of -files, -mir, or -queue")
        exit_with_error()

    if arguments.files:
        _files_mode(arguments)
    elif arguments.mir:
        _mirror_mode(arguments)
    elif arguments.queue:
        _queue_mode(arguments)
    else:
        _files_mode(arguments)
예제 #2
0
def mirror_videos(source_directory, destination_directory, log_directory, exclusions, only, encoding_profile):
    source_pattern = join(source_directory, MKV_SEARCH)
    source_glob = glob(source_pattern)
    source_set = set(source_glob)
    destination_pattern = join(destination_directory, MP4_SEARCH)
    destination_glob = glob(destination_pattern)
    log_pattern = join(log_directory, MP4_SEARCH)
    log_glob = glob(log_pattern)
    encode_list = []

    if exclusions and only:
        print('mirror_videos was passed both exclusions and only')
        exit_with_error()
        return

    if exclusions:
        for exclusion in exclusions:
            exclusion_pattern = join(source_directory, exclusion)
            exclusion_glob = glob(exclusion_pattern)
            exclusion_set = set(exclusion_glob)

            source_set -= exclusion_set
    elif only:
        source_set = set()
        for pattern in only:
            only_pattern = join(source_directory, pattern)
            only_glob = glob(only_pattern)
            only_set = set(only_glob)

            source_set |= only_set

    for source_file in source_set:
        destination_file = generate_output_name(source_file, destination_directory)
        log_file = generate_output_name(source_file, log_directory)
        if log_file in log_glob:
            # We have a log of doing this conversion. We should make sure we keep the log
            # intact and not convert it again.
            log_glob.remove(log_file)
        elif destination_file in destination_glob:
            # We have the destination file, but not the log of doing it. Create the log.
            create_log_file(log_file)
        else:
            # We haven't converted this video yet. Queue it up
            encode_job = (source_file, destination_file, log_file)
            encode_list.append(encode_job)

    for log_file in log_glob:
        print("Deleting " + log_file)
        remove(log_file)

    for input_file, output_file, log_file in encode_list:
        generate_output(input_file, output_file, encoding_profile)
        create_log_file(log_file)
예제 #3
0
def _queue_mode(arguments):
    if len(arguments.paths) < 2 or len(arguments.paths) > 3:
        print('Queue mode can only take two or three paths')
        exit_with_error()

    # The first two paths are the source and destination directories
    source_directory = arguments.paths[0]
    destination_directory = arguments.paths[1]
    queue_directory = arguments.paths[0] # If there isn't a queue directory specified, the source acts like it

    if len(arguments.paths) == 3:
        queue_directory = arguments.paths[2]

    process_queue(source_directory, destination_directory, queue_directory, arguments.encoding_profile)
예제 #4
0
def _mirror_mode(arguments):
    if len(arguments.paths) < 2 or len(arguments.paths) > 3:
        print('Mirror mode can only take two or three paths')
        exit_with_error()

    # The first two paths are the source and destination directories
    source_directory = arguments.paths[0]
    destination_directory = arguments.paths[1]
    log_directory = arguments.paths[1]  # If there isn't a log directory specified, the destination acts like it
    if arguments.exclusions:
        exclusions = list(chain(*arguments.exclusions))
    else:
        exclusions = None
    if arguments.only:
        only = list(chain(*arguments.only))
    else:
        only = None

    if len(arguments.paths) == 3:
        log_directory = arguments.paths[2]

    mirror_videos(source_directory, destination_directory, log_directory, exclusions, only, arguments.encoding_profile)
예제 #5
0
def _files_mode(arguments):
    if len(arguments.paths) < 2:
        print('Files mode requires at least two paths')
        exit_with_error()
    convert_videos(arguments.paths[:-1], arguments.paths[-1], arguments.encoding_profile)
예제 #6
0
def convert_video(input_file, output_file, encoding_profile):
    print('Converting ' + input_file + ' to ' + output_file)

    if encoding_profile == 'video_passthrough':
        call_parameters = [
            'ffmpeg',
            '-i',
            input_file,
            '-y',
            '-c:v',
            'copy',
            '-c:a',
            'libfdk_aac',
            '-cutoff',
            '18000',
            '-b:a',
            '192k',
            '-ac',
            '2',
            output_file,
        ]

    elif encoding_profile == 'burn_in':
        call_parameters = [
            'ffmpeg',
            '-i',
            input_file,
            '-y',
            '-filter_complex',
            '[0:v][0:s]overlay[overlaid]',
            '-map',
            '[overlaid]',
            '-map',
            '0:a',
            '-c:v',
            'libx264',
            '-preset',
            'medium',
            '-crf',
            '22',
            '-c:a',
            'libfdk_aac',
            '-cutoff',
            '18000',
            '-b:a',
            '192k',
            '-ac',
            '2',
            output_file
        ]

    elif encoding_profile == '720p_burn_in':
        call_parameters = [
            'ffmpeg',
            '-i',
            input_file,
            '-y',
            '-filter_complex',
            '[0:v][0:s]overlay,scale=w=min(1280\,iw):h=min(720\,ih):force_original_aspect_ratio=decrease,'
            'scale=w=trunc(iw/2)*2:h=trunc(ih/2)*2[scaled]',
            '-map',
            '[scaled]',
            '-map',
            '0:a',
            '-c:v',
            'libx264',
            '-preset',
            'medium',
            '-crf',
            '22',
            '-c:a',
            'libfdk_aac',
            '-cutoff',
            '18000',
            '-b:a',
            '192k',
            '-ac',
            '2',
            output_file,
        ]

    elif encoding_profile == '720p':
        call_parameters = [
            'ffmpeg',
            '-i',
            input_file,
            '-y',
            '-filter_complex',
            '[0:v]scale=w=min(1280\,iw):h=min(720\,ih):force_original_aspect_ratio=decrease,'
            'scale=w=trunc(iw/2)*2:h=trunc(ih/2)*2[scaled]',
            '-map',
            '[scaled]',
            '-map',
            '0:a',
            '-c:v',
            'libx264',
            '-preset',
            'medium',
            '-crf',
            '22',
            '-c:a',
            'libfdk_aac',
            '-cutoff',
            '18000',
            '-b:a',
            '192k',
            '-ac',
            '2',
            output_file,
        ]

    else:
        call_parameters = None
        print('Unknown encoding profile: {0}'.format(encoding_profile))
        exit_with_error()

    call(call_parameters)