diff --git a/TTS/engine_wrapper.py b/TTS/engine_wrapper.py index 33e9cc8..519ee09 100644 --- a/TTS/engine_wrapper.py +++ b/TTS/engine_wrapper.py @@ -74,7 +74,7 @@ class TTSEngine: def run(self) -> Tuple[int, int]: Path(self.path).mkdir(parents=True, exist_ok=True) - print_step("Saving Text to MP3 files...") + # print_step("Saving Text to MP3 files...") self.add_periods() self.call_tts("title", process_text(self.reddit_object["thread_title"])) @@ -88,11 +88,11 @@ class TTSEngine: else: self.call_tts("postaudio", process_text(self.reddit_object["thread_post"])) elif settings.config["settings"]["storymodemethod"] == 1: - for idx, text in track(enumerate(self.reddit_object["thread_post"]), total=len(self.reddit_object["thread_post"])): + for idx, text in track(enumerate(self.reddit_object["thread_post"]), "🎶 Creating audio from text...", total=len(self.reddit_object["thread_post"])): self.call_tts(f"postaudio-{idx}", process_text(text)) else: - for idx, comment in track(enumerate(self.reddit_object["comments"]), "Saving...", total=len(self.reddit_object["comments"])): + for idx, comment in track(enumerate(self.reddit_object["comments"]), "💾 Saving...", total=len(self.reddit_object["comments"])): # ! Stop creating mp3 files if the length is greater than max length. if self.length > self.max_length and idx > 1: self.length -= self.last_clip_length @@ -105,7 +105,7 @@ class TTSEngine: else: # If the comment is not too long, just call the tts engine self.call_tts(f"{idx}", process_text(comment["comment_body"])) - print_substep("Saved Text to MP3 files successfully.", style="bold green") + print_substep("Created audio from text successfully!", style="bold green") return self.length, idx def split_post(self, text: str, idx): diff --git a/main.py b/main.py index 8c62b24..4d55e67 100755 --- a/main.py +++ b/main.py @@ -5,6 +5,7 @@ from os import name from pathlib import Path from subprocess import Popen from typing import NoReturn +from humanfriendly import format_timespan from prawcore import ResponseException from utils.console import print_substep @@ -50,6 +51,7 @@ def main(POST_ID=None) -> None: redditid = id(reddit_object) length, number_of_comments = save_text_to_mp3(reddit_object) length = math.ceil(length) + print_substep(f"Video will be {format_timespan(length)} long", style="bold blue") get_screenshots_of_reddit_posts(reddit_object, number_of_comments) bg_config = { "video": get_background_config("video"), diff --git a/reddit/subreddit.py b/reddit/subreddit.py index 0700573..efb1a7c 100644 --- a/reddit/subreddit.py +++ b/reddit/subreddit.py @@ -109,9 +109,9 @@ def get_subreddit_threads(POST_ID: str): num_comments = submission.num_comments threadurl = f"https://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") - print_substep(f"Thread has {upvotes} upvotes", style="bold blue") + print_substep(f"Video will be: {submission.title} :thumbsup:", style="bold blue") + print_substep(f"Thread url is: {threadurl} :thumbsup:", style="bold blue") + print_substep(f"Thread has {upvotes} up votes", style="bold blue") print_substep(f"Thread has a upvote ratio of {ratio}%", style="bold blue") print_substep(f"Thread has {num_comments} comments", style="bold blue") if similarity_score: @@ -162,5 +162,5 @@ def get_subreddit_threads(POST_ID: str): } ) - print_substep("Received subreddit threads Successfully.", style="bold green") + print_substep("Received subreddit threads successfully!", style="bold green") return content diff --git a/utils/ffmpeg.py b/utils/ffmpeg.py index 6962d92..eee5e14 100644 --- a/utils/ffmpeg.py +++ b/utils/ffmpeg.py @@ -56,10 +56,10 @@ def get_duration(filename): # print(f"Returning duration {duration} from ffprobe for {filename}...") return duration -def ffmpeg_progress_run(ffmpeg_cmd, length): +def ffmpeg_progress_run(ffmpeg_cmd, length, progress_text='Rendering...'): with Progress() as progress_bar: # pbar = tqdm(total=100, desc="Progress: ", bar_format="{l_bar}{bar}", unit=" %", dynamic_ncols=True, leave=False) - task = progress_bar.add_task("Rendering...", total=100) + task = progress_bar.add_task(progress_text, total=100) def progress_tracker(progress) -> None: new_progress=progress*100 if new_progress >= progress_bar._tasks[task].completed: diff --git a/utils/imagenarator.py b/utils/imagenarator.py index e7392a6..1a4ef42 100644 --- a/utils/imagenarator.py +++ b/utils/imagenarator.py @@ -6,6 +6,7 @@ import json from PIL import Image, ImageDraw, ImageFont from rich.progress import track from TTS.engine_wrapper import process_text +from utils.console import print_substep def load_text_replacements(): text_replacements = {} @@ -94,10 +95,11 @@ def imagemaker(theme, reddit_obj: dict, txtclr, padding=5, transparent=False) -> image.save(f"assets/temp/{id}/png/title.png") - for idx, text in track(enumerate(texts), "Rendering Image", total=len(texts)): + for idx, text in track(enumerate(texts), "💬 Rendering captions...", total=len(texts)): image = Image.new("RGBA", size, theme) text = process_text(text, False) draw_multiple_line_text(image, perform_text_replacements(text), font, txtclr, padding, wrap=30, transparent=transparent) image.save(f"assets/temp/{id}/png/img{idx}.png") + print_substep("Captions rendered successfully!", style="bold green") text_replacements = load_text_replacements() \ No newline at end of file diff --git a/video_creation/background.py b/video_creation/background.py index 83e1de4..e1e93e4 100644 --- a/video_creation/background.py +++ b/video_creation/background.py @@ -142,7 +142,6 @@ def chop_background(background_config: Dict[str, Tuple], video_length: int, redd background_looped_audio_file_path = f"assets/backgrounds/audio/looped-{audio_choice}" background_audio_loops = math.ceil(video_length / audio_file_duration) if background_audio_loops > 1: - print_step(f"Looping background audio {background_audio_loops} times...🔁") background_audio_loop_input = ffmpeg.input( audio_file_path, stream_loop=background_audio_loops @@ -154,11 +153,12 @@ def chop_background(background_config: Dict[str, Tuple], video_length: int, redd vcodec="copy", acodec="copy" ).overwrite_output(), - background_audio_loops*audio_file_duration + background_audio_loops*audio_file_duration, + "🔁 Looping background audio..." ) + print_substep("Background audio looped successfully!", style="bold green") audio_file_path = background_looped_audio_file_path audio_file_duration = audio_file_duration*background_audio_loops - print_step("Finding a spot in the background audio to chop...✂️") start_time_audio, end_time_audio = get_start_and_end_times( video_length, audio_file_duration ) @@ -174,8 +174,10 @@ def chop_background(background_config: Dict[str, Tuple], video_length: int, redd ss=start_time_audio, to=end_time_audio ).overwrite_output(), - end_time_audio-start_time_audio + end_time_audio-start_time_audio, + "✂️ Chopping background audio..." ) + print_substep("Background audio chopped successfully!", style="bold green") video_choice = f"{background_config['video'][2]}-{background_config['video'][1]}" video_file_path = f"assets/backgrounds/video/{video_choice}" @@ -185,7 +187,6 @@ def chop_background(background_config: Dict[str, Tuple], video_length: int, redd background_looped_video_file_path = f"assets/backgrounds/video/looped-{video_choice}" background_video_loops = math.ceil(video_length / video_file_duration) if background_video_loops > 1: - print_step(f"Looping background video {background_video_loops} times...🔁") background_video_loop_input = ffmpeg.input( video_file_path, stream_loop=background_video_loops @@ -197,14 +198,16 @@ def chop_background(background_config: Dict[str, Tuple], video_length: int, redd vcodec="copy", acodec="copy" ).overwrite_output(), - background_video_loops*video_file_duration + background_video_loops*video_file_duration, + "🔁 Looping background video..." ) + print_substep("Background video looped successfully!", style="bold green") video_file_path = background_looped_video_file_path video_file_duration = video_file_duration * background_video_loops # print(f"Calculated duration after looping: {video_file_duration}") # print(f"Actual duration after looping: {get_duration(video_file_path)}") - print_step("Finding a spot in the background video to chop...✂️") + # print_step("Finding a spot in the background video to chop...✂️") start_time_video, end_time_video = get_start_and_end_times( video_length, video_file_duration ) @@ -212,7 +215,8 @@ def chop_background(background_config: Dict[str, Tuple], video_length: int, redd # try: ffmpeg_progress_run( ffmpeg.input(video_file_path, ss=("%0.2f" % start_time_video), t=("%0.2f" % (end_time_video-start_time_video))).output(f"assets/temp/{id}/background.mp4", vcodec="copy", acodec="copy", map="0"), - end_time_video-start_time_video + end_time_video-start_time_video, + "✂️ Chopping background video..." ) # ffmpeg_extract_subclip( # video_file_path, diff --git a/video_creation/final_video.py b/video_creation/final_video.py index 238c412..048bd20 100644 --- a/video_creation/final_video.py +++ b/video_creation/final_video.py @@ -40,7 +40,6 @@ def name_normalize(name: str) -> str: def prepare_background(reddit_id: str, W: int, H: int) -> str: - print_substep('Preparing the background video...') output_path = f"assets/temp/{reddit_id}/background_noaudio.mp4" input_path = f"assets/temp/{reddit_id}/background.mp4" input_duration=get_duration(input_path) @@ -60,7 +59,8 @@ def prepare_background(reddit_id: str, W: int, H: int) -> str: .overwrite_output() ) try: - ffmpeg_progress_run(output, input_duration) + ffmpeg_progress_run(output, input_duration, "🎥 Rendering background video...") + print_substep("Background video rendered successfully!", style="bold green") except ffmpeg.Error as e: print(e.stderr.decode("utf8")) exit(1) @@ -113,8 +113,6 @@ def make_final_video( and settings.config["settings"]["background"]["background_audio_volume"] != 0 ) - print_step("Creating the final video 🎥") - background_clip = ffmpeg.input(prepare_background(reddit_id, W=W, H=H)) # Gather all audio clips @@ -137,18 +135,21 @@ def make_final_video( elif settings.config["settings"]["storymodemethod"] == 1: 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...") + for i in range(number_of_clips + 1) + # for i in track(range(number_of_clips + 1), "🎶 Collecting audio files...") ] audio_clips.insert(0, ffmpeg.input(f"assets/temp/{reddit_id}/mp3/title.mp3")) audio_clips_durations = [ get_duration(f"assets/temp/{reddit_id}/mp3/postaudio-{i}.mp3") - for i in track(range(number_of_clips + 1), "Calculating the audio file durations...") + for i in track(range(number_of_clips + 1), "🎶 Calculating audio file durations...") ] audio_clips_durations.insert( 0, get_duration(f"assets/temp/{reddit_id}/mp3/title.mp3") ) + print_substep("Calculated audio file durations successfully!", style="bold green") + else: audio_clips = [ @@ -169,10 +170,10 @@ def make_final_video( ffmpeg.output( audio_concat, f"assets/temp/{reddit_id}/audio.mp3", **{"b:a": "192k"} ).overwrite_output(), - sum(audio_clips_durations) + sum(audio_clips_durations), + "🎶 Rendering joined audio..." ) - - print_substep(f"Video will be {format_timespan(length)} long", style="bold green") + print_substep("Joined audio rendered successfully!", style="bold green") screenshot_width = int((W * 45) // 100) audio = ffmpeg.input(f"assets/temp/{reddit_id}/audio.mp3") @@ -213,7 +214,8 @@ def make_final_video( ) current_time += audio_clips_durations[0] elif settings.config["settings"]["storymodemethod"] == 1: - for i in track(range(0, number_of_clips + 1), "Collecting the image files..."): + for i in range(0, number_of_clips + 1): + # for i in track(range(0, number_of_clips + 1), "💬 Collecting caption images..."): image_clips.append( ffmpeg.input(f"assets/temp/{reddit_id}/png/img{i}.png")["v"].filter( "scale", screenshot_width, -1 @@ -316,7 +318,8 @@ def make_final_video( fontfile=os.path.join("fonts", "Roboto-Regular.ttf"), ) background_clip = background_clip.filter("scale", W, H) - print_step("Rendering the video 🎥") + + # print_step("Creating the final video 🎥") defaultPath = f"results/{subreddit}" path = defaultPath + f"/{filename}" @@ -337,8 +340,10 @@ def make_final_video( "threads": multiprocessing.cpu_count(), }, ).overwrite_output(), - length + length, + "🎥 Rendering final video..." ) + print_substep("Video rendered successfully!", style="bold green") except ffmpeg.Error as e: print(e.stderr.decode("utf8")) exit(1) @@ -347,7 +352,7 @@ def make_final_video( path = ( path[:251] + ".mp4" ) # Prevent a error by limiting the path length, do not change this. - print_step("Rendering the Only TTS Video 🎥") + # print_step("Rendering the Only TTS Video 🎥") try: ffmpeg_progress_run( ffmpeg.output( @@ -362,7 +367,8 @@ def make_final_video( "threads": multiprocessing.cpu_count(), }, ).overwrite_output(), - length + length, + "🎥 Rending TTS video..." ) except ffmpeg.Error as e: print(e.stderr.decode("utf8")) @@ -375,4 +381,4 @@ def make_final_video( print_substep(f"Removed {cleanups} temporary files 🗑") file_size=os.stat(f"{defaultPath}/{save_filename}").st_size file_size_human_readable=format_size(file_size) - print_step(f"Done! 🎉 The {file_size_human_readable} video is in the results folder 📁") + print_step(f"Done! 🎉 The {file_size_human_readable}, {format_timespan(length)} long, video is in the results folder 📁") diff --git a/video_creation/screenshot_downloader.py b/video_creation/screenshot_downloader.py index cdc8d61..a49c4a4 100644 --- a/video_creation/screenshot_downloader.py +++ b/video_creation/screenshot_downloader.py @@ -31,7 +31,6 @@ def get_screenshots_of_reddit_posts(reddit_object: dict, screenshot_num: int): lang: Final[str] = settings.config["reddit"]["thread"]["post_lang"] storymode: Final[bool] = settings.config["settings"]["storymode"] - print_step("Downloading screenshots of reddit posts...") reddit_id = re.sub(r"[^\w\s-]", "", reddit_object["thread_id"]) # ! Make sure the reddit screenshots folder exists Path(f"assets/temp/{reddit_id}/png").mkdir(parents=True, exist_ok=True) @@ -62,7 +61,7 @@ def get_screenshots_of_reddit_posts(reddit_object: dict, screenshot_num: int): transparent = False if storymode and settings.config["settings"]["storymodemethod"] == 1: # for idx,item in enumerate(reddit_object["thread_post"]): - print_substep("Generating images...") + # print_substep("Generating images...") return imagemaker( theme=bgcolor, reddit_obj=reddit_object, @@ -210,7 +209,7 @@ def get_screenshots_of_reddit_posts(reddit_object: dict, screenshot_num: int): for idx, comment in enumerate( track( reddit_object["comments"][:screenshot_num], - "Downloading screenshots...", + "📸 Downloading screenshots...", ) ): # Stop if we have reached the screenshot_num @@ -263,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")