def _copy(self, src, dst, overwrite=False):
     if self.dry_run:
         print('Copy: {}=>{}'.format(src, dst))
     else:
         if not overwrite and check_exists(dst, log=self.dry_run):
             return False
         create_dirs(dst)
         shutil.copy(src, dst)
         return True
def cut(input, output, start=None, end=None):
    if check_exists(output):
        return -1
    create_dirs(output)
    args = [ffmpeg(), '-i', input]
    args.extend(['-c:v', 'copy'])
    args.extend(['-c:a', 'copy'])
    args.extend(['-c:s', 'copy'])
    args.extend(['-map', '0'])
    if start:
        args.extend(['-ss', str(start)])
    if end:
        args.extend(['-to', str(end)])
    args.append(output)
    return execute(args)
def combine(video,
            srt,
            output,
            lang=None,
            overwrite=False,
            convert=False,
            crf=DEFAULT_CRF,
            preset=DEFAULT_PRESET,
            skip_eia_608=True):
    if not overwrite and check_exists(output):
        return -1

    if srt.endswith('.ttml') or srt.endswith('.xml'):
        logger.debug('Converting ttml/xml to srt')
        name, _ = os.path.splitext(srt)
        srt_out = name + '.srt'
        convert_to_srt(srt, srt_out)
        srt = srt_out
    create_dirs(output)
    args = [ffmpeg(), '-i', video]
    if overwrite:
        args.append('-y')
    args.extend(['-i', srt])
    args.extend(['-map', '0:v', '-map', '0:a'])
    if skip_eia_608:
        metadata = extract_metadata(video)
        for i in (s.index for s in metadata.subtitle_streams
                  if s.codec != 'eia_608'):
            args.extend(['-map', '0:{}'.format(i)])
    else:
        args.extend(['-map', '0:s?'])
    args.extend(['-map', '1:0'])
    if convert:
        args.extend(['-c:v', 'libx264', '-crf', str(crf), '-preset', preset])
        args.extend(['-c:a', 'aac'])
    else:
        args.extend(['-c:v', 'copy'])
        args.extend(['-c:a', 'copy'])
    args.extend(['-c:s', 'copy'])
    # -metadata:s:s:0 language=eng
    if lang:
        args.extend(['-metadata:s:s:0', 'language=' + lang])
    args.append(output)
    return execute(args)
def create_remux_args(input_files: List[str],
                      output_file: str,
                      mappings: List,
                      overwrite=False,
                      metadata={}):
    """

    :param input_files:
    :param output_file:
    :param mappings:
    :param overwrite:
    :param metadata: {'s:0': {'language':'eng'}, '': {'title': 'A Great Movie'}}
    :return:
    """
    if not overwrite and check_exists(output_file):
        return -1
    args = [ffmpeg()]
    if overwrite:
        args.append('-y')
    for input_file in input_files:
        args.extend(['-i', input_file])
    args.extend(['-c', 'copy'])
    for m in mappings:
        if type(m) == int:
            args.extend(['-map', '0:{}'.format(m)])
        else:
            args.extend(['-map', m])
    for key, value in metadata.items():
        if key:
            key = ':s:' + key
        for meta_key, meta_val in value.items():
            args.append('-metadata{}'.format(key))
            args.append('{}={}'.format(meta_key, meta_val))

    args.append(output_file)
    return args
def convert_with_config(input,
                        output,
                        config: ConvertConfig,
                        print_output=True,
                        overwrite=False,
                        metadata=None,
                        mappings=None,
                        use_nice=True):
    """

    :param input:
    :param output:
    :param config:
    :param print_output:
    :param overwrite:
    :param metadata:
    :param mappings: List of mappings (for example ['0:0', '0:1'])
    :return:
    """
    if not overwrite and check_exists(output):
        return -1
    if print_output:
        print('Converting {} -> {}'.format(input, output))
        print('Using config: {}'.format(config))

    if not metadata:
        metadata = create_metadata_extractor().extract(
            input, detect_interlace=config.deinterlace)
    elif config.deinterlace and not metadata.interlace_report:
        raise Exception(
            'Metadata provided without interlace report, but convert requires deinterlace checks'
        )

    if metadata.resolution not in (Resolution.LOW_DEF, Resolution.STANDARD_DEF,
                                   Resolution.MEDIUM_DEF,
                                   Resolution.HIGH_DEF) and not config.scale:
        print('{}: Resolution not supported for conversion: {}'.format(
            input, metadata.resolution))
        # TODO Handle converting 4k content in H.265/HVEC
        return -2
    if use_nice and nice_exe:
        args = [nice_exe, ffmpeg()]
    else:
        args = [ffmpeg()]
    if overwrite:
        args.append('-y')
    args.extend(['-i', input])

    if config.scale:
        args.extend(['-vf', 'scale=-1:{}'.format(config.scale)])

    args.extend(['-c:v', config.video_codec])
    crf = config.crf
    bitrate = config.bitrate
    if VideoCodec.H264.equals(
            config.video_codec
    ) and config.bitrate is not None and config.bitrate != 'disabled':
        crf = 1
        # -x264-params vbv-maxrate=1666:vbv-bufsize=3332:crf-max=22:qpmax=34
        if config.bitrate == 'auto':
            bitrate = auto_bitrate_from_config(metadata.resolution, config)
        params = 'vbv-maxrate={}:vbv-bufsize={}:crf-max=25:qpmax=34'.format(
            str(bitrate), str(bitrate * 2))
        args.extend(['-x264-params', params])
    elif VideoCodec.H265.equals(
            config.video_codec
    ) and config.bitrate is not None and config.bitrate != 'disabled':
        raise Exception('Avg Bitrate not supported for H265')

    args.extend(['-crf', str(crf), '-preset', config.preset])
    if config.deinterlace:
        is_interlaced = metadata.interlace_report.is_interlaced(
            config.deinterlace_threshold)
        if print_output:
            print('{} - Interlaced: {}'.format(metadata.interlace_report,
                                               is_interlaced))
        if is_interlaced:
            # Video is interlaced, so add the deinterlace filter
            args.extend(['-vf', 'yadif'])

    args.extend(['-c:a', config.audio_codec])

    index = 0
    for audio in metadata.audio_streams:
        if audio.channels == 7:
            # 6.1 sound, so mix it up to 7.1
            args.extend(['-ac:a:{}'.format(index), '8'])
        index += 1

    if config.include_subtitles:
        args.extend(['-c:s', 'copy'])

    if not mappings:
        args.extend(['-map', '0'])
    else:
        for m in mappings:
            if type(m) == int:
                args.extend(['-map', '0:{}'.format(m)])
            else:
                args.extend(['-map', m])

    if config.include_meta:
        args.extend(['-metadata', 'ripped=true'])
        args.extend(['-metadata:s:v:0', 'ripped=true'])
    args.append(output)

    return execute(args, print_output)