예제 #1
0
def get_palette(
    video_file_path,
    start=0,
    duration=2.5,
):
    in_file = ffmpeg.input(video_file_path, ss=start, t=duration)
    palette = in_file.filter("palettegen")
    ffmpeg.overwrite_output(palette.output('palette.png')).run()
    return
예제 #2
0
def say_over(message, base_path):
    output = tempfile.NamedTemporaryFile(suffix=".ogg", delete=False)
    with tempfile.NamedTemporaryFile() as temporary:
        subprocess.check_call(
            [espeak, "-v", "it", "-w", temporary.name, message])
        speech = ffmpeg.input(temporary.name).filter('volume', 10)
        base = ffmpeg.input(base_path)
        merged_audio = ffmpeg.filter([base, speech], 'amix')
        ffmpeg.overwrite_output(merged_audio.output(output.name)).run()
    return output.name
예제 #3
0
def make_gif_from_video(video_file_path, start=0, duration=2.5, gif_name=None):
    gif_name = gif_name or drop_extension(video_file_path)
    gif_file_path = gif_name + ".gif"

    # get the file, and make the palette
    in_file = ffmpeg.input(video_file_path, ss=start, t=duration)
    palette = in_file.filter("palettegen")

    # scale and lower framerate:
    smaller = in_file.filter('scale', 480, -1).filter('fps', 12)
    # apply the palette to the video clip, and make into a gif
    output_stream = ffmpeg.filter([smaller, palette],
                                  "paletteuse").output(gif_file_path)
    ffmpeg.overwrite_output(output_stream).run()
    return
예제 #4
0
def download_video(url,
                   file_out='video.mp4',
                   audio=True,
                   duration=5,
                   input_kwargs={},
                   output_kwargs={}):
    """
    Function to download video from 'url'
    'file_out' can take on most extensions, just
    ... read the docs for ffmpeg
    Video will be recorded to 'file_out'
    ... for 'duration' seconds
    If 'audio' is True, audio will be recorded too
    Returns the current working directory + file_out
    """

    local_dir = os.getcwd()
    path = local_dir + '\\' + file_out

    if not audio:
        output_kwargs.update({'an': None})

    stream = ffmpeg.input(url, t=duration, **input_kwargs)
    stream = ffmpeg.output(stream, file_out, **output_kwargs)
    stream = ffmpeg.overwrite_output(stream)

    out, err = ffmpeg.run(stream, capture_stdout=True, capture_stderr=True)

    return path
예제 #5
0
def combine_videos(videos, scores):
    sorted_videos = sorted(Path(videos).iterdir())
    sorted_videos = [
        video for video in sorted_videos if "meta" not in str(video)
    ]

    indices = (get_iteration(v) for v in sorted_videos)
    inputs = [ffmpeg.input(str(v)) for v in sorted_videos]
    texted = [
        ffmpeg.drawtext(v,
                        text=f"{idx} - {score}",
                        x='(w-tw)/2',
                        y='(h-th)',
                        fontcolor='[email protected]',
                        box=1,
                        boxcolor='[email protected]',
                        fontfile='ttf/Hack-Bold.ttf')
        for idx, v, score in zip(indices, inputs, scores)
    ]
    #texted = [ffmpeg.drawtext(v, text=f"{idx} - {score}", x='(w-tw)/2', y='(h-th)', fontcolor='[email protected]', box=1, boxcolor='[email protected]', fontfile='ttf/Hack-Regular.ttf') for idx, v, score in zip(indices, inputs, scores)]
    joined = ffmpeg.concat(*texted)

    out_file = f"/tmp/{uuid.uuid1()}.mp4"
    out = ffmpeg.overwrite_output(ffmpeg.output(joined, out_file))
    out.run()
    return out_file
def save_mp3_to_wav(file):
    """ Convert Flask mp3 file to wav and save
    Flask request.file is wrap request.file.stream
    And request.file.stream ia type: tempfile.SpooledTemporaryFile
    tempfile.SpooledTemporaryFile: Temporary file wrapper, specialized to switch from BytesIO \
    or StringIO to a real file when it exceeds a certain size or when a fileno is needed.
    :param file:
    :return:
    """
    f_path = 'upload_file.wav'
    stream = ffmpeg.input('pipe:0')
    stream = ffmpeg.output(stream, f_path, acodec='pcm_s16le', ac=1, ar='16k')
    # TODO, prompt and log when overwrite
    stream = ffmpeg.overwrite_output(stream)
    # call ffmpeg manually (i.e. p = subprocess.Popen(stream.compile(), stdin=subprocess.PIPE)),
    # use stdin as input in ffmpeg (use pipe:0 as the file name, see [this](https://ffmpeg.org/ffmpeg-protocols.html#pipe))

    # stream.compile() Build command-line for invoking ffmpeg.
    # subprocess.Popen() Execute a child program in a new process
    p = subprocess.Popen(stream.compile(), stdin=subprocess.PIPE)
    CHUNK_SIZE = 1024
    data = file.read(CHUNK_SIZE)
    while data:
        p.stdin.write(data)
        data = file.read(CHUNK_SIZE)
예제 #7
0
def main():
    parser = argparse.ArgumentParser(
        "Split audio file by timestamps using ffmpeg")
    parser.add_argument('timestamps',
                        metavar="timestamps.csv",
                        help="CSV file formatted as <start>,<end>,<filename>")
    parser.add_argument('input', metavar="input.mp3", help="Input audio file")

    args = parser.parse_args()

    splits = []
    with open(args.timestamps) as tsfile:
        tsreader = csv.reader(tsfile)
        for row in tsreader:
            splits.append(
                (ts_to_seconds(row[0]), ts_to_seconds(row[1]), row[2]))

    for i, tp in enumerate(splits):
        start, end, filename = tp

        print("========================================")
        print("Extracting %s (%d out of %d)" % (filename, i, len(splits)))
        print("========================================")
        print()
        # open a file, from `ss`, for duration `t`
        stream = ffmpeg.input(args.input, ss=start, t=(end - start))
        # output to named file
        stream = ffmpeg.output(stream, filename)
        # this was to make trial and error easier
        stream = ffmpeg.overwrite_output(stream)

        # and actually run
        ffmpeg.run(stream)

    print("done")
예제 #8
0
def cut_ranges(filename, ranges):
    """ ranges are in seconds """
    raise AssertionError('Deprecated! Look at concat_ranges!')

    input_vid = ffmpeg.input(filename)

    dir = f'{filename[:-4]}'
    if not os.path.exists(dir):
        os.makedirs(dir)

    count = 0
    for r in ranges:
        start = int(r[0])
        end = math.ceil(r[1])
        out_filename = f'{dir}/out_{count}.mp4'

        print(f'{filename}: Trimming {out_filename} (of {len(ranges)}) from {start} to {end}')

        vid = (
            input_vid
                .trim(start=start, end=end)
                .setpts('PTS-STARTPTS')
        )
        aud = (
            input_vid
                .filter_('atrim', start=start, end=end)
                .filter_('asetpts', 'PTS-STARTPTS')
        )

        joined = ffmpeg.concat(vid, aud, v=1, a=1)
        output = ffmpeg.output(joined, out_filename)
        output = ffmpeg.overwrite_output(output)
        output.run(cmd=ffmpeg_cmd)

        count = count + 1
예제 #9
0
def ffmpeg_trim_audio_clip_atrim_encode(input_file: Path,
                                        stream_index: int,
                                        timestamp_start: int,
                                        timestamp_end: int,
                                        quality: Union[int, None],
                                        to_mono: bool,
                                        normalize_audio: bool,
                                        outpath: Path,
                                        format: str = None,
                                        capture_stdout: bool = False,
                                        silent: bool = True):
    r"""
    Take media file and export a trimmed audio file.
    :param stream_index: FFmpeg stream index. If input is not a container format, 0 should be used.
    :param capture_stdout: If true, returns stdout. Used in conjunction with outpath="pipe:" and format option.
    :param input_file: Path to video/audio file to clip from.
    :param timestamp_start: Start time in milliseconds.
    :param timestamp_end: End time in milliseconds.
    :param quality: If output extension is .mp3, this is the bitrate in kbps. Ignored otherwise.
    :param to_mono: If set, mixes all input channels to mono to save space
    :param normalize_audio: If set, attempts to normalize loudness of output audio. YMMV.
    :param outpath: Path to save to.
    :param format: Output format (e.g. mp3, flac, etc), required if extension of outpath is missing/not the intended
                    format. Required if outpath is "pipe:" since there is no output extension to infer from.
    :param silent: If set, suppresses stderr.
    :return: FFmpeg stdout data if capture_stdout is set
    """
    input_stream = ffmpeg.input(str(input_file))
    input_stream = input_stream[str(stream_index)]

    input_stream = input_stream.filter("atrim",
                                       start=timestamp_start / 1000,
                                       end=timestamp_end / 1000).filter(
                                           "asetpts", "PTS-STARTPTS")

    if normalize_audio:
        input_stream = input_stream.filter("loudnorm", print_format="summary")

    kwargs = {}

    if outpath.suffix.lower() == ".mp3":
        if quality is not None:
            kwargs['audio_bitrate'] = f'{quality}k'
        else:
            kwargs['audio_bitrate'] = '320k'

    if to_mono:
        kwargs['ac'] = 1  # audio channels

    if format is not None:
        kwargs['format'] = format
    input_stream = ffmpeg.output(input_stream, str(outpath), **kwargs)

    input_stream = ffmpeg.overwrite_output(input_stream)
    args = input_stream.get_args()
    # logging.debug(f"ffmpeg_trim_audio_clip: args: {args}")
    stdout, stderr = ffmpeg.run(input_stream,
                                capture_stdout=capture_stdout,
                                capture_stderr=silent)
    return stdout
예제 #10
0
def crop_video(
        filename,
        xmin,
        xmax,
        ymin,
        ymax,
        out_name=None,
        speed='superfast',
        bit_rate='20000k'):

    if out_name is None:
        core, ext = os.path.splitext(filename)
        if ext == '.MP4':
            ext = '.mp4'
        out_name = core + '_crop' + ext
    width = xmax - xmin
    height = ymax - ymin
    stream = ffmpeg.input(filename)
    stream = ffmpeg.crop(
        stream,
        xmin,
        ymin,
        width,
        height)
    stream = ffmpeg.output(
        stream,
        out_name,
        preset=speed,
        video_bitrate=bit_rate)
    stream = ffmpeg.overwrite_output(stream)
    ffmpeg.run(stream, quiet=True)
예제 #11
0
def convert(file_name: str, convert_ext):
    tmp_path = os.getcwd() + "\\" + tmp_dir_path + "\\" + file_name

    convert_dir_path = "convert"

    if os.path.exists(convert_dir_path) is False:
        os.mkdir(convert_dir_path)

    convert_path = os.getcwd(
    ) + "\\" + convert_dir_path + "\\" + file_name.split(
        ".")[0] + "." + convert_ext

    if os.path.exists(log_dir_path) is False:
        os.mkdir(log_dir_path)

    log_path = os.getcwd() + "\\" + log_dir_path + "\\" + file_name.split(
        ".")[0] + ".txt"
    kwargs = {"progress": log_path}

    try:
        stream = ffmpeg.input(tmp_path)
        stream = ffmpeg.output(stream, convert_path, **kwargs)
        stream = ffmpeg.overwrite_output(stream)
        ffmpeg.run(stream)
    except Exception as e:
        print(e)
    finally:
        os.remove(tmp_path)
        return ""
예제 #12
0
def extract(source_path):
    wav_path = source_path + '.wav'

    stream = ffmpeg.input(source_path)
    stream = ffmpeg.output(stream, wav_path, acodec='pcm_s16le', ac=1)
    stream = ffmpeg.overwrite_output(stream)
    ffmpeg.run(stream, capture_stderr=True)

    wav, fr = _read_wave(wav_path)
    wav = wav[0]

    feat = dict()

    feat['sample_rate'] = fr
    feat['length'] = wav.size
    feat['time_ms'] = wav.size * 1000 // fr

    feat['db'] = _db(wav)
    feat['sound_sect'] = _sound_section(wav, fr)
    feat['power_spec'], feat['freq'], feat['pitch'] = _spectrum(wav, fr)

    nfilt = 16
    high_freq = 8000
    filter_type = 'mel'
    feat['fbank_spec'], feat['fbank_freq'] = _fbank(wav, sample_rate=fr, nfilt=nfilt,
                                                    high_freq=high_freq, type=filter_type)

    feat['pitch_reaper'] = _pitch_reaper(wav_path)

    wav, fr = librosa.load(wav_path)
    feat['pitch_librosa'] = _pitch_librosa(wav, fr)

    os.remove(wav_path)
    return feat
예제 #13
0
def _save_video(path, array, fps=25, video_codec='libx264'):

    # Check the extension of the given file
    path = _check_extensions([path], extensions=['.mp4'])[0]

    # Get the informations from the array
    n, height, width, channels = array.shape

    # Initialize the process
    process = ffmpeg.input('pipe:',
                           format='rawvideo',
                           pix_fmt='rgb24',
                           s='{}x{}'.format(width, height))
    process = ffmpeg.output(process,
                            path,
                            pix_fmt='yuv420p',
                            vcodec=video_codec,
                            r=fps)
    process = ffmpeg.overwrite_output(process)
    process = ffmpeg.run_async(process, pipe_stdin=True)

    # Save all the frames
    for frame in array:
        process.stdin.write(frame.tobytes())

    # Terminate the process
    process.stdin.close()
    process.wait()
예제 #14
0
파일: videos.py 프로젝트: serans1/dtlpy
    def reencode(filepath, loglevel='panic'):
        """
        Re-encode video as mp4, remove start offset and set bframes to 0

        :param filepath: input video file
        :param loglevel: ffmpeg loglevel
        :return:
        """
        try:
            import ffmpeg
        except ImportError:
            logger.error(
                'Import Error! Cant import ffmpeg. '
                'Annotations operations will be limited. import manually and fix errors'
            )
            raise
        if not os.path.isfile(filepath):
            raise IOError('File doesnt exists: {}'.format(filepath))
        # re encode video without b frame and as mp4
        basename, ext = os.path.splitext(filepath)
        output_filepath = os.path.join(
            basename,
            os.path.basename(filepath).replace(ext, '.mp4'))
        if not os.path.isdir(os.path.dirname(output_filepath)):
            os.makedirs(os.path.dirname(output_filepath))
        try:
            stream = ffmpeg.input(filepath, **{
                'loglevel': loglevel
            }).output(output_filepath, **{
                'x264opts': 'bframes=0',
                'f': 'mp4'
            })
            ffmpeg.overwrite_output(stream).run()
        except Exception as e:
            logger.exception('ffmpeg error in disassemble:')
            raise

        output_probe = Videos.get_info(output_filepath)
        start_time = eval(output_probe['streams'][0]['start_time'])
        fps = eval(output_probe['streams'][0]['avg_frame_rate'])
        has_b_frames = output_probe['streams'][0]['has_b_frames']
        start_frame = fps * start_time
        if start_time != 0:
            logger.warning('Video start_time is not 0!')
        if has_b_frames != 0:
            logger.warning('Video still has b frames!')
        return output_filepath
def convertToVideo(path):
	stream = ffmpeg.input(r'tweetimages/'+path+'/*.png', pattern_type='glob', framerate=0.33)
	#stream = ffmpeg.input(r'tweetimages/*.png', pattern_type='glob', framerate=1)
	#stream = ffmpeg.output(stream,'tweetimages/movie1.mp4')
	stream = ffmpeg.output(stream,'Videos/'+path+'.mp4',loglevel="quiet")
	stream = ffmpeg.overwrite_output(stream)
	ffmpeg.run(stream)
	shutil.rmtree('tweetimages/'+path)
예제 #16
0
def encode_frames(directory: str, output: str, framerate: int,
                  pad_length: int):
    frames = ffmpeg.input(pjoin(directory, f"%0{pad_length}d.png"),
                          **{"pattern_type": "sequence"})
    frames = ffmpeg.filter(frames, "fps", fps=framerate)
    frames = ffmpeg.output(frames, output)
    frames = ffmpeg.overwrite_output(frames)
    ffmpeg.run(frames)
예제 #17
0
def ffmpeg_condense_audio(audiofile, sub_times, outfile=None):
    if outfile is None:
        outfile = "condensed.flac"
    # logging.info(f"saving condensed audio to {outfile}")

    # get samples in audio file
    audio_info = ffmpeg.probe(audiofile, cmd='ffprobe')
    sps = int(
        audio_info['streams'][0]['time_base'].split('/')[1])  # audio samples per second, inverse of sampling frequency
    # samples = audio_info['streams'][0]['duration_ts']  # total samples in audio track

    stream = ffmpeg.input(audiofile)
    clips = list()
    for time in sub_times:  # times are in milliseconds
        start = int(time[0] * sps / 1000)  # convert to sample index
        end = int(time[1] * sps / 1000)
        # use start_pts for sample/millisecond level precision
        clips.append(stream.audio.filter('atrim', start_pts=start, end_pts=end).filter('asetpts', 'PTS-STARTPTS'))
    combined = ffmpeg.concat(*clips, a=1, v=0)
    if os.path.splitext(outfile)[1] == ".mp3":
        combined = ffmpeg.output(combined, outfile, audio_bitrate='320k')  # todo: make this user-settable
    else:
        combined = ffmpeg.output(combined, outfile)
    combined = ffmpeg.overwrite_output(combined)
    logging.debug(f"ffmpeg arguments: {' '.join(ffmpeg.get_args(combined))}")
    args = ffmpeg.get_args(combined)
    if len("ffmpeg " + " ".join(args)) > 32766 and os.name == 'nt':
        logging.warning("Arguments passed to ffmpeg exceeds 32767 characters while running on a Windows system. "
                        "Will try using a temporary file to pass filter_complex arguments to ffmpeg.")
        idx = args.index("-filter_complex") + 1
        complex_filter = str(args[idx])
        # write complex_filter to a temporary file
        fp = tempfile.NamedTemporaryFile(delete=False)  # don't delete b/c can't open file again when it's already open in windows, need to close first
        fp.write(complex_filter.encode(encoding="utf-8"))
        fp.close()
        args[idx] = fp.name
        args[idx - 1] = "-filter_complex_script"
    args = ["ffmpeg"] + args

    # ffmpeg.run(combined, quiet=logging.getLogger().getEffectiveLevel() >= logging.WARNING)

    pipe_stdin = False
    pipe_stdout = False
    pipe_stderr = False
    quiet = logging.getLogger().getEffectiveLevel() >= logging.WARNING

    stdin_stream = subprocess.PIPE if pipe_stdin else None
    stdout_stream = subprocess.PIPE if pipe_stdout or quiet else None
    stderr_stream = subprocess.PIPE if pipe_stderr or quiet else None
    process = subprocess.Popen(
        args, stdin=stdin_stream, stdout=stdout_stream, stderr=stderr_stream
    )
    out, err = process.communicate(input)
    retcode = process.poll()
    if retcode:
        raise Error('ffmpeg', out, err)
def demo_extract_audio():
    host = '172.31.23.124'
    stream = '2'
    stream = ffmpeg.input('rtsp://' + host + '/' + stream)
    stream = stream['a']
    # 只抽出MPEG-4 AAC音频不转码
    stream = ffmpeg.output(stream, 'out/rtsp_audio.mp4', strict='-2')
    # 直接覆盖同名文件不询问
    stream = ffmpeg.overwrite_output(stream)
    stream.run(capture_stdout=True)
예제 #19
0
def generate_sequence(d):
    '''will expect correct folders and files'''
    d = os.path.abspath(d)
    console.rule(d, align='left')
    d_seq = os.path.join(d, 'sequences')
    console.print(d_seq)
    #  stream = None
    #  files = [d.path for d in os.scandir(d_seq) if d.is_file()]
    frames = []

    for root, dirs, files in os.walk(d_seq):
        #  files = [f for f in files if ('circle' in f or 'line' in f) ]
        files = [f for f in files if '.png' in f]
        files = [f for f in files if 'zoom' not in f]
        with open(f'{d}/output/sequence.lst', 'w') as lst:
            for f in sorted(files):
                png = os.path.join(d_seq, f)
                mp4 = f'{d}/output/{f}.mp4'
                frame = ffmpeg.input(png, r=1)
                frame = ffmpeg.output(frame, mp4)
                frame = ffmpeg.overwrite_output(frame)
                ffmpeg.run(frame)
                #  frames.append(frame)

                lst.write(f'file {mp4}\n')
                #  frames.append(ffmpeg.input(png, r=1))
                #  frames.append(ffmpeg.input(os.path.join(d_seq, f), frames=24))
                f = os.path.splitext(f)[0]
                #  num, *type = f.split('-')
                #  print(int(num), *type)

    #  out = ffmpeg.merge_outputs(*frames)
    #  print(ffmpeg.get_args(out))
    #  out = ffmpeg.concat(*frames)
    #  out = ffmpeg.input('output/sequence.lst', f='concat')
    #  out = ffmpeg.input('output/sequence.lst')
    #  out = ffmpeg.output(out, 'sequences3.mp4', unsafe=False)

    #  files = [f.path for f in list(os.scandir('output')) if '.mp4' in f.path]
    #  stream = ''
    #  inputs = []
    #  for f in files:
    #  inputs.append(ffmpeg.input(f))

    #  out = ffmpeg.output(*inputs, 'sequences3.mp4')
    #  ffmpeg.run(out)
    proc = ['ffmpeg']
    proc.append('-f')
    proc.append('concat')
    proc.append('-i')
    proc.append('output/sequence.lst')
    proc.append('-r')
    proc.append('60')
    proc.append('sequence4.mp4')
    subprocess.run(proc)
예제 #20
0
def videoConvert(inputFile, outputFile):
    stream = ffmpeg.input(inputFile, loglevel="error", stats="")
    stream = ffmpeg.output(stream, outputFile)
    stream = ffmpeg.overwrite_output(stream)

    print("Converting {}:".format(inputFile))
    initial_time = time.time()
    ffmpeg.run(stream)
    overall = time.time() - initial_time
    print("Overall convert time", overall)
    return overall
예제 #21
0
def ffmpeg_export(
    p_indir
):  # the real meat, this is where i struggle with ffmpeg-python and occasionally succeed
    des_w = int(entry_w.get())
    des_h = int(entry_h.get())
    if (des_w > sel_w) or (des_h > sel_h):
        messagebox.showerror(
            title="Error", message="Desired size is larger than source size!")
        return
    sel_ratio = sel_w / sel_h
    des_ratio = des_w / des_h
    # safe placeholder values for when src and output have the same ratio
    x_offset = 0
    y_offset = 0
    adj_w = sel_w
    adj_h = sel_h
    if (crop_h.get() == 1) and (sel_ratio != des_ratio):
        adj_w = des_ratio * sel_h  # get the new width for the desired aspect ratio
        x_offset = (sel_w - adj_w) / 2  # centering math
    elif (crop_h.get() == 0) and (sel_ratio != des_ratio):
        adj_h = des_ratio * sel_w
        y_offset = (sel_h - adj_h) / 2
    for x in files:
        x = p_indir + os.sep + x
        progress_ffmpeg.config(text='Rendering: ' + os.path.split(x)[1])
        frame_ffmpeg.update()
        # ffmpeg complains if we try to output to the same file as our input
        # so we output to a different file and replace the input afterwards
        outdir = x + '~.png'
        if overwrite_og.get() == 0 and use_custom_outdir.get() == 0:
            newdir = os.path.dirname(str(x)) + '_' + \
                str(des_w) + 'x' + str(
                    des_h)  # results in {old directory}_{width}x{height} in the old directory's parent dir
            outdir = newdir + os.sep + str(os.path.split(x)[1])
            if not os.path.isdir(newdir):
                os.mkdir(newdir)
        elif use_custom_outdir.get() == 1:
            outdir = custom_outdir + os.sep + str(os.path.split(x)[1])
        stream = ffmpeg.input(str(x), nostdin=None)
        stream = ffmpeg.crop(stream, x_offset, y_offset, adj_w, adj_h)
        stream = ffmpeg.filter(
            stream, "scale", des_w, des_h,
            flags="bilinear")  # TODO: allow user to choose algorithm
        stream = ffmpeg.output(
            stream, outdir, hide_banner=None
        )  # TODO: find a way to stop making a new shell for each op
        stream = ffmpeg.overwrite_output(stream)
        ffmpeg.run_async(stream)
        if overwrite_og.get(
        ) == 1:  # check again because overwriting when we're not supposed to is bad mkay
            os.remove(x)
            os.rename(x + '~.png', x)
    progress_ffmpeg.config(text='Rendering: Done!')
예제 #22
0
파일: prep.py 프로젝트: ncoop57/tango
    def _fix_framerate(self, vid_path, fr, overwrite):
        """
            Fixes each video in the list of video paths to a certain frame rate.
        """
        output_path = str(vid_path) if overwrite else str(
            vid_path.parent / f'{vid_path.stem}_fixed_{fr}.mp4')
        stream = ffmpeg.input(vid_path)
        stream = ffmpeg.output(stream, output_path, r=fr)
        stream = ffmpeg.overwrite_output(stream)
        out, err = ffmpeg.run(stream)

        return Path(output_path)
예제 #23
0
def convert_to_wav(tmp_path, dest_path):
    """Convert between any audio format supported by ffmpeg

    Args:
        tmp_path: string, input file path with some audio extension at the end
                    (example: ./data/foo/name.mp3)
        dest_path: string, output path to which file will be converted to 
                    (example: ./data/bar/name.wav)
    """
    stream = ffmpeg.input(tmp_path)
    stream = ffmpeg.output(stream, dest_path)
    stream = ffmpeg.overwrite_output(stream)
    ffmpeg.run(stream)
예제 #24
0
파일: video.py 프로젝트: milesgray/CALAE
def save_video(fname, images, output_fps=30, vcodec='libx264', filters=''):
    assert isinstance(images, np.ndarray), "images should be np.array: NHWC"
    num_frames, height, width, channels = images.shape
    stream = ffmpeg.input('pipe:', format='rawvideo', 
                          pix_fmt='rgb24', s='{}x{}'.format(width, height))
    stream = ffmpeg.filter(stream, 'setpts', '2*PTS')  # 2*PTS is for slower playback
    stream = ffmpeg.output(stream, fname, pix_fmt='yuv420p', vcodec=vcodec, r=output_fps)
    stream = ffmpeg.overwrite_output(stream)
    process = ffmpeg.run_async(stream, pipe_stdin=True)
    for frame in tqdm(images, desc='writing video to %s' % fname):
        process.stdin.write(frame.astype(np.uint8).tobytes())
    process.stdin.close()
    process.wait()
예제 #25
0
def convert_video(avi_file, source_file_path):
    source_file_dir = os.path.dirname(source_file_path)
    source_file_name = os.path.splitext(os.path.basename(source_file_path))[0]
    final_file_path = source_file_dir + "/" + source_file_name + ".mp4"
    stream = ffmpeg.input(avi_file)
    # stream = ffmpeg.output(stream, source_file_dir+"/"+source_file_name+".mp4", vcodec='libx264', metadata='s:v rotate="0"', vf="transpose=3", crf=23, acodec="copy")
    stream = ffmpeg.output(stream,
                           final_file_path,
                           vcodec='libx264',
                           crf=23,
                           acodec="copy")
    stream = ffmpeg.overwrite_output(stream)
    ffmpeg.run(stream)
    return final_file_path
 def convert(self, scale_width):
     # self.message.reply_text('🔥 Testing video conversion 🔥')
     stream = ffmpeg.input('temp.' + self.ext)
     audio_stream = stream.audio
     if scale_width:
         stream = ffmpeg.filter(stream, 'scale', 640, -1)
     else:
         stream = ffmpeg.filter(stream, 'scale', -1, 640)
     out_stream = ffmpeg.concat(stream, audio_stream, v=1, a=1)
     output_filename = 'temp.converted.' + self.ext
     out_stream = ffmpeg.output(out_stream, output_filename)
     out_stream = ffmpeg.overwrite_output(out_stream)
     ffmpeg.run(out_stream)
     self.bot.send_video(chat_id=self.message.chat_id, video=open(output_filename, 'rb'), supports_streaming=True)
예제 #27
0
def output_segment_video(segment_video, segment_video_path):
    # if os.path.exists(segment_video_path):
    #     os.rename(segment_video_path, segment_video_path + '.old')
    #     segment_video_input_file = segment_video_path + '.old'
    # else:
    #     segment_video_input_file = config.background_video
    segment_video = ffmpeg.output(segment_video,
                                  segment_video_path,
                                  preset='ultrafast',
                                  loglevel=config.ffmpeg['error_level'],
                                  threads=config.ffmpeg['threads'])

    segment_video = ffmpeg.overwrite_output(segment_video)
    ffmpeg.run(segment_video)
예제 #28
0
    def disassemble(filepath, fps=None, loglevel='panic'):
        """
        Disassemble video to images

        :param filepath: input video filepath
        :param fps: rate of disassemble. e.g if 1 frame per second fps is 1. if None all frames will be extracted
        :param loglevel: ffmpeg loglevel
        :return:
        """
        import ffmpeg
        if not os.path.isfile(filepath):
            logger.exception('File doesnt exists')
            raise IOError
        basename, ext = os.path.splitext(filepath)
        # create folder for the frames
        if not os.path.exists(basename):
            os.makedirs(basename, exist_ok=True)
        # get video information
        video_props = Videos.get_info(filepath)
        if fps is None:
            fps = eval(video_props['streams'][0]['avg_frame_rate'])
        num_of_zeros = len(video_props['streams'][0]['nb_frames'])
        # format the output filename
        output_regex = os.path.join(basename, '%%0%dd.jpg' % num_of_zeros)

        try:
            stream = ffmpeg.input(filepath, **{
                'loglevel': loglevel
            }).output(output_regex, **{
                'start_number': '0',
                'r': str(fps)
            })
            ffmpeg.overwrite_output(stream).run()
        except Exception as e:
            logger.exception('ffmpeg error in disassemble:')
            raise
        return basename
예제 #29
0
def concat_ranges(filename, out_filename, ranges, config: VideoMontageConfig):
    """ ranges are in seconds """

    assert os.path.isfile(filename)

    input_vid = ffmpeg.input(filename)

    total_duration = sum([x[1] - x[0] for x in ranges])
    print(f'Processing {out_filename} ({len(ranges)} ranges -> {total_duration:.0f} seconds)')

    streams = []

    for r in ranges:
        start = int(r[0])
        end = math.floor(r[1])

        vid = (
            input_vid
                .trim(start=start, end=end)
                .setpts('PTS-STARTPTS')
        )
        aud = (
            input_vid['a:0']
                .filter_('atrim', start=start, end=end)
                .filter_('asetpts', 'PTS-STARTPTS')
        )

        if config.mix_mic_audio_track:
            mic = (
                input_vid['a:1']
                    .filter_('atrim', start=start, end=end)
                    .filter_('asetpts', 'PTS-STARTPTS')
            )
            aud = ffmpeg.filter([aud, mic], 'amix', duration='shortest', weights=f'1 {config.mic_volume_multiplier}')

        streams.append(vid)
        streams.append(aud)

    joined = ffmpeg.concat(*streams, v=1, a=1)
    output = ffmpeg.output(joined, out_filename, vcodec='hevc_nvenc', video_bitrate=config.video_bitrate)
    output = output.global_args('-loglevel', 'error')
    output = ffmpeg.overwrite_output(output)

    start_time = time.time()

    custom_ffmpeg_run(output, ffmpeg_cmd)

    elapsed = time.time() - start_time
    print(f'Elapsed {elapsed:.2f} seconds\n')
예제 #30
0
    def process_file(self, track: Track):
        """
        Attempts to transcode the file in download/temp into the audio file
        """

        temp_file = Path("download/temp")
        if not temp_file.is_file():
            raise Exception("temp file doesn't exist")

        input_ffmpeg = ffmpeg.input("download/temp")
        input_audio = input_ffmpeg['a'] # We will not be referencing the video stream, only the main audio stream

        # Normalise loudness
        input_audio = ffmpeg.filter(input_audio, "loudnorm", I=-16, TP=-1.5, LRA=11)


        # https://superuser.com/questions/1362176/how-to-trim-silence-only-from-beginning-and-end-of-mp3-files-using-ffmpeg/1364824
        # Trim silence from start
        input_audio = ffmpeg.filter(input_audio, "silenceremove", start_periods=1, start_duration=1, start_threshold="-60dB", detection="peak")

        # No idea what this does
        input_audio = ffmpeg.filter(input_audio, "aformat", "dblp")

        # Reverse the audio
        input_audio = ffmpeg.filter(input_audio, "areverse")

        # Trim silence from start (but this track is reversed now, so this is trimming from the end
        input_audio = ffmpeg.filter(input_audio, "silenceremove", start_periods=1, start_duration=1, start_threshold="-60dB", detection="peak")

        # No idea what this does
        input_audio = ffmpeg.filter(input_audio, "aformat", "dblp")

        # Reverse the audio
        input_audio = ffmpeg.filter(input_audio, "areverse")

        output_ffmpeg = ffmpeg.output(input_audio, filename=f"download/{track.info.source_id}.mp3")
        output_ffmpeg = ffmpeg.overwrite_output(output_ffmpeg) # overwrite if needed


        def run_ffmpeg(output):
            return ffmpeg.run(output, quiet=True)

        # Force monkey patching to run this in the background in this supposed background task...
        tpool.execute(run_ffmpeg, output_ffmpeg)

        try:
            os.remove("download/temp")
        except:
            raise Exception("failed to delete temp file")