예제 #1
0
def render_video(recording, output, dry, quality, audio_bitrate):
    start = time.time()
    logging.debug("Rendering video from frame %s to %s",
                  str(recording.start_frame), str(recording.end_frame))

    if dry:
        recording.sorted_location = "** DRY RUN **"
        return

    recording.sorted_location = get_next_filename(
        os.path.join(output, recording.matched_model))

    ffmpeg = FFmpeg().input(recording.original_location).output(
        recording.sorted_location, {
            'codec:v': 'libx265',
            'codec:a': 'eac3',
            'tag:v': 'hvc1',
            'preset': 'fast',
            'crf': quality,
            'b:a': audio_bitrate,
            'vf': f'scale={recording.dimension}:flags=lanczos',
            'ss': calculate_timestamp_fps(recording.start_frame,
                                          recording.fps),
            'to': calculate_timestamp_fps(recording.end_frame, recording.fps)
        })

    @ffmpeg.on('progress')
    def on_progress(progress):
        progressbar.update_to(progress.frame)

        if recording.average_bitrate == 0:
            recording.average_bitrate = progress.bitrate
        else:
            recording.average_bitrate = round(
                (recording.average_bitrate + progress.bitrate) / 2)

    @ffmpeg.on('terminated')
    def on_terminated():
        raise Exception('ffmpeg was externally terminated')

    @ffmpeg.on('error')
    def on_error(code):
        raise Exception('ffmpeg exited with ' + code)

    loop = asyncio.get_event_loop()

    tqdm_out = TqdmToLogger(logging.getLogger(), level=logging.INFO)
    progressbar = TqdmUpTo(total=recording.end_frame - recording.start_frame +
                           1,
                           desc="Rendering video",
                           unit="frame",
                           file=tqdm_out,
                           bar_format='{l_bar}{bar:50}{r_bar}{bar:-50b}',
                           ascii=False)

    loop.run_until_complete(ffmpeg.execute())
    progressbar.close()

    logging.debug("Finished rendering in in %ss",
                  str(round(time.time() - start, 2)))
예제 #2
0
def compare(path=u'../02-cut-00.mp4',
            width=1280,
            height=720,
            vcodec='libx264',
            preset='faster',
            crf=23):

    ffmpeg = FFmpeg(path=path)
    output = '%s/%s.%s' % (ffmpeg.root, preset, ffmpeg.attr)
    cmd = 'ffmpeg.exe -i "%s" -s %dx%d  -vcodec %s -preset %s -crf %d "%s"' % (
        ffmpeg.path, width, height, vcodec, preset, crf, output)
    cost = ffmpeg.execute(cmd)
    return cost
예제 #3
0
from ffmpeg import FFmpeg
import asyncio
import sys

ffscale = FFmpeg()


@ffscale.on('completed')
def on_complete():
    print("completed")


# @ffscale.on('progress')
# def on_ffprobe_progress(progress):
#     print(progress.resolution)

new_file = sys.argv[1] + "_scale"
filter_scale = "scale=" + sys.argv[2]

ffscale.input(sys.argv[1])
ffscale.output(new_file, {'filter_complex': filter_scale}, f='mp4')
loop = asyncio.get_event_loop()
loop.run_until_complete(ffscale.execute())
loop.close()
예제 #4
0
    def download(self):
        metadata = None
        track_image_path = None

        asyncio.set_event_loop(asyncio.new_event_loop())
        loop = asyncio.get_event_loop()

        if self.metadata_filepath is not None:
            if self.is_album:
                tg = TitleGenerator(self.metadata_filepath, self.artist)
            else:
                tg = TitleGenerator(self.metadata_filepath,
                                    self.artist,
                                    no_album=True)

            tg.make_titles()
            metadata = tg.get_titles()

        for num, url in self.urls:
            yt = None
            image_dl_failed = False
            failed_image_url = ""
            self.cur_song = num + self.start + 1
            try:
                if self.proxies is not None:
                    yt = YouTube(url, proxies=self.proxies)
                else:
                    yt = YouTube(url)

            except Exception as e:
                self.retry_urls.append((num, url))
                print(
                    f"Downloading song {font.apply('gb', str(self.cur_song))} - {font.apply('bf', '[Failed - ')} {font.apply('bf', str(e) + ']')}\n"
                )
                continue

            path = None
            try:
                yt.register_on_progress_callback(self.progress_function)
                self.cur_video = (yt.streams.filter(
                    type="audio",
                    subtype="mp4").order_by("abr").desc().first())

                safe_name = extract_title(
                    make_safe_filename(self.cur_video.title))
                path = self.cur_video.download(
                    output_path=self.outdir,
                    filename=safe_name,
                )
                self.successful_filepaths.append(path)
                self.successful += 1
            except (Exception, KeyboardInterrupt) as e:
                self.retry_urls.append((num, url))
                print(
                    f"Downloading song {font.apply('gb',str(self.cur_song))+' - '+font.apply('gb', self.cur_video.title)} - {font.apply('bf', '[Failed - ')} {font.apply('bf', str(e) + ']')}\n"
                )

                continue
            # if self.is_album:
            #     if self.image_filepath is None:
            #         if not self.album_image_set:
            #             image_path = Downloader.download_image(
            #                 yt.thumbnail_url, num, self.outdir
            #             )
            #             self.images.append(image_path)
            #             self.image_filepath = image_path
            #             self.album_image_set = True
            # else:
            #     image_path = Downloader.download_image(yt.thumbnail_url, num, self.outdir)
            #     self.images.append(image_path)
            #     self.image_filepath = image_path

            track_title = None
            track_artist = None

            if metadata is not None:
                t = metadata[num]
                track_title = t.title if not t.unused else self.cur_video.title
                track_artist = t.artist if not t.unused else self.artist
                track_album = self.album
                track_image_path = self.image_filepath
                if t.image_path is not None:
                    if not is_url(t.image_path):
                        track_image_path = t.image_path
                    else:
                        try:
                            track_image_path = Downloader.download_image(
                                t.image_path, num, self.outdir)
                            self.to_delete.append(track_image_path)
                            num = 0  # track num should always be 1 if downloading a single
                        except error.ImageDownloadError as e:
                            image_dl_failed = True
                            failed_image_url = t.image_path
                else:
                    if self.image_filepath is not None:
                        try:
                            track_image_path = Downloader.download_image(
                                self.image_filepath, num, self.outdir)
                            self.to_delete.append(track_image_path)
                            num = 0  # track num should always be 1 if downloading a single
                        except error.ImageDownloadError as e:
                            image_dl_failed = True
                            failed_image_url = self.image_filepath

                if not self.is_album:
                    track_album = t.album

            else:
                track_title = self.cur_video.title
                track_artist = self.artist
                track_album = self.album
                if self.image_filepath is not None:
                    if not is_url(self.image_filepath):
                        track_image_path = self.image_filepath
                    else:
                        try:
                            track_image_path = Downloader.download_image(
                                self.image_filepath, num, self.outdir)
                            self.to_delete.append(track_image_path)
                        except error.ImageDownloadError as e:
                            image_dl_failed = True
                            failed_image_url = self.image_filepath

            metadata_branch = "├──" if self.mp3 else "└──"

            try:
                if image_dl_failed:
                    raise error.ImageDownloadError(failed_image_url)

                self.apply_metadata(
                    num + 1,
                    self.total_songs,
                    path,
                    track_album,
                    track_title,
                    track_artist,
                    track_image_path,
                )
                print(
                    f"{metadata_branch} Applying metadata - {font.apply('bl', '[Done]')}"
                )

            except (Exception, KeyboardInterrupt) as e:
                print(
                    f"{metadata_branch} Applying metadata - {font.apply('bf', '[Failed - ')} {font.apply('bf', str(e) + ']')}"
                )

            if self.mp3:
                ffmpeg = FFmpeg().input(path).output(
                    f"{extract_title(path)}.mp3")

                @ffmpeg.on("progress")
                def mp3_conv_progress(event):
                    p = (to_sec(event.time) / int(yt.length)) * 100
                    progress = (
                        f"└── Converting to mp3 - [{p:.2f}%]" if p < 100 else
                        f"└── Converting to mp3 - {font.apply('bl', '[Done]          ')}"
                    )

                    end = "\n" if p >= 100 else "\r"
                    print(progress, end=end, flush=True)

                try:
                    loop.run_until_complete(ffmpeg.execute())

                    os.remove(f"{extract_title(path)}.mp4")
                    path = f"{extract_title(path)}.mp3"

                except (Exception, KeyboardInterrupt) as e:
                    print(
                        f"└── Converting to mp3 - {font.apply('bf', '[Failed - ')} {font.apply('bf', str(e) + ']')}"
                    )

            print(" ")
        loop.close()
        for image in self.to_delete:
            os.remove(image)
예제 #5
0
from ffmpeg import FFmpeg
import asyncio
import sys

resolution = ""
ffmpeg = FFmpeg()


@ffmpeg.on('progress')
def on_ffmpeg_progress(progress):
    if 'VMAF' in progress._fields:
        print(progress.VMAF)


ffmpeg.input(sys.argv[1])
ffmpeg.input(sys.argv[2])
ffmpeg.output("-", {'filter_complex': 'libvmaf'}, f="null")
loop = asyncio.get_event_loop()
loop.run_until_complete(ffmpeg.execute())
loop.close()
예제 #6
0
from ffmpeg import FFmpeg
import asyncio
import sys

resolution = ""
ffprobe = FFmpeg(executable='ffprobe')


@ffprobe.on('progress')
def on_ffprobe_progress(progress):
    if 'resolution' in progress._fields:
        resolution = progress.resolution.replace("\n", "").replace("\r", "")
        print(resolution)


ffprobe.input(sys.argv[1])
loop = asyncio.get_event_loop()
loop.run_until_complete(ffprobe.execute())
loop.close()