From 8a10b2bba5c3aa04a2af23d99392d275cc40b0b1 Mon Sep 17 00:00:00 2001 From: Ivan Habunek Date: Fri, 30 Aug 2024 17:44:45 +0200 Subject: [PATCH] wip --- twitchdl/cache.py | 7 +++++-- twitchdl/chat.py | 36 ++++++++++++++++++++++-------------- twitchdl/output.py | 6 +++++- 3 files changed, 32 insertions(+), 17 deletions(-) diff --git a/twitchdl/cache.py b/twitchdl/cache.py index f457f6d..12f270e 100644 --- a/twitchdl/cache.py +++ b/twitchdl/cache.py @@ -19,10 +19,13 @@ def download_cached( filename: Optional[str] = None, subfolder: Optional[str] = None, ) -> Optional[Path]: - base = get_cache_dir() + cache_dir = get_cache_dir() + target_dir = cache_dir / subfolder if subfolder else cache_dir + target_dir.mkdir(parents=True, exist_ok=True) + if not filename: filename = hashlib.sha256(url.encode()).hexdigest() - target = base / subfolder / filename if subfolder else base / filename + target = target_dir / filename if not target.exists(): download_file(url, target) diff --git a/twitchdl/chat.py b/twitchdl/chat.py index ed05ddf..bfbb0de 100644 --- a/twitchdl/chat.py +++ b/twitchdl/chat.py @@ -12,6 +12,7 @@ import math import re import shutil import subprocess +import time from itertools import groupby from pathlib import Path from typing import Dict, Generator, List, Optional, Tuple @@ -22,7 +23,7 @@ from PIL import Image, ImageDraw, ImageFont from twitchdl import cache from twitchdl.entities import Badge, Comment, Emote from twitchdl.exceptions import ConsoleError -from twitchdl.output import clear_line, print_log +from twitchdl.output import clear_line, cursor_previous_line, green, print_log from twitchdl.twitch import get_comments, get_video, get_video_comments from twitchdl.utils import format_time, iterate_with_next, parse_video_identifier @@ -76,7 +77,8 @@ def render_chat(id: str, width: int, height: int, font_size: int, dark: bool): cache_dir.mkdir(parents=True, exist_ok=True) first = True - for offset, duration, comments in group_comments(video_id, total_duration): + start = time.monotonic() + for index, offset, duration, comments in group_comments(video_id, total_duration): if first: # Save the initial empty frame frame_path = cache_dir / f"chat_{0:05d}.bmp" @@ -91,12 +93,7 @@ def render_chat(id: str, width: int, height: int, font_size: int, dark: bool): frame_path = cache_dir / f"chat_{offset:05d}.bmp" screen.image.save(frame_path) frames.append((frame_path, duration)) - - perc = int(100 * offset / total_duration) - print_status( - f"Rendering chat frames {format_time(offset)}/{format_time(total_duration)} ({perc}%)", - transient=True, - ) + _print_progress(index, offset, start, total_duration) spec_path = cache_dir / "concat.txt" with open(spec_path, "w") as f: @@ -113,6 +110,16 @@ def render_chat(id: str, width: int, height: int, font_size: int, dark: bool): shutil.rmtree(cache_dir) +def _print_progress(index: int, offset: int, start: float, total_duration: int): + perc = 100 * offset / total_duration + duration = time.monotonic() - start + print_status( + f"Rendering chat frame {index} at {index / duration:.1f}fps, " + + f"{format_time(offset)}/{format_time(total_duration)} ({perc:.0f}%)", + transient=True, + ) + + def add_frame_to_spec(concat_spec: str, frame_path: Path, duration: int) -> str: concat_spec += f"file '{frame_path.resolve()}'\n" concat_spec += f"duration {duration}\n" @@ -308,7 +315,7 @@ def generate_video(spec_path: Path, output: Path): if result.returncode != 0: raise ConsoleError("Joining files failed") - print_status(f"Saved {output}") + print_status(f"Saved: {green(output)}") def shift(image: Image.Image, dy: int, background: str): @@ -346,11 +353,13 @@ def group_comments(video_id: str, total_duration: int): # Delazify the comments list, without this they are consumed before we get to them g3 = ((offset, list(comments)) for offset, comments in g2) g4 = iterate_with_next(g3) + g5 = enumerate(g4) + # We need to go deeper? ^^; - for (offset, comments), next_pair in g4: + for index, ((offset, comments), next_pair) in g5: next_offset = next_pair[0] if next_pair else total_duration duration = next_offset - offset - yield offset, duration, comments + yield index, offset, duration, comments def generate_comments(video_id: str) -> Generator[Comment, None, None]: @@ -375,9 +384,8 @@ def print_status(message: str, transient: bool = False, dim: bool = False): global _prev_transient if _prev_transient: + cursor_previous_line() clear_line() - else: - click.echo("", err=True) - click.secho(message, nl=False, err=True, dim=dim) + click.secho(message, err=True, dim=dim) _prev_transient = transient diff --git a/twitchdl/output.py b/twitchdl/output.py index e43d1c7..eca6428 100644 --- a/twitchdl/output.py +++ b/twitchdl/output.py @@ -11,8 +11,12 @@ from twitchdl.entities import Clip, Video T = TypeVar("T") +def cursor_previous_line(): + sys.stdout.write("\033[1F") + + def clear_line(): - sys.stdout.write("\033[1K") + sys.stdout.write("\033[2K") sys.stdout.write("\r")