Upgraded title to be fancy, credits to beingbored (tim)

pull/2041/head
Kristian 1 year ago
parent 15247b0b63
commit 33f49a51e1

5
.gitignore vendored

@ -231,7 +231,10 @@ fabric.properties
# Android studio 3.1+ serialized cache file
.idea/caches/build_file_checksums.ser
assets/
assets/backgrounds
assets/temp
/.vscode
out
.DS_Store

Binary file not shown.

After

Width:  |  Height:  |  Size: 50 KiB

@ -10,7 +10,7 @@ rich==13.4.1
toml==0.10.2
translators==5.7.6
pyttsx3==2.90
Pillow==10.2.0
Pillow==9.5.0
tomlkit==0.11.8
Flask==2.3.3
clean-text==0.6.0

@ -4,13 +4,14 @@ import re
import tempfile
import threading
import time
import textwrap
from os.path import exists # Needs to be imported specifically
from typing import Final
from typing import Tuple, Dict
import ffmpeg
import translators
from PIL import Image
from PIL import ImageDraw, ImageFont, Image
from rich.console import Console
from rich.progress import track
@ -20,9 +21,12 @@ from utils.console import print_step, print_substep
from utils.thumbnail import create_thumbnail
from utils.videos import save_data
from pathlib import Path
console = Console()
class ProgressFfmpeg(threading.Thread):
def __init__(self, vid_duration_seconds, progress_update_callback):
threading.Thread.__init__(self, name="ProgressFfmpeg")
@ -99,13 +103,49 @@ def prepare_background(reddit_id: str, W: int, H: int) -> str:
.overwrite_output()
)
try:
output.run(quiet=False)
output.run(quiet=True)
except ffmpeg.Error as e:
print(e.stderr.decode("utf8"))
exit(1)
return output_path
# The following function is based on code under: Copyright 2024 beingbored (aka. Tim), MIT License, permission granted to use, copy, modify, and distribute.
def create_fancy_thumbnail(image, text, text_color, padding, wrap=35):
print_step(f"Creating fancy thumbnail for {text}")
font_title_size = 47
font = ImageFont.truetype(os.path.join("fonts", "Roboto-Bold.ttf"), font_title_size)
image_width, image_height = image.size
lines = textwrap.wrap(text, width=wrap)
y = (image_height / 2) - (((font.getsize(text)[1] + (len(lines) * padding) / len(lines)) * len(lines)) / 2) + 30
draw = ImageDraw.Draw(image)
username_font = ImageFont.truetype(os.path.join("fonts", "Roboto-Bold.ttf"), 30)
draw.text((205, 825), f"Reddit Tales", font=username_font, fill=text_color, align="left")
if len(lines) == 3:
lines = textwrap.wrap(text, width=wrap+10)
font_title_size = 40
font = ImageFont.truetype(os.path.join("fonts", "Roboto-Bold.ttf"), font_title_size)
y = (image_height / 2) - (((font.getsize(text)[1] + (len(lines) * padding) / len(lines)) * len(lines)) / 2) + 35
elif len(lines) == 4:
lines = textwrap.wrap(text, width=wrap+10)
font_title_size = 35
font = ImageFont.truetype(os.path.join("fonts", "Roboto-Bold.ttf"), font_title_size)
y = (image_height / 2) - (((font.getsize(text)[1] + (len(lines) * padding) / len(lines)) * len(lines)) / 2) + 40
elif len(lines) > 4:
lines = textwrap.wrap(text, width=wrap+10)
font_title_size = 30
font = ImageFont.truetype(os.path.join("fonts", "Roboto-Bold.ttf"), font_title_size)
y = (image_height / 2) - (((font.getsize(text)[1] + (len(lines) * padding) / len(lines)) * len(lines)) / 2) + 30
for line in lines:
_, line_height = font.getsize(line)
draw.text((120, y), line, font=font, fill=text_color, align="left")
y += line_height + padding
return image
def merge_background_audio(audio: ffmpeg, reddit_id: str):
"""Gather an audio and merge with assets/backgrounds/background.mp3
Args:
@ -166,9 +206,8 @@ def make_final_video(
if settings.config["settings"]["storymode"]:
if settings.config["settings"]["storymodemethod"] == 0:
audio_clips = [ffmpeg.input(f"assets/temp/{reddit_id}/mp3/title.mp3")]
#audio_clips.insert(1, ffmpeg.input(f"assets/temp/{reddit_id}/mp3/postaudio.mp3"))
audio_clips.insert(1, ffmpeg.input(f"assets/temp/{reddit_id}/mp3/postaudio.mp3"))
elif settings.config["settings"]["storymodemethod"] == 1:
if not settings.config["settings"]["mememode"]:
audio_clips = [
ffmpeg.input(f"assets/temp/{reddit_id}/mp3/postaudio-{i}.mp3")
for i in track(range(number_of_clips + 1), "Collecting the audio files...")
@ -192,7 +231,7 @@ def make_final_video(
audio_concat = ffmpeg.concat(*audio_clips, a=1, v=0)
ffmpeg.output(
audio_concat, f"assets/temp/{reddit_id}/audio.mp3", **{"b:a": "192k"}
).overwrite_output().run(quiet=False)
).overwrite_output().run(quiet=True)
console.log(f"[bold green] Video Will Be: {length} Seconds Long")
@ -202,17 +241,39 @@ def make_final_video(
image_clips = list()
if settings.config["settings"]["storymode"]:
Path(f"assets/temp/{reddit_id}/png").mkdir(parents=True, exist_ok=True)
# Copyright 2024 beingbored (aka. Tim), MIT License, permission granted to use, copy, modify, and distribute.
# get the title_template image and draw a text in the middle part of it with the title of the thread
title_template = Image.open("assets/title_template.png")
title = reddit_obj["thread_title"]
title = name_normalize(title)
font_color = "#000000"
padding = 5
# create_fancy_thumbnail(image, text, text_color, padding
title_img = create_fancy_thumbnail(
title_template, title, font_color, padding
)
title_img.save(f"assets/temp/{reddit_id}/png/title.png")
# Copyright end
image_clips.insert(
0,
ffmpeg.input(f"assets/temp/{reddit_id}/png/title.png")["v"].filter(
"scale", screenshot_width, -1,
"scale", screenshot_width, -1
),
)
current_time = 0
if settings.config["settings"]["storymode"]:
audio_clips_durations = []
if not settings.config["settings"]["mememode"]:
audio_clips_durations = [
float(
ffmpeg.probe(f"assets/temp/{reddit_id}/mp3/postaudio-{i}.mp3")["format"]["duration"]
@ -230,8 +291,6 @@ def make_final_video(
"scale", screenshot_width, -1
),
)
if settings.config["settings"]["mememode"]: audio_clips_durations[0] += 2
background_clip = background_clip.overlay(
image_clips[0],
enable=f"between(t,{current_time},{current_time + audio_clips_durations[0]})",
@ -239,7 +298,7 @@ def make_final_video(
y="(main_h-overlay_h)/2",
)
current_time += audio_clips_durations[0]
elif settings.config["settings"]["storymodemethod"] == 1 and not settings.config["settings"]["mememode"]:
elif settings.config["settings"]["storymodemethod"] == 1:
for i in track(range(0, number_of_clips + 1), "Collecting the image files..."):
image_clips.append(
ffmpeg.input(f"assets/temp/{reddit_id}/png/img{i}.png")["v"].filter(
@ -253,8 +312,6 @@ def make_final_video(
y="(main_h-overlay_h)/2",
)
current_time += audio_clips_durations[i]
elif settings.config["settings"]["mememode"]:
pass
else:
for i in range(0, number_of_clips + 1):
image_clips.append(
@ -361,10 +418,10 @@ def make_final_video(
"threads": multiprocessing.cpu_count(),
},
).overwrite_output().global_args("-progress", progress.output_file.name).run(
quiet=False,
quiet=True,
overwrite_output=True,
capture_stdout=False,
capture_stderr=True,
capture_stderr=False,
)
except ffmpeg.Error as e:
print(e.stderr.decode("utf8"))
@ -391,10 +448,10 @@ def make_final_video(
"threads": multiprocessing.cpu_count(),
},
).overwrite_output().global_args("-progress", progress.output_file.name).run(
quiet=False,
quiet=True,
overwrite_output=True,
capture_stdout=False,
capture_stderr=True,
capture_stderr=False,
)
except ffmpeg.Error as e:
print(e.stderr.decode("utf8"))

@ -1,5 +1,7 @@
import os
import json
import re
from pathlib import Path
from typing import Dict, Final
@ -12,10 +14,10 @@ from utils.console import print_step, print_substep
from utils.imagenarator import imagemaker
from utils.playwright import clear_cookie_by_name
from utils.videos import save_data
from video_creation.final_video import name_normalize
__all__ = ["download_screenshots_of_reddit_posts"]
def get_screenshots_of_reddit_posts(reddit_object: dict, screenshot_num: int):
"""Downloads screenshots of reddit posts as seen on the web. Downloads to assets/temp/png
@ -23,6 +25,9 @@ def get_screenshots_of_reddit_posts(reddit_object: dict, screenshot_num: int):
reddit_object (Dict): Reddit object received from reddit/subreddit.py
screenshot_num (int): Number of screenshots to download
"""
if settings.config["settings"]["storymodemethod"] == 0:
return
# settings values
W: Final[int] = int(settings.config["settings"]["resolution_w"])
H: Final[int] = int(settings.config["settings"]["resolution_h"])
@ -168,42 +173,6 @@ def get_screenshots_of_reddit_posts(reddit_object: dict, screenshot_num: int):
else:
print_substep("Skipping translation...")
postcontentpath = f"assets/temp/{reddit_id}/png/title.png"
try:
if settings.config["settings"]["zoom"] != 1:
# store zoom settings
zoom = settings.config["settings"]["zoom"]
# zoom the body of the page
page.evaluate("document.body.style.zoom=" + str(zoom))
# as zooming the body doesn't change the properties of the divs, we need to adjust for the zoom
location = page.locator('[data-test-id="post-content"]').bounding_box()
for i in location:
location[i] = float("{:.2f}".format(location[i] * zoom))
page.screenshot(clip=location, path=postcontentpath)
else:
page.locator('[data-test-id="post-content"]').screenshot(path=postcontentpath)
except Exception as e:
print_substep("Something went wrong!", style="red")
resp = input(
"Something went wrong with making the screenshots! Do you want to skip the post? (y/n) "
)
if resp.casefold().startswith("y"):
save_data("", "", "skipped", reddit_id, "")
print_substep(
"The post is successfully skipped! You can now restart the program and this post will skipped.",
"green",
)
resp = input("Do you want the error traceback for debugging purposes? (y/n)")
if not resp.casefold().startswith("y"):
exit()
raise e
if storymode and not mememode:
page.locator('[data-click-id="text"]').first.screenshot(
path=f"assets/temp/{reddit_id}/png/story_content.png"

Loading…
Cancel
Save