mirror of
https://github.com/ihabunek/twitch-dl
synced 2024-08-30 18:32:25 +00:00
wip
This commit is contained in:
parent
ec985efcd1
commit
8a10b2bba5
@ -19,10 +19,13 @@ def download_cached(
|
|||||||
filename: Optional[str] = None,
|
filename: Optional[str] = None,
|
||||||
subfolder: Optional[str] = None,
|
subfolder: Optional[str] = None,
|
||||||
) -> Optional[Path]:
|
) -> 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:
|
if not filename:
|
||||||
filename = hashlib.sha256(url.encode()).hexdigest()
|
filename = hashlib.sha256(url.encode()).hexdigest()
|
||||||
target = base / subfolder / filename if subfolder else base / filename
|
target = target_dir / filename
|
||||||
|
|
||||||
if not target.exists():
|
if not target.exists():
|
||||||
download_file(url, target)
|
download_file(url, target)
|
||||||
|
@ -12,6 +12,7 @@ import math
|
|||||||
import re
|
import re
|
||||||
import shutil
|
import shutil
|
||||||
import subprocess
|
import subprocess
|
||||||
|
import time
|
||||||
from itertools import groupby
|
from itertools import groupby
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import Dict, Generator, List, Optional, Tuple
|
from typing import Dict, Generator, List, Optional, Tuple
|
||||||
@ -22,7 +23,7 @@ from PIL import Image, ImageDraw, ImageFont
|
|||||||
from twitchdl import cache
|
from twitchdl import cache
|
||||||
from twitchdl.entities import Badge, Comment, Emote
|
from twitchdl.entities import Badge, Comment, Emote
|
||||||
from twitchdl.exceptions import ConsoleError
|
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.twitch import get_comments, get_video, get_video_comments
|
||||||
from twitchdl.utils import format_time, iterate_with_next, parse_video_identifier
|
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)
|
cache_dir.mkdir(parents=True, exist_ok=True)
|
||||||
|
|
||||||
first = 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:
|
if first:
|
||||||
# Save the initial empty frame
|
# Save the initial empty frame
|
||||||
frame_path = cache_dir / f"chat_{0:05d}.bmp"
|
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"
|
frame_path = cache_dir / f"chat_{offset:05d}.bmp"
|
||||||
screen.image.save(frame_path)
|
screen.image.save(frame_path)
|
||||||
frames.append((frame_path, duration))
|
frames.append((frame_path, duration))
|
||||||
|
_print_progress(index, offset, start, total_duration)
|
||||||
perc = int(100 * offset / total_duration)
|
|
||||||
print_status(
|
|
||||||
f"Rendering chat frames {format_time(offset)}/{format_time(total_duration)} ({perc}%)",
|
|
||||||
transient=True,
|
|
||||||
)
|
|
||||||
|
|
||||||
spec_path = cache_dir / "concat.txt"
|
spec_path = cache_dir / "concat.txt"
|
||||||
with open(spec_path, "w") as f:
|
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)
|
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:
|
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"file '{frame_path.resolve()}'\n"
|
||||||
concat_spec += f"duration {duration}\n"
|
concat_spec += f"duration {duration}\n"
|
||||||
@ -308,7 +315,7 @@ def generate_video(spec_path: Path, output: Path):
|
|||||||
if result.returncode != 0:
|
if result.returncode != 0:
|
||||||
raise ConsoleError("Joining files failed")
|
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):
|
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
|
# Delazify the comments list, without this they are consumed before we get to them
|
||||||
g3 = ((offset, list(comments)) for offset, comments in g2)
|
g3 = ((offset, list(comments)) for offset, comments in g2)
|
||||||
g4 = iterate_with_next(g3)
|
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
|
next_offset = next_pair[0] if next_pair else total_duration
|
||||||
duration = next_offset - offset
|
duration = next_offset - offset
|
||||||
yield offset, duration, comments
|
yield index, offset, duration, comments
|
||||||
|
|
||||||
|
|
||||||
def generate_comments(video_id: str) -> Generator[Comment, None, None]:
|
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
|
global _prev_transient
|
||||||
|
|
||||||
if _prev_transient:
|
if _prev_transient:
|
||||||
|
cursor_previous_line()
|
||||||
clear_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
|
_prev_transient = transient
|
||||||
|
@ -11,8 +11,12 @@ from twitchdl.entities import Clip, Video
|
|||||||
T = TypeVar("T")
|
T = TypeVar("T")
|
||||||
|
|
||||||
|
|
||||||
|
def cursor_previous_line():
|
||||||
|
sys.stdout.write("\033[1F")
|
||||||
|
|
||||||
|
|
||||||
def clear_line():
|
def clear_line():
|
||||||
sys.stdout.write("\033[1K")
|
sys.stdout.write("\033[2K")
|
||||||
sys.stdout.write("\r")
|
sys.stdout.write("\r")
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user