diff --git a/README.md b/README.md index 7f10287..af01afe 100644 --- a/README.md +++ b/README.md @@ -75,12 +75,10 @@ Please read our [contributing guidelines](CONTRIBUTING.md) for more detailed inf Elebumm (Lewis#6305) - https://github.com/elebumm (Founder) -Jason (JasonLovesDoggo#1904) - https://github.com/JasonLovesDoggo +Jason (JasonLovesDoggo#1904) - https://github.com/JasonLovesDoggo (Maintainer) CallumIO (c.#6837) - https://github.com/CallumIO -HarryDaDev (hrvyy#9677) - https://github.com/ImmaHarry +Verq (Verq#2338) - https://github.com/CordlessCoder LukaHietala (Pix.#0001) - https://github.com/LukaHietala - -Freebiell (Freebie#6429) - https://github.com/FreebieII diff --git a/TTS/aws_polly.py b/TTS/aws_polly.py index bf8ec1e..0ff0d74 100644 --- a/TTS/aws_polly.py +++ b/TTS/aws_polly.py @@ -37,7 +37,7 @@ class AWSPolly: else: if not settings.config["settings"]["tts"]["aws_polly_voice"]: return ValueError( - f"Please set the environment variable AWS_VOICE to a valid voice. options are: {voices}" + f"Please set the TOML variable AWS_VOICE to a valid voice. options are: {voices}" ) voice = str( settings.config["settings"]["tts"]["aws_polly_voice"] diff --git a/TTS/streamlabs_polly.py b/TTS/streamlabs_polly.py index e9e6358..d4ddcb4 100644 --- a/TTS/streamlabs_polly.py +++ b/TTS/streamlabs_polly.py @@ -37,7 +37,7 @@ class StreamlabsPolly: else: if not settings.config["settings"]["tts"]["streamlabs_polly_voice"]: return ValueError( - f"Please set the environment variable STREAMLABS_VOICE to a valid voice. options are: {voices}" + f"Please set the config variable STREAMLABS_VOICE to a valid voice. options are: {voices}" ) voice = str( settings.config["settings"]["tts"]["streamlabs_polly_voice"] diff --git a/main.py b/main.py index 568c17e..cefb74d 100755 --- a/main.py +++ b/main.py @@ -13,7 +13,7 @@ from video_creation.final_video import make_final_video from video_creation.screenshot_downloader import download_screenshots_of_reddit_posts from video_creation.voices import save_text_to_mp3 -VERSION = "2.2.8" +VERSION = "2.2.9" print( """ ██████╗ ███████╗██████╗ ██████╗ ██╗████████╗ ██╗ ██╗██╗██████╗ ███████╗ ██████╗ ███╗ ███╗ █████╗ ██╗ ██╗███████╗██████╗ @@ -36,11 +36,11 @@ def main(POST_ID=None): reddit_object = get_subreddit_threads(POST_ID) length, number_of_comments = save_text_to_mp3(reddit_object) length = math.ceil(length) - bg_config = get_background_config() download_screenshots_of_reddit_posts(reddit_object, number_of_comments) - download_background() - credit = chop_background_video(length) - make_final_video(number_of_comments, length, reddit_object, credit) + bg_config = get_background_config() + download_background(bg_config) + chop_background_video(bg_config, length) + make_final_video(number_of_comments, length, reddit_object, bg_config) def run_many(times): diff --git a/utils/videos.py b/utils/videos.py index 4e36729..51143c3 100755 --- a/utils/videos.py +++ b/utils/videos.py @@ -28,7 +28,7 @@ def check_done( if video["id"] == str(redditobj): if settings.config["reddit"]["thread"]["post_id"]: print_step( - "You already have done this video but since it was declared specifically in the .env file the program will continue" + "You already have done this video but since it was declared specifically in the config file the program will continue" ) return redditobj print_step("Getting new post as the current one has already been done") @@ -48,7 +48,7 @@ def save_data(filename: str, reddit_title: str, reddit_id: str, credit: str): with open("./video_creation/data/videos.json", "r+", encoding="utf-8") as raw_vids: done_vids = json.load(raw_vids) if reddit_id in [video["id"] for video in done_vids]: - return # video already done but was specified to continue anyway in the .env file + return # video already done but was specified to continue anyway in the config file payload = { "id": reddit_id, "time": str(int(time.time())), diff --git a/video_creation/background.py b/video_creation/background.py index 42f6044..d9dc056 100644 --- a/video_creation/background.py +++ b/video_creation/background.py @@ -1,12 +1,13 @@ -import random -from os import listdir from pathlib import Path +import random from random import randrange -from typing import Tuple +from typing import Any, Tuple + from moviepy.editor import VideoFileClip from moviepy.video.io.ffmpeg_tools import ffmpeg_extract_subclip from pytube import YouTube +from pytube.cli import on_progress from utils import settings from utils.console import print_step, print_substep @@ -44,6 +45,20 @@ background_options = { lambda t: ('center', 480 + t) ) } + +def get_start_and_end_times(video_length: int, length_of_clip: int) -> Tuple[int, int]: + """Generates a random interval of time to be used as the background of the video. + + Args: + video_length (int): Length of the video + length_of_clip (int): Length of the video to be used as the background + + Returns: + tuple[int,int]: Start and end time of the randomized interval + """ + random_time = randrange(180, int(length_of_clip) - int(video_length)) + return random_time, random_time + video_length + def get_background_config(): """Fetch the background/s configuration""" try: @@ -59,65 +74,41 @@ def get_background_config(): return background_options[choice] -def get_start_and_end_times(video_length: int, length_of_clip: int) -> Tuple[int, int]: - """Generates a random interval of time to be used as the background of the video. - Args: - video_length (int): Length of the video - length_of_clip (int): Length of the video to be used as the background - - Returns: - tuple[int,int]: Start and end time of the randomized interval - """ - random_time = randrange(180, int(length_of_clip) - int(video_length)) - return random_time, random_time + video_length - - -def download_background(): - """Downloads the backgrounds/s video from YouTube.""" +def download_background(background_config: Tuple[str, str, str, Any]): + """Downloads the background/s video from YouTube.""" Path("./assets/backgrounds/").mkdir(parents=True, exist_ok=True) - background_options = [ # uri , filename , credit - ("https://www.youtube.com/watch?v=n_Dv4JMiwK8", "parkour.mp4", "bbswitzer"), - # ( - # "https://www.youtube.com/watch?v=2X9QGY__0II", - # "rocket_league.mp4", - # "Orbital Gameplay", - # ), - ] # note: make sure the file name doesn't include an - in it - if not len(listdir("./assets/backgrounds")) >= len( - background_options - ): # if there are any background videos not installed - print_step( - "We need to download the backgrounds videos. they are fairly large but it's only done once. 😎" - ) - print_substep("Downloading the backgrounds videos... please be patient 🙏 ") - for uri, filename, credit in background_options: - if Path(f"assets/backgrounds/{credit}-{filename}").is_file(): - continue # adds check to see if file exists before downloading - print_substep(f"Downloading {filename} from {uri}") - YouTube(uri).streams.filter(res="1080p").first().download( - "assets/backgrounds", filename=f"{credit}-{filename}" - ) - - print_substep( - "Background videos downloaded successfully! 🎉", style="bold green" - ) + uri, filename, credit, _ = background_config + if Path(f"assets/backgrounds/{credit}-{filename}").is_file(): + return + print_step( + "We need to download the backgrounds videos. they are fairly large but it's only done once. 😎" + ) + print_substep("Downloading the backgrounds videos... please be patient 🙏 ") + print_substep(f"Downloading {filename} from {uri}") + YouTube(uri, on_progress_callback=on_progress).streams.filter(res="1080p").first().download( + "assets/backgrounds", filename=f"{credit}-{filename}" + ) + print_substep("Background videos downloaded successfully! 🎉", + style="bold green") -def chop_background_video(video_length: int) -> str: +def chop_background_video(background_config: Tuple[str, str, str, Any], video_length: int): """Generates the background footage to be used in the video and writes it to assets/temp/background.mp4 Args: + background_config (Tuple[str, str, str, Any]) : Current background configuration video_length (int): Length of the clip where the background footage is to be taken out of """ + print_step("Finding a spot in the backgrounds video to chop...✂️") - choice = random.choice(listdir("assets/backgrounds")) - credit = choice.split("-")[0] + choice = f"{background_config[2]}-{background_config[1]}" background = VideoFileClip(f"assets/backgrounds/{choice}") - start_time, end_time = get_start_and_end_times(video_length, background.duration) + start_time, end_time = get_start_and_end_times( + video_length, background.duration) try: ffmpeg_extract_subclip( f"assets/backgrounds/{choice}", @@ -131,4 +122,4 @@ def chop_background_video(video_length: int) -> str: new = video.subclip(start_time, end_time) new.write_videofile("assets/temp/background.mp4") print_substep("Background video chopped successfully!", style="bold green") - return credit + return background_config[2] diff --git a/video_creation/final_video.py b/video_creation/final_video.py index c06598e..ebdf4d0 100755 --- a/video_creation/final_video.py +++ b/video_creation/final_video.py @@ -23,6 +23,7 @@ from utils.console import print_step, print_substep from utils.videos import save_data from utils import settings + console = Console() W, H = 1080, 1920 @@ -45,14 +46,13 @@ def name_normalize(name: str) -> str: else: return name - def make_final_video(number_of_clips: int, length: int, reddit_obj: dict, background_config: Tuple[str, str, str, Any]): """Gathers audio clips, gathers all screenshots, stitches them together and saves the final video to assets/temp Args: - number_of_clips (int): Index to end at when going through the screenshots + number_of_clips (int): Index to end at when going through the screenshots' length (int): Length of the video reddit_obj (dict): The reddit object that contains the posts to read. - background_config Tuple[str, str, str, Any]: The background config to use. + background_config (Tuple[str, str, str, Any]): The background config to use. """ print_step("Creating the final video 🎥") VideoFileClip.reW = lambda clip: clip.resize(width=W) @@ -78,7 +78,6 @@ def make_final_video(number_of_clips: int, length: int, reddit_obj: dict, backgr image_clips = [] # Gather all images new_opacity = 1 if opacity is None or float(opacity) >= 1 else float(opacity) - image_clips.insert( 0, ImageClip("assets/temp/png/title.png") @@ -104,7 +103,7 @@ def make_final_video(number_of_clips: int, length: int, reddit_obj: dict, backgr # .resize(width=W - 100) # .set_opacity(float(opacity)), # ) - # else: + # else: story mode stuff img_clip_pos = background_config[3] image_concat = concatenate_videoclips( image_clips).set_position(img_clip_pos)