diff --git a/requirements.txt b/requirements.txt index 3382509..77a2264 100644 --- a/requirements.txt +++ b/requirements.txt @@ -18,4 +18,5 @@ clean-text==0.6.0 unidecode==1.3.2 spacy==3.4.1 torch==1.12.1 -transformers==4.25.1 \ No newline at end of file +transformers==4.25.1 +ffmpeg-python==0.2.0 \ No newline at end of file diff --git a/video_creation/final_video.py b/video_creation/final_video.py index f220748..f67d4b4 100755 --- a/video_creation/final_video.py +++ b/video_creation/final_video.py @@ -50,16 +50,18 @@ def name_normalize(name: str) -> str: def prepare_background(reddit_id: str, W: int, H: int) -> str: output_path = f"assets/temp/{reddit_id}/background_noaudio.mp4" - output = ffmpeg.input(f"assets/temp/{reddit_id}/background.mp4").filter('crop', "ih*(9/16)", "ih").output(output_path, an=None, **{"c:v": "h264", "b:v": "8M", "b:a": "192k", "threads": multiprocessing.cpu_count()}).overwrite_output() + output = ffmpeg.input(f"assets/temp/{reddit_id}/background.mp4").filter('crop', "ih*(9/16)", "ih").output( + output_path, an=None, + **{"c:v": "h264", "b:v": "20M", "b:a": "192k", "threads": multiprocessing.cpu_count()}).overwrite_output() output.run() return output_path def make_final_video( - number_of_clips: int, - length: int, - reddit_obj: dict, - background_config: Tuple[str, str, str, Any], + 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: @@ -95,16 +97,17 @@ def make_final_video( else: audio_clips = [ffmpeg.input(f"assets/temp/{reddit_id}/mp3/{i}.mp3") for i in range(number_of_clips)] audio_clips.insert(0, ffmpeg.input(f"assets/temp/{reddit_id}/mp3/title.mp3")) - - audio_clips_durations = [float(ffmpeg.probe(f"assets/temp/{reddit_id}/mp3/{i}.mp3")['format']['duration']) for i in range(number_of_clips)] - audio_clips_durations.insert(0, float(ffmpeg.probe(f"assets/temp/{reddit_id}/mp3/title.mp3")['format']['duration'])) + + audio_clips_durations = [float(ffmpeg.probe(f"assets/temp/{reddit_id}/mp3/{i}.mp3")['format']['duration']) for i in + range(number_of_clips)] + audio_clips_durations.insert(0, float(ffmpeg.probe(f"assets/temp/{reddit_id}/mp3/title.mp3")['format']['duration'])) 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() console.log(f"[bold green] Video Will Be: {length} Seconds Long") - # Gather all images - screenshot_width = "iw-800" - + # Create a screenshot_width variable to scale the screenshots to the correct size, the calculation is int((W * 90) // 100) + # Convert it to a ffmpeg one with iw- + screenshot_width = int((W * 45) // 100) audio = ffmpeg.input(f"assets/temp/{reddit_id}/audio.mp3") image_clips = list() @@ -117,31 +120,40 @@ def make_final_video( current_time = 0 if settings.config["settings"]["storymode"]: + audio_clips_durations = [float(ffmpeg.probe(f"assets/temp/{reddit_id}/mp3/postaudio-{i}.mp3")['format']['duration']) for i in + range(number_of_clips)] + audio_clips_durations.insert(0, float(ffmpeg.probe(f"assets/temp/{reddit_id}/mp3/title.mp3")['format']['duration'])) if settings.config["settings"]["storymodemethod"] == 0: image_clips.insert( 1, ffmpeg.input(f"assets/temp/{reddit_id}/png/story_content.png") .filter('scale', screenshot_width, -1) ) - background_clip = background_clip.overlay(image_clips[i], enable=f'between(t,{current_time},{current_time + audio_clips_durations[i]})', x='(main_w-overlay_w)/2', y='(main_h-overlay_h)/2') - current_time += audio_clips_durations[i] + background_clip = background_clip.overlay(image_clips[1], + enable=f'between(t,{current_time},{current_time + audio_clips_durations[i]})', + x='(main_w-overlay_w)/2', y='(main_h-overlay_h)/2') + current_time += audio_clips_durations[1] elif settings.config["settings"]["storymodemethod"] == 1: for i in track( - range(0, number_of_clips + 1), "Collecting the image files..." + 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('scale', screenshot_width, -1) ) - background_clip = background_clip.overlay(image_clips[i], enable=f'between(t,{current_time},{current_time + audio_clips_durations[i]})', x='(main_w-overlay_w)/2', y='(main_h-overlay_h)/2') + background_clip = background_clip.overlay(image_clips[i], + enable=f'between(t,{current_time},{current_time + audio_clips_durations[i]})', + x='(main_w-overlay_w)/2', y='(main_h-overlay_h)/2') current_time += audio_clips_durations[i] else: for i in range(0, number_of_clips + 1): image_clips.append( - ffmpeg.input(f"assets/temp/{reddit_id}/png/comment_{i}.png")['v'] - .filter('scale', screenshot_width, -1) + ffmpeg.input(f"assets/temp/{reddit_id}/png/comment_{i}.png")['v'] + .filter('scale', screenshot_width, -1) ) - background_clip = background_clip.overlay(image_clips[i], enable=f'between(t,{current_time},{current_time + audio_clips_durations[i]})', x='(main_w-overlay_w)/2', y='(main_h-overlay_h)/2') + background_clip = background_clip.overlay(image_clips[i], + enable=f'between(t,{current_time},{current_time + audio_clips_durations[i]})', + x='(main_w-overlay_w)/2', y='(main_h-overlay_h)/2') current_time += audio_clips_durations[i] title = re.sub(r"[^\w\s-]", "", reddit_obj["thread_title"]) @@ -151,7 +163,12 @@ def make_final_video( filename = f"{name_normalize(title)[:251]}" subreddit = settings.config["reddit"]["thread"]["subreddit"] - final = ffmpeg.output(background_clip, audio, f"results/{subreddit}/{filename}.mp4", f='mp4', **{"c:v": "h264", "b:v": "8M", "b:a": "192k", "threads": multiprocessing.cpu_count()}).overwrite_output() + + final = ffmpeg.output(background_clip, audio, f"results/{subreddit}/{filename}.mp4", f='mp4', + **{"c:v": "h264", "b:v": "20M", "b:a": "192k", + "threads": multiprocessing.cpu_count()}).overwrite_output() + + if not exists(f"./results/{subreddit}"): print_substep("The results folder didn't exist so I made it") @@ -190,6 +207,15 @@ def make_final_video( # create a tumbnail for the video settingsbackground = settings.config["settings"]["background"] + + # final = Video(final).add_watermark( + # text=f"Background credit: {background_config[2]}", + # opacity=0.4, + # redditid=reddit_obj, + # ) + # + # from utils.video import Video.Video.add_watermark() + if settingsbackground["background_thumbnail"]: if not exists(f"./results/{subreddit}/thumbnails"): print_substep( @@ -218,11 +244,11 @@ def make_final_video( print_substep(f"Thumbnail - Building Thumbnail in assets/temp/{reddit_id}/thumbnail.png") final.run() - #get the thumbnail image from assets/temp/id/thumbnail.png and save it in results/subreddit/thumbnails + # get the thumbnail image from assets/temp/id/thumbnail.png and save it in results/subreddit/thumbnails if settingsbackground["background_thumbnail"] and exists(f"assets/temp/{reddit_id}/thumbnail.png"): shutil.move(f"assets/temp/{reddit_id}/thumbnail.png", f"./results/{subreddit}/thumbnails/{filename}.png") - save_data(subreddit, filename+".mp4", title, idx, background_config[2]) + save_data(subreddit, filename + ".mp4", title, idx, background_config[2]) print_step("Removing temporary files 🗑") cleanups = cleanup(reddit_id) print_substep(f"Removed {cleanups} temporary files 🗑")