Merge pull request #2051 from Cyteon/fancy-title-screen
Adds Fancy title screen
This commit is contained in:
11 files changed
+79
-21
No files matched your search
+3
-2
@@ -231,7 +231,8 @@ fabric.properties
|
||||
# Android studio 3.1+ serialized cache file
|
||||
.idea/caches/build_file_checksums.ser
|
||||
|
||||
assets/
|
||||
assets/temp
|
||||
assets/backgrounds
|
||||
/.vscode
|
||||
out
|
||||
.DS_Store
|
||||
@@ -244,4 +245,4 @@ video_creation/data/videos.json
|
||||
video_creation/data/envvars.txt
|
||||
|
||||
config.toml
|
||||
*.exe
|
||||
*.exe
|
||||
@@ -81,7 +81,7 @@ I have tried to simplify the code so anyone can read it and start contributing a
|
||||
|
||||
Please read our [contributing guidelines](CONTRIBUTING.md) for more detailed information.
|
||||
|
||||
### For any questions or support join the [Discord](https://discord.gg/Vkanmh6C8V) server
|
||||
### For any questions or support join the [Discord](https://discord.gg/qfQSx45xCV) server
|
||||
|
||||
## Developers and maintainers.
|
||||
|
||||
@@ -101,6 +101,8 @@ Freebiell (Freebie#3263) - https://github.com/FreebieII
|
||||
|
||||
Aman Raza (electro199#8130) - https://github.com/electro199
|
||||
|
||||
Cyteon (cyteon) - https://github.com/cyteon
|
||||
|
||||
|
||||
## LICENSE
|
||||
[Roboto Fonts](https://fonts.google.com/specimen/Roboto/about) are licensed under [Apache License V2](https://www.apache.org/licenses/LICENSE-2.0)
|
||||
@@ -43,9 +43,11 @@ class StreamlabsPolly:
|
||||
f"Please set the config variable STREAMLABS_POLLY_VOICE to a valid voice. options are: {voices}"
|
||||
)
|
||||
voice = str(settings.config["settings"]["tts"]["streamlabs_polly_voice"]).capitalize()
|
||||
|
||||
body = {"voice": voice, "text": text, "service": "polly"}
|
||||
headers = {"Referer": "https://streamlabs.com/"}
|
||||
response = requests.post(self.url, headers=headers, data=body)
|
||||
|
||||
if not check_ratelimit(response):
|
||||
self.run(text, filepath, random_voice)
|
||||
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 50 KiB |
@@ -81,7 +81,7 @@ def shutdown() -> NoReturn:
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
if sys.version_info.major != 3 or sys.version_info.minor != 10:
|
||||
if sys.version_info.major != 3 or sys.version_info.minor not in [10, 11]:
|
||||
print(
|
||||
"Hey! Congratulations, you've made it so far (which is pretty rare with no Python 3.10). Unfortunately, this program only works on Python 3.10. Please install Python 3.10 and try again."
|
||||
)
|
||||
|
||||
+1
-1
@@ -104,7 +104,7 @@ def get_subreddit_threads(POST_ID: str):
|
||||
upvotes = submission.score
|
||||
ratio = submission.upvote_ratio * 100
|
||||
num_comments = submission.num_comments
|
||||
threadurl = f"https://reddit.com{submission.permalink}"
|
||||
threadurl = f"https://new.reddit.com/{submission.permalink}"
|
||||
|
||||
print_substep(f"Video will be: {submission.title} :thumbsup:", style="bold green")
|
||||
print_substep(f"Thread url is: {threadurl} :thumbsup:", style="bold green")
|
||||
|
||||
@@ -31,6 +31,7 @@ storymode_max_length = { optional = true, default = 1000, example = 1000, explan
|
||||
resolution_w = { optional = false, default = 1080, example = 1440, explantation = "Sets the width in pixels of the final video" }
|
||||
resolution_h = { optional = false, default = 1920, example = 2560, explantation = "Sets the height in pixels of the final video" }
|
||||
zoom = { optional = true, default = 1, example = 1.1, explanation = "Sets the browser zoom level. Useful if you want the text larger.", type = "float", nmin = 0.1, nmax = 2, oob_error = "The text is really difficult to read at a zoom level higher than 2" }
|
||||
channel_name = { optional = true, default = "Reddit Tales", example = "Reddit Stories", explanation = "Sets the channel name for the video" }
|
||||
|
||||
[settings.background]
|
||||
background_video = { optional = true, default = "minecraft", example = "rocket-league", options = ["minecraft", "gta", "rocket-league", "motor-gta", "csgo-surf", "cluster-truck", "minecraft-2","multiversus","fall-guys","steep", ""], explanation = "Sets the background for the video based on game name" }
|
||||
|
||||
@@ -56,25 +56,17 @@ def imagemaker(theme, reddit_obj: dict, txtclr, padding=5, transparent=False) ->
|
||||
"""
|
||||
Render Images for video
|
||||
"""
|
||||
title = process_text(reddit_obj["thread_title"], False)
|
||||
texts = reddit_obj["thread_post"]
|
||||
id = re.sub(r"[^\w\s-]", "", reddit_obj["thread_id"])
|
||||
|
||||
if transparent:
|
||||
font = ImageFont.truetype(os.path.join("fonts", "Roboto-Bold.ttf"), 100)
|
||||
tfont = ImageFont.truetype(os.path.join("fonts", "Roboto-Bold.ttf"), 100)
|
||||
else:
|
||||
tfont = ImageFont.truetype(os.path.join("fonts", "Roboto-Bold.ttf"), 100) # for title
|
||||
font = ImageFont.truetype(os.path.join("fonts", "Roboto-Regular.ttf"), 100)
|
||||
size = (1920, 1080)
|
||||
|
||||
image = Image.new("RGBA", size, theme)
|
||||
|
||||
# for title
|
||||
draw_multiple_line_text(image, title, tfont, txtclr, padding, wrap=30, transparent=transparent)
|
||||
|
||||
image.save(f"assets/temp/{id}/png/title.png")
|
||||
|
||||
for idx, text in track(enumerate(texts), "Rendering Image"):
|
||||
image = Image.new("RGBA", size, theme)
|
||||
text = process_text(text, False)
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
[]
|
||||
@@ -3,14 +3,17 @@ import os
|
||||
import re
|
||||
import tempfile
|
||||
import threading
|
||||
import textwrap
|
||||
import time
|
||||
|
||||
from pathlib import Path
|
||||
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
|
||||
|
||||
@@ -105,6 +108,41 @@ def prepare_background(reddit_id: str, W: int, H: int) -> str:
|
||||
exit(1)
|
||||
return output_path
|
||||
|
||||
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), settings.config["settings"]["channel_name"], 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
|
||||
@@ -201,6 +239,28 @@ def make_final_video(
|
||||
|
||||
image_clips = list()
|
||||
|
||||
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(
|
||||
|
||||
@@ -58,6 +58,7 @@ def get_screenshots_of_reddit_posts(reddit_object: dict, screenshot_num: int):
|
||||
bgcolor = (255, 255, 255, 255)
|
||||
txtcolor = (0, 0, 0)
|
||||
transparent = False
|
||||
|
||||
if storymode and settings.config["settings"]["storymodemethod"] == 1:
|
||||
# for idx,item in enumerate(reddit_object["thread_post"]):
|
||||
print_substep("Generating images...")
|
||||
@@ -73,7 +74,7 @@ def get_screenshots_of_reddit_posts(reddit_object: dict, screenshot_num: int):
|
||||
print_substep("Launching Headless Browser...")
|
||||
|
||||
browser = p.chromium.launch(
|
||||
headless=True
|
||||
headless=False
|
||||
) # headless=False will show the browser for debugging purposes
|
||||
# Device scale factor (or dsf for short) allows us to increase the resolution of the screenshots
|
||||
# When the dsf is 1, the width of the screenshot is 600 pixels
|
||||
@@ -98,9 +99,9 @@ def get_screenshots_of_reddit_posts(reddit_object: dict, screenshot_num: int):
|
||||
page.set_viewport_size(ViewportSize(width=1920, height=1080))
|
||||
page.wait_for_load_state()
|
||||
|
||||
page.locator('[name="username"]').fill(settings.config["reddit"]["creds"]["username"])
|
||||
page.locator('[name="password"]').fill(settings.config["reddit"]["creds"]["password"])
|
||||
page.locator("button[class$='m-full-width']").click()
|
||||
page.locator(f'input[name="username"]').fill(settings.config["reddit"]["creds"]["username"])
|
||||
page.locator(f'input[name="password"]').fill(settings.config["reddit"]["creds"]["password"])
|
||||
page.get_by_role("button", name="Log In").click()
|
||||
page.wait_for_timeout(5000)
|
||||
|
||||
login_error_div = page.locator(".AnimatedForm__errorMessage").first
|
||||
@@ -218,7 +219,7 @@ def get_screenshots_of_reddit_posts(reddit_object: dict, screenshot_num: int):
|
||||
if page.locator('[data-testid="content-gate"]').is_visible():
|
||||
page.locator('[data-testid="content-gate"] button').click()
|
||||
|
||||
page.goto(f'https://reddit.com{comment["comment_url"]}', timeout=0)
|
||||
page.goto(f"https://new.reddit.com/{comment['comment_url']}")
|
||||
|
||||
# translate code
|
||||
|
||||
@@ -261,4 +262,4 @@ def get_screenshots_of_reddit_posts(reddit_object: dict, screenshot_num: int):
|
||||
# close browser instance when we are done using it
|
||||
browser.close()
|
||||
|
||||
print_substep("Screenshots downloaded Successfully.", style="bold green")
|
||||
print_substep("Screenshots downloaded Successfully.", style="bold green")
|
||||
Reference in new issue
Block a user