From 1cc8f40e2c789418049ec5ff35d67ea0f20ce191 Mon Sep 17 00:00:00 2001 From: Simon <65854503+OpenSourceSimon@users.noreply.github.com> Date: Thu, 13 Apr 2023 16:48:58 +0200 Subject: [PATCH 01/38] Fix autoblack --- .github/workflows/autoblack.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/autoblack.yml b/.github/workflows/autoblack.yml index ba9cc36..60bf35c 100644 --- a/.github/workflows/autoblack.yml +++ b/.github/workflows/autoblack.yml @@ -29,4 +29,4 @@ jobs: git remote set-url origin https://x-access-token:${{ secrets.GITHUB_TOKEN }}@github.com/$GITHUB_REPOSITORY git checkout $GITHUB_HEAD_REF git commit -am "fixup: Format Python code with Black" - git push + git push origin HEAD:master From 6c29ad91720291b32fefedff836267e2e7eb58f2 Mon Sep 17 00:00:00 2001 From: "codesee-maps[bot]" <86324825+codesee-maps[bot]@users.noreply.github.com> Date: Thu, 13 Apr 2023 19:58:29 +0000 Subject: [PATCH 02/38] Install the CodeSee workflow. Learn more at https://docs.codesee.io --- .github/workflows/codesee-arch-diagram.yml | 23 ++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 .github/workflows/codesee-arch-diagram.yml diff --git a/.github/workflows/codesee-arch-diagram.yml b/.github/workflows/codesee-arch-diagram.yml new file mode 100644 index 0000000..a72f58b --- /dev/null +++ b/.github/workflows/codesee-arch-diagram.yml @@ -0,0 +1,23 @@ +# This workflow was added by CodeSee. Learn more at https://codesee.io/ +# This is v2.0 of this workflow file +on: + push: + branches: + - master + pull_request_target: + types: [opened, synchronize, reopened] + +name: CodeSee + +permissions: read-all + +jobs: + codesee: + runs-on: ubuntu-latest + continue-on-error: true + name: Analyze the repo with CodeSee + steps: + - uses: Codesee-io/codesee-action@v2 + with: + codesee-token: ${{ secrets.CODESEE_ARCH_DIAG_API_TOKEN }} + codesee-url: https://app.codesee.io From 82731db6f2ae946a1ed4b586308e6039271e95e3 Mon Sep 17 00:00:00 2001 From: liamb Date: Sat, 15 Apr 2023 17:08:48 +1000 Subject: [PATCH 03/38] adds background audio --- utils/.config.template.toml | 4 ++-- video_creation/final_video.py | 8 ++++++++ 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/utils/.config.template.toml b/utils/.config.template.toml index b2fa1d4..30aef5c 100644 --- a/utils/.config.template.toml +++ b/utils/.config.template.toml @@ -34,8 +34,8 @@ resolution_h = { optional = false, default = 1920, example = 2560, explantation [settings.background] background_choice = { 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" } -#background_audio = { optional = true, type = "bool", default = false, example = false, options = [true, false,], explanation = "Sets a audio to play in the background (put a background.mp3 file in the assets/backgrounds directory for it to be used.)" } -#background_audio_volume = { optional = true, type = "float", default = 0.3, example = 0.1, explanation="Sets the volume of the background audio. only used if the background_audio is also set to true" } +background_audio = { optional = true, type = "bool", default = false, example = false, options = [true, false,], explanation = "Sets a audio to play in the background (put a background.mp3 file in the assets/backgrounds directory for it to be used.)" } +background_audio_volume = { optional = true, type = "float", default = 0.3, example = 0.1, explanation="Sets the volume of the background audio. only used if the background_audio is also set to true" } background_thumbnail = { optional = true, type = "bool", default = false, example = false, options = [true, false,], explanation = "Generate a thumbnail for the video (put a thumbnail.png file in the assets/backgrounds directory.)" } background_thumbnail_font_family = { optional = true, default = "arial", example = "arial", explanation = "Font family for the thumbnail text" } background_thumbnail_font_size = { optional = true, type = "int", default = 96, example = 96, explanation = "Font size in pixels for the thumbnail text" } diff --git a/video_creation/final_video.py b/video_creation/final_video.py index 4838574..7ef9c2b 100644 --- a/video_creation/final_video.py +++ b/video_creation/final_video.py @@ -177,6 +177,14 @@ def make_final_video( screenshot_width = int((W * 45) // 100) audio = ffmpeg.input(f"assets/temp/{reddit_id}/audio.mp3") + # adds background audio + if settings.config["settings"]['background']["background_audio"] and exists(f"assets/backgrounds/background.mp3"): + # sets volume to config + bg_audio = ffmpeg.input(f"assets/backgrounds/background.mp3").filter('volume', settings.config["settings"]['background']["background_audio_volume"]) + # merges audio and bg_audio + merged_audio = ffmpeg.filter([audio, bg_audio], 'amix', duration='first') + # sets final audio to merged audio + audio = merged_audio image_clips = list() From 9f79880fb3e55399b06cbe6e5db78901ba59bd5f Mon Sep 17 00:00:00 2001 From: liamb Date: Sat, 15 Apr 2023 17:11:05 +1000 Subject: [PATCH 04/38] sets default voice --- utils/.config.template.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/utils/.config.template.toml b/utils/.config.template.toml index b2fa1d4..ec837a1 100644 --- a/utils/.config.template.toml +++ b/utils/.config.template.toml @@ -42,7 +42,7 @@ background_thumbnail_font_size = { optional = true, type = "int", default = 96, background_thumbnail_font_color = { optional = true, default = "255,255,255", example = "255,255,255", explanation = "Font color in RGB format for the thumbnail text" } [settings.tts] -voice_choice = { optional = false, default = "tiktok", options = ["streamlabspolly", "tiktok", "googletranslate", "awspolly", "pyttsx", ], example = "tiktok", explanation = "The voice platform used for TTS generation. This can be left blank and you will be prompted to choose at runtime." } +voice_choice = { optional = false, default = "streamlabspolly", options = ["streamlabspolly", "tiktok", "googletranslate", "awspolly", "pyttsx", ], example = "tiktok", explanation = "The voice platform used for TTS generation. This can be left blank and you will be prompted to choose at runtime." } aws_polly_voice = { optional = false, default = "Matthew", example = "Matthew", explanation = "The voice used for AWS Polly" } streamlabs_polly_voice = { optional = false, default = "Matthew", example = "Matthew", explanation = "The voice used for Streamlabs Polly" } tiktok_voice = { optional = true, default = "en_us_001", example = "en_us_006", explanation = "The voice used for TikTok TTS" } From 74b0061e67e06ad86af04c0142621840a08b9a09 Mon Sep 17 00:00:00 2001 From: Simon <65854503+OpenSourceSimon@users.noreply.github.com> Date: Sat, 15 Apr 2023 09:14:56 +0200 Subject: [PATCH 05/38] Update .config.template.toml --- utils/.config.template.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/utils/.config.template.toml b/utils/.config.template.toml index b2fa1d4..126b2e1 100644 --- a/utils/.config.template.toml +++ b/utils/.config.template.toml @@ -46,7 +46,7 @@ voice_choice = { optional = false, default = "tiktok", options = ["streamlabspol aws_polly_voice = { optional = false, default = "Matthew", example = "Matthew", explanation = "The voice used for AWS Polly" } streamlabs_polly_voice = { optional = false, default = "Matthew", example = "Matthew", explanation = "The voice used for Streamlabs Polly" } tiktok_voice = { optional = true, default = "en_us_001", example = "en_us_006", explanation = "The voice used for TikTok TTS" } -tiktok_sessionid = { optional = true, example = "c76bcc3a7625abcc27b508c7db457ff1", explanation = "TikTok sessionid needed for the TTS API request. Check documentation if you don't know how to obtain it." } +tiktok_sessionid = { optional = true, example = "c76bcc3a7625abcc27b508c7db457ff1", explanation = "TikTok sessionid needed if you're using the TikTok TTS. Check documentation if you don't know how to obtain it." } python_voice = { optional = false, default = "1", example = "1", explanation = "The index of the system tts voices (can be downloaded externally, run ptt.py to find value, start from zero)" } py_voice_num = { optional = false, default = "2", example = "2", explanation = "The number of system voices (2 are pre-installed in Windows)" } silence_duration = { optional = true, example = "0.1", explanation = "Time in seconds between TTS comments", default = 0.3, type = "float" } From 637e4c66f28da2dec6feec29f16e36774b329962 Mon Sep 17 00:00:00 2001 From: liamb Date: Sat, 15 Apr 2023 17:20:52 +1000 Subject: [PATCH 06/38] adds zoom function --- utils/.config.template.toml | 1 + video_creation/screenshot_downloader.py | 34 ++++++++++++++++++++----- 2 files changed, 29 insertions(+), 6 deletions(-) diff --git a/utils/.config.template.toml b/utils/.config.template.toml index b2fa1d4..e6fa558 100644 --- a/utils/.config.template.toml +++ b/utils/.config.template.toml @@ -31,6 +31,7 @@ storymodemethod= { optional = true, default = 1, example = 1, explanation = "Sty storymode_max_length = { optional = true, default = 1000, example = 1000, explanation = "Max length of the storymode video in characters. 200 characters are approximately 50 seconds.", type = "int", nmin = 1, oob_error = "It's very hard to make a video under a second." } 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" } [settings.background] background_choice = { 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" } diff --git a/video_creation/screenshot_downloader.py b/video_creation/screenshot_downloader.py index 1c3ab5e..ecff2f4 100644 --- a/video_creation/screenshot_downloader.py +++ b/video_creation/screenshot_downloader.py @@ -158,9 +158,20 @@ def get_screenshots_of_reddit_posts(reddit_object: dict, screenshot_num: int): postcontentpath = f"assets/temp/{reddit_id}/png/title.png" try: - page.locator('[data-test-id="post-content"]').screenshot( - path=postcontentpath - ) + 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( @@ -214,9 +225,20 @@ def get_screenshots_of_reddit_posts(reddit_object: dict, screenshot_num: int): [comment_tl, comment["comment_id"]], ) try: - page.locator(f"#t1_{comment['comment_id']}").screenshot( - path=f"assets/temp/{reddit_id}/png/comment_{idx}.png" - ) + 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(f"#t1_{comment['comment_id']}").bounding_box() + for i in location: + location[i] = float("{:.2f}".format(location[i]*zoom)) + page.screenshot(clip=location, path=f"assets/temp/{reddit_id}/png/comment_{idx}.png") + else: + page.locator(f"#t1_{comment['comment_id']}").screenshot( + path=f"assets/temp/{reddit_id}/png/comment_{idx}.png" + ) except TimeoutError: del reddit_object["comments"] screenshot_num += 1 From 5c517a50271efcf32069c44ba6003f7f9641e015 Mon Sep 17 00:00:00 2001 From: Simon Date: Sun, 16 Apr 2023 14:32:51 +0200 Subject: [PATCH 07/38] Reformat --- video_creation/final_video.py | 35 ++++++++++++++++++++++++++++------- 1 file changed, 28 insertions(+), 7 deletions(-) diff --git a/video_creation/final_video.py b/video_creation/final_video.py index 7ef9c2b..fc19f4e 100644 --- a/video_creation/final_video.py +++ b/video_creation/final_video.py @@ -178,13 +178,34 @@ def make_final_video( screenshot_width = int((W * 45) // 100) audio = ffmpeg.input(f"assets/temp/{reddit_id}/audio.mp3") # adds background audio - if settings.config["settings"]['background']["background_audio"] and exists(f"assets/backgrounds/background.mp3"): - # sets volume to config - bg_audio = ffmpeg.input(f"assets/backgrounds/background.mp3").filter('volume', settings.config["settings"]['background']["background_audio_volume"]) - # merges audio and bg_audio - merged_audio = ffmpeg.filter([audio, bg_audio], 'amix', duration='first') - # sets final audio to merged audio - audio = merged_audio + if settings.config["settings"]["background"]["background_audio"]: + if not exists("assets/backgrounds/background.mp3"): + print_substep( + "No audio file found called background.mp3 in assets/backgrounds", "red" + ) + else: + if ( + not settings.config["settings"]["background"]["background_audio_volume"] + or settings.config["settings"]["background"]["background_audio_volume"] == 0 + or settings.config["settings"]["background"]["background_audio_volume"] == "" + ): + print_substep( + "Background audio volume is set to 0, not adding background audio", + "red", + ) + else: + # sets volume to config + bg_audio = ( + ffmpeg.input("assets/backgrounds/background.mp3") + .filter( + "volume", + settings.config["settings"]["background"]["background_audio_volume"], + ) + ) + # merges audio and bg_audio + merged_audio = ffmpeg.filter([audio, bg_audio], "amix", duration="longest") + # sets final audio to merged audio + audio = merged_audio image_clips = list() From 3515afe7f18aa595dce3476b67e262e3ee789e3f Mon Sep 17 00:00:00 2001 From: Simon Date: Sun, 16 Apr 2023 14:42:22 +0200 Subject: [PATCH 08/38] Display ffmpeg error if any --- main.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/main.py b/main.py index b7a1b7f..d2273c6 100755 --- a/main.py +++ b/main.py @@ -6,6 +6,7 @@ from os import name from pathlib import Path from subprocess import Popen +import ffmpeg from prawcore import ResponseException from utils.console import print_substep from reddit.subreddit import get_subreddit_threads @@ -53,7 +54,11 @@ def main(POST_ID=None) -> None: bg_config = get_background_config() download_background(bg_config) chop_background_video(bg_config, length, reddit_object) - make_final_video(number_of_comments, length, reddit_object, bg_config) + try: + make_final_video(number_of_comments, length, reddit_object, bg_config) + except ffmpeg.Error as e: + print(e.stderr.decode("utf8")) + exit(1) def run_many(times) -> None: From 9bacf100dfcc6e3b3ede4e7013d6e329e29fc713 Mon Sep 17 00:00:00 2001 From: Xpl0itU <24777100+Xpl0itU@users.noreply.github.com> Date: Sun, 16 Apr 2023 15:28:28 +0200 Subject: [PATCH 09/38] Use yt-dlp for downloading the background videos --- requirements.txt | 4 ++-- video_creation/background.py | 14 +++++++++----- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/requirements.txt b/requirements.txt index 22d3d7f..823493e 100644 --- a/requirements.txt +++ b/requirements.txt @@ -5,7 +5,6 @@ moviepy==1.0.3 playwright==1.23.0 praw==7.6.1 prawcore~=2.3.0 -pytube==12.1.0 requests==2.28.1 rich==13.3.1 toml==0.10.2 @@ -19,4 +18,5 @@ unidecode==1.3.2 spacy==3.4.1 torch==1.12.1 transformers==4.25.1 -ffmpeg-python==0.2.0 \ No newline at end of file +ffmpeg-python==0.2.0 +yt-dlp==2023.3.4 \ No newline at end of file diff --git a/video_creation/background.py b/video_creation/background.py index 0458ce6..14c9623 100644 --- a/video_creation/background.py +++ b/video_creation/background.py @@ -7,10 +7,9 @@ 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 +import yt_dlp # Load background videos with open("./utils/backgrounds.json") as json_file: @@ -72,9 +71,14 @@ def download_background(background_config: Tuple[str, str, str, Any]): ) 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}") + ydl_opts = { + 'format': "bestvideo[height<=1080][ext=mp4]", + "outtmpl": f"assets/backgrounds/{credit}-{filename}", + "retries": 10, + } + + with yt_dlp.YoutubeDL(ydl_opts) as ydl: + ydl.download(uri) print_substep("Background video downloaded successfully! 🎉", style="bold green") From 40e42b1307d02623a8d241d782e59993a91109a2 Mon Sep 17 00:00:00 2001 From: Simon Date: Sun, 16 Apr 2023 15:45:07 +0200 Subject: [PATCH 10/38] Fix font size --- utils/imagenarator.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/utils/imagenarator.py b/utils/imagenarator.py index a3883b6..847073c 100644 --- a/utils/imagenarator.py +++ b/utils/imagenarator.py @@ -68,9 +68,9 @@ def imagemaker(theme, reddit_obj: dict, txtclr, padding=5, transparent=False) -> tfont = ImageFont.truetype(os.path.join("fonts", "Roboto-Bold.ttf"), 50) else: tfont = ImageFont.truetype( - os.path.join("fonts", "Roboto-Bold.ttf"), 35 + os.path.join("fonts", "Roboto-Bold.ttf"), 100 ) # for title - font = ImageFont.truetype(os.path.join("fonts", "Roboto-Regular.ttf"), 30) + font = ImageFont.truetype(os.path.join("fonts", "Roboto-Regular.ttf"), 90) size = (1920, 1080) image = Image.new("RGBA", size, theme) From fb039735437455c3aade22a29b475fd2cada4fe9 Mon Sep 17 00:00:00 2001 From: Xpl0itU <24777100+Xpl0itU@users.noreply.github.com> Date: Sun, 16 Apr 2023 16:03:07 +0200 Subject: [PATCH 11/38] Add random background choice --- utils/.config.template.toml | 2 +- video_creation/background.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/utils/.config.template.toml b/utils/.config.template.toml index 0eaeb26..387eeb6 100644 --- a/utils/.config.template.toml +++ b/utils/.config.template.toml @@ -33,7 +33,7 @@ resolution_w = { optional = false, default = 1080, example = 1440, explantation resolution_h = { optional = false, default = 1920, example = 2560, explantation = "Sets the height in pixels of the final video" } [settings.background] -background_choice = { 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" } +background_choice = { optional = true, default = "minecraft", example = "rocket-league", options = ["minecraft", "gta", "rocket-league", "motor-gta", "csgo-surf", "cluster-truck", "minecraft-2","multiversus","fall-guys","steep", "random", ""], explanation = "Sets the background for the video based on game name" } background_audio = { optional = true, type = "bool", default = false, example = false, options = [true, false,], explanation = "Sets a audio to play in the background (put a background.mp3 file in the assets/backgrounds directory for it to be used.)" } background_audio_volume = { optional = true, type = "float", default = 0.3, example = 0.1, explanation="Sets the volume of the background audio. only used if the background_audio is also set to true" } background_thumbnail = { optional = true, type = "bool", default = false, example = false, options = [true, false,], explanation = "Generate a thumbnail for the video (put a thumbnail.png file in the assets/backgrounds directory.)" } diff --git a/video_creation/background.py b/video_creation/background.py index 14c9623..87f725a 100644 --- a/video_creation/background.py +++ b/video_creation/background.py @@ -53,7 +53,7 @@ def get_background_config(): # Handle default / not supported background using default option. # Default : pick random from supported background. - if not choice or choice not in background_options: + if not choice or choice not in background_options or choice == "random": choice = random.choice(list(background_options.keys())) return background_options[choice] From ba5e8b89877f93df22029cb5d0523a7025cb8d1a Mon Sep 17 00:00:00 2001 From: Lucas Date: Fri, 21 Apr 2023 14:31:13 -0300 Subject: [PATCH 12/38] adaptations in filePath and toml for audio option --- main.py | 4 +- utils/background_audios.json | 8 +++ ...ackgrounds.json => background_videos.json} | 0 video_creation/background.py | 49 ++++++++++++------- 4 files changed, 43 insertions(+), 18 deletions(-) create mode 100644 utils/background_audios.json rename utils/{backgrounds.json => background_videos.json} (100%) diff --git a/main.py b/main.py index b7a1b7f..9ccd1ed 100755 --- a/main.py +++ b/main.py @@ -49,8 +49,10 @@ def main(POST_ID=None) -> None: redditid = id(reddit_object) length, number_of_comments = save_text_to_mp3(reddit_object) length = math.ceil(length) + bg_config = {} get_screenshots_of_reddit_posts(reddit_object, number_of_comments) - bg_config = get_background_config() + bg_config["video"] = get_background_config("video") + bg_config["audio"] = get_background_config("audio") download_background(bg_config) chop_background_video(bg_config, length, reddit_object) make_final_video(number_of_comments, length, reddit_object, bg_config) diff --git a/utils/background_audios.json b/utils/background_audios.json new file mode 100644 index 0000000..5e37445 --- /dev/null +++ b/utils/background_audios.json @@ -0,0 +1,8 @@ +{ + "__comment": "Supported Backgrounds Audio. Can add/remove background audio here...", + "minecraft": [ + "https://www.youtube.com/watch?v=2p3nBYUaJz8", + "minecraft.mp4", + "adriPixs" + ] +} diff --git a/utils/backgrounds.json b/utils/background_videos.json similarity index 100% rename from utils/backgrounds.json rename to utils/background_videos.json diff --git a/video_creation/background.py b/video_creation/background.py index 0458ce6..f6db6fc 100644 --- a/video_creation/background.py +++ b/video_creation/background.py @@ -5,27 +5,37 @@ from pathlib import Path from random import randrange from typing import Any, Tuple -from moviepy.editor import VideoFileClip +from moviepy.editor import VideoFileClip,AudioFileClip 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 -# Load background videos -with open("./utils/backgrounds.json") as json_file: - background_options = json.load(json_file) +def load_background_options(): + background_options = {} + # Load background videos + with open("./utils/background_videos.json") as json_file: + background_options["video"] = json.load(json_file) -# Remove "__comment" from backgrounds -background_options.pop("__comment", None) + # Load background audios + with open("./utils/background_audios.json") as json_file: + background_options["audio"] = json.load(json_file) + + # Remove "__comment" from backgrounds + background_options["video"].pop("__comment", None) + background_options["audio"].pop("__comment", None) + + # Add position lambda function + # (https://zulko.github.io/moviepy/ref/VideoClip/VideoClip.html#moviepy.video.VideoClip.VideoClip.set_position) + for name in list(background_options["video"].keys()): + pos = background_options["video"][name][3] -# Add position lambda function -# (https://zulko.github.io/moviepy/ref/VideoClip/VideoClip.html#moviepy.video.VideoClip.VideoClip.set_position) -for name in list(background_options.keys()): - pos = background_options[name][3] + if pos != "center": + background_options["video"][name][3] = lambda t: ("center", pos + t) + + return background_options - if pos != "center": - background_options[name][3] = lambda t: ("center", pos + t) def get_start_and_end_times(video_length: int, length_of_clip: int) -> Tuple[int, int]: @@ -42,11 +52,11 @@ def get_start_and_end_times(video_length: int, length_of_clip: int) -> Tuple[int return random_time, random_time + video_length -def get_background_config(): +def get_background_config(mode: str): """Fetch the background/s configuration""" try: choice = str( - settings.config["settings"]["background"]["background_choice"] + settings.config["settings"]["background"][f"background_{mode}_choice"] ).casefold() except AttributeError: print_substep("No background selected. Picking random background'") @@ -54,10 +64,10 @@ def get_background_config(): # Handle default / not supported background using default option. # Default : pick random from supported background. - if not choice or choice not in background_options: - choice = random.choice(list(background_options.keys())) + if not choice or choice not in background_options[mode]: + choice = random.choice(list(background_options[mode].keys())) - return background_options[choice] + return background_options[mode][choice] def download_background(background_config: Tuple[str, str, str, Any]): @@ -78,6 +88,8 @@ def download_background(background_config: Tuple[str, str, str, Any]): print_substep("Background video downloaded successfully! 🎉", style="bold green") + + def chop_background_video( background_config: Tuple[str, str, str, Any], video_length: int, reddit_object: dict ): @@ -108,3 +120,6 @@ def chop_background_video( new.write_videofile(f"assets/temp/{id}/background.mp4") print_substep("Background video chopped successfully!", style="bold green") return background_config[2] + +# Create a tuple for downloads background (background_audio_options, background_video_options) +background_options = load_background_options() \ No newline at end of file From a21c17ef557f43cd6bc7b37a629fabb81a05f1cc Mon Sep 17 00:00:00 2001 From: Lucas Date: Fri, 21 Apr 2023 19:17:05 -0300 Subject: [PATCH 13/38] composing the video but with no audio --- main.py | 10 +++--- utils/.config.template.toml | 6 ++-- utils/background_audios.json | 2 +- video_creation/background.py | 54 +++++++++++++++++++++------------ video_creation/data/videos.json | 19 +++++++++++- 5 files changed, 63 insertions(+), 28 deletions(-) diff --git a/main.py b/main.py index 9ccd1ed..81fb503 100755 --- a/main.py +++ b/main.py @@ -15,8 +15,9 @@ from utils.console import print_markdown, print_step from utils.id import id from utils.version import checkversion from video_creation.background import ( - download_background, - chop_background_video, + download_background_video, + download_background_audio, + chop_background, get_background_config, ) from video_creation.final_video import make_final_video @@ -53,8 +54,9 @@ def main(POST_ID=None) -> None: get_screenshots_of_reddit_posts(reddit_object, number_of_comments) bg_config["video"] = get_background_config("video") bg_config["audio"] = get_background_config("audio") - download_background(bg_config) - chop_background_video(bg_config, length, reddit_object) + download_background_video(bg_config["video"]) + download_background_audio(bg_config["audio"]) + chop_background(bg_config, length, reddit_object) make_final_video(number_of_comments, length, reddit_object, bg_config) diff --git a/utils/.config.template.toml b/utils/.config.template.toml index b2fa1d4..b146922 100644 --- a/utils/.config.template.toml +++ b/utils/.config.template.toml @@ -33,9 +33,9 @@ resolution_w = { optional = false, default = 1080, example = 1440, explantation resolution_h = { optional = false, default = 1920, example = 2560, explantation = "Sets the height in pixels of the final video" } [settings.background] -background_choice = { 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" } -#background_audio = { optional = true, type = "bool", default = false, example = false, options = [true, false,], explanation = "Sets a audio to play in the background (put a background.mp3 file in the assets/backgrounds directory for it to be used.)" } -#background_audio_volume = { optional = true, type = "float", default = 0.3, example = 0.1, explanation="Sets the volume of the background audio. only used if the background_audio is also set to true" } +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" } +background_audio = { optional = true, type = "bool", default = false, example = false, options = [true, false,], explanation = "Sets a audio to play in the background (put a background.mp3 file in the assets/backgrounds directory for it to be used.)" } +background_audio_volume = { optional = true, type = "float", default = 0.3, example = 0.1, explanation="Sets the volume of the background audio. only used if the background_audio is also set to true" } background_thumbnail = { optional = true, type = "bool", default = false, example = false, options = [true, false,], explanation = "Generate a thumbnail for the video (put a thumbnail.png file in the assets/backgrounds directory.)" } background_thumbnail_font_family = { optional = true, default = "arial", example = "arial", explanation = "Font family for the thumbnail text" } background_thumbnail_font_size = { optional = true, type = "int", default = 96, example = 96, explanation = "Font size in pixels for the thumbnail text" } diff --git a/utils/background_audios.json b/utils/background_audios.json index 5e37445..bd34cef 100644 --- a/utils/background_audios.json +++ b/utils/background_audios.json @@ -2,7 +2,7 @@ "__comment": "Supported Backgrounds Audio. Can add/remove background audio here...", "minecraft": [ "https://www.youtube.com/watch?v=2p3nBYUaJz8", - "minecraft.mp4", + "minecraft.mp3", "adriPixs" ] } diff --git a/video_creation/background.py b/video_creation/background.py index f6db6fc..75a88d2 100644 --- a/video_creation/background.py +++ b/video_creation/background.py @@ -3,7 +3,7 @@ import random import re from pathlib import Path from random import randrange -from typing import Any, Tuple +from typing import Any, Tuple,Dict from moviepy.editor import VideoFileClip,AudioFileClip from moviepy.video.io.ffmpeg_tools import ffmpeg_extract_subclip @@ -56,7 +56,7 @@ def get_background_config(mode: str): """Fetch the background/s configuration""" try: choice = str( - settings.config["settings"]["background"][f"background_{mode}_choice"] + settings.config["settings"]["background"][f"background_{mode}"] ).casefold() except AttributeError: print_substep("No background selected. Picking random background'") @@ -69,13 +69,12 @@ def get_background_config(mode: str): return background_options[mode][choice] - -def download_background(background_config: Tuple[str, str, str, Any]): +def download_background_video(background_config: Tuple[str, str, str, Any]): """Downloads the background/s video from YouTube.""" - Path("./assets/backgrounds/").mkdir(parents=True, exist_ok=True) + Path("./assets/backgrounds/video/").mkdir(parents=True, exist_ok=True) # note: make sure the file name doesn't include an - in it uri, filename, credit, _ = background_config - if Path(f"assets/backgrounds/{credit}-{filename}").is_file(): + if Path(f"assets/backgrounds/video/{credit}-{filename}").is_file(): return print_step( "We need to download the backgrounds videos. they are fairly large but it's only done once. 😎" @@ -84,14 +83,26 @@ def download_background(background_config: Tuple[str, str, str, Any]): 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}") + ).first().download("assets/backgrounds/video", filename=f"{credit}-{filename}") print_substep("Background video downloaded successfully! 🎉", style="bold green") +def download_background_audio(background_config: Tuple[str, str, str]): + """Downloads the background/s audio from YouTube.""" + Path("./assets/backgrounds/audio/").mkdir(parents=True, exist_ok=True) + # note: make sure the file name doesn't include an - in it + uri, filename, credit = background_config + if Path(f"assets/backgrounds/audio/{credit}-{filename}").is_file(): + return + print_step( + "We need to download the backgrounds audio. they are fairly large but it's only done once. 😎" + ) + print_substep("Downloading the backgrounds audio... please be patient 🙏 ") + print_substep(f"Downloading {filename} from {uri}") + YouTube(uri, on_progress_callback=on_progress).streams.filter(only_audio=True).first().download("assets/backgrounds/audio", filename=f"{credit}-{filename}") + print_substep("Background audio downloaded successfully! 🎉", style="bold green") - - -def chop_background_video( - background_config: Tuple[str, str, str, Any], video_length: int, reddit_object: dict +def chop_background( + background_config: Dict[str,Tuple[str, str, str, Any]], video_length: int, reddit_object: dict ): """Generates the background footage to be used in the video and writes it to assets/temp/background.mp4 @@ -101,22 +112,27 @@ def chop_background_video( """ print_step("Finding a spot in the backgrounds video to chop...✂️") - choice = f"{background_config[2]}-{background_config[1]}" + video_choice = f"{background_config['video'][2]}-{background_config['video'][1]}" + audio_choice = f"{background_config['audio'][2]}-{background_config['audio'][1]}" id = re.sub(r"[^\w\s-]", "", reddit_object["thread_id"]) - background = VideoFileClip(f"assets/backgrounds/{choice}") + background_video = VideoFileClip(f"assets/backgrounds/video/{video_choice}") + background_audio = AudioFileClip(f"assets/backgrounds/audio/{audio_choice}") + start_time_video, end_time_video = get_start_and_end_times(video_length, background_video.duration) + start_time_audio, end_time_audio = get_start_and_end_times(video_length, background_audio.duration) + background_audio.subclip(start_time_audio,end_time_audio) + background_video.set_audio(background_audio) - start_time, end_time = get_start_and_end_times(video_length, background.duration) try: ffmpeg_extract_subclip( - f"assets/backgrounds/{choice}", - start_time, - end_time, + f"assets/backgrounds/video/{video_choice}", + start_time_video, + end_time_video, targetname=f"assets/temp/{id}/background.mp4", ) except (OSError, IOError): # ffmpeg issue see #348 print_substep("FFMPEG issue. Trying again...") - with VideoFileClip(f"assets/backgrounds/{choice}") as video: - new = video.subclip(start_time, end_time) + with VideoFileClip(f"assets/backgrounds/video/{video_choice}") as video: + new = video.subclip(start_time_video, end_time_video) new.write_videofile(f"assets/temp/{id}/background.mp4") print_substep("Background video chopped successfully!", style="bold green") return background_config[2] diff --git a/video_creation/data/videos.json b/video_creation/data/videos.json index fe51488..4e0cb8c 100644 --- a/video_creation/data/videos.json +++ b/video_creation/data/videos.json @@ -1 +1,18 @@ -[] +[ + { + "subreddit": "", + "id": "12tt2xe", + "time": "1682111299", + "background_credit": "", + "reddit_title": "skipped", + "filename": "" + }, + { + "subreddit": "", + "id": "12u9m3f", + "time": "1682114905", + "background_credit": "", + "reddit_title": "skipped", + "filename": "" + } +] \ No newline at end of file From 405b1f89eb1ad31a14459aae83c5172d5cacd1b6 Mon Sep 17 00:00:00 2001 From: Lucas Date: Fri, 21 Apr 2023 21:28:56 -0300 Subject: [PATCH 14/38] Volume down done --- video_creation/background.py | 17 +++++++++--- video_creation/data/videos.json | 48 +++++++++++++++++++++++++++++++++ video_creation/final_video.py | 8 +++--- 3 files changed, 66 insertions(+), 7 deletions(-) diff --git a/video_creation/background.py b/video_creation/background.py index 75a88d2..55b5399 100644 --- a/video_creation/background.py +++ b/video_creation/background.py @@ -5,7 +5,7 @@ from pathlib import Path from random import randrange from typing import Any, Tuple,Dict -from moviepy.editor import VideoFileClip,AudioFileClip +from moviepy.editor import VideoFileClip,AudioFileClip,afx from moviepy.video.io.ffmpeg_tools import ffmpeg_extract_subclip from pytube import YouTube from pytube.cli import on_progress @@ -115,13 +115,24 @@ def chop_background( video_choice = f"{background_config['video'][2]}-{background_config['video'][1]}" audio_choice = f"{background_config['audio'][2]}-{background_config['audio'][1]}" id = re.sub(r"[^\w\s-]", "", reddit_object["thread_id"]) + + # audioclip = audioclip.fx( volumex, 0.2) + # final_audio = mpe.CompositeAudioClip([final.audio, audioclip]) + # # lowered_audio = audio_background.multiply_volume( # todo get this to work + # # VOLUME_MULTIPLIER) # lower volume by background_audio_volume, use with fx + # final.set_audio(final_audio) background_video = VideoFileClip(f"assets/backgrounds/video/{video_choice}") background_audio = AudioFileClip(f"assets/backgrounds/audio/{audio_choice}") start_time_video, end_time_video = get_start_and_end_times(video_length, background_video.duration) start_time_audio, end_time_audio = get_start_and_end_times(video_length, background_audio.duration) - background_audio.subclip(start_time_audio,end_time_audio) + #background_audio.set_start(start_time_audio) + #background_audio.set_end(end_time_audio) + background_audio = background_audio.fx(afx.volumex,0.1) + #background_audio = background_audio.subclip(start_time_audio,end_time_audio) + background_audio.write_audiofile(f"assets/temp/{id}/background.mp3") background_video.set_audio(background_audio) + try: ffmpeg_extract_subclip( f"assets/backgrounds/video/{video_choice}", @@ -135,7 +146,7 @@ def chop_background( new = video.subclip(start_time_video, end_time_video) new.write_videofile(f"assets/temp/{id}/background.mp4") print_substep("Background video chopped successfully!", style="bold green") - return background_config[2] + return background_config["video"][2] # Create a tuple for downloads background (background_audio_options, background_video_options) background_options = load_background_options() \ No newline at end of file diff --git a/video_creation/data/videos.json b/video_creation/data/videos.json index 4e0cb8c..a7eb3b8 100644 --- a/video_creation/data/videos.json +++ b/video_creation/data/videos.json @@ -14,5 +14,53 @@ "background_credit": "", "reddit_title": "skipped", "filename": "" + }, + { + "subreddit": "", + "id": "12u5j7a", + "time": "1682116292", + "background_credit": "", + "reddit_title": "skipped", + "filename": "" + }, + { + "subreddit": "", + "id": "12twuvx", + "time": "1682118162", + "background_credit": "", + "reddit_title": "skipped", + "filename": "" + }, + { + "subreddit": "", + "id": "12tir3d", + "time": "1682121760", + "background_credit": "", + "reddit_title": "skipped", + "filename": "" + }, + { + "subreddit": "", + "id": "12u60fn", + "time": "1682122061", + "background_credit": "", + "reddit_title": "skipped", + "filename": "" + }, + { + "subreddit": "", + "id": "12txuo4", + "time": "1682123020", + "background_credit": "", + "reddit_title": "skipped", + "filename": "" + }, + { + "subreddit": "AskReddit", + "id": "12uei9x", + "time": "1682123178", + "background_credit": "bbswitzer", + "reddit_title": "People who pick up trash on the sides of roads what is the coolest grossestmost interesting thing youve found", + "filename": "People who pick up trash on the sides of roads what is the coolest grossestmost interesting thing youve found.mp4" } ] \ No newline at end of file diff --git a/video_creation/final_video.py b/video_creation/final_video.py index 4838574..5e42e12 100644 --- a/video_creation/final_video.py +++ b/video_creation/final_video.py @@ -4,7 +4,7 @@ import re import shutil from os.path import exists # Needs to be imported specifically from typing import Final -from typing import Tuple, Any +from typing import Tuple, Any, Dict import ffmpeg import translators as ts @@ -108,7 +108,7 @@ def make_final_video( number_of_clips: int, length: int, reddit_obj: dict, - background_config: Tuple[str, str, str, Any], + background_config: Dict[str,Tuple[str, str, str, Any]], ): """Gathers audio clips, gathers all screenshots, stitches them together and saves the final video to assets/temp Args: @@ -300,7 +300,7 @@ def make_final_video( f"Thumbnail - Building Thumbnail in assets/temp/{reddit_id}/thumbnail.png" ) - text = f"Background by {background_config[2]}" + text = f"Background by {background_config['video'][2]}" background_clip = ffmpeg.drawtext( background_clip, text=text, @@ -347,7 +347,7 @@ def make_final_video( pbar.update(100 - old_percentage) pbar.close() - save_data(subreddit, filename + ".mp4", title, idx, background_config[2]) + save_data(subreddit, filename + ".mp4", title, idx, background_config['video'][2]) print_step("Removing temporary files 🗑") cleanups = cleanup(reddit_id) print_substep(f"Removed {cleanups} temporary files 🗑") From 5a103e76cddf006ff816af9d448a83173bfdf070 Mon Sep 17 00:00:00 2001 From: Lucas Date: Fri, 21 Apr 2023 22:09:53 -0300 Subject: [PATCH 15/38] rendering video and audio --- utils/.config.template.toml | 4 ++-- utils/background_audios.json | 10 ++++++++++ video_creation/background.py | 12 ++---------- video_creation/final_video.py | 4 +++- 4 files changed, 17 insertions(+), 13 deletions(-) diff --git a/utils/.config.template.toml b/utils/.config.template.toml index b146922..75c5e4e 100644 --- a/utils/.config.template.toml +++ b/utils/.config.template.toml @@ -34,8 +34,8 @@ resolution_h = { optional = false, default = 1920, example = 2560, explantation [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" } -background_audio = { optional = true, type = "bool", default = false, example = false, options = [true, false,], explanation = "Sets a audio to play in the background (put a background.mp3 file in the assets/backgrounds directory for it to be used.)" } -background_audio_volume = { optional = true, type = "float", default = 0.3, example = 0.1, explanation="Sets the volume of the background audio. only used if the background_audio is also set to true" } +background_audio = { optional = true, type = "bool", default = false, example = false, options = ["minecraft","lofi"], explanation = "Sets a audio to play in the background (put a background.mp3 file in the assets/backgrounds directory for it to be used.)" } +background_audio_volume = { optional = true, type = "float", default = 0.1, example = 0.05, explanation="Sets the volume of the background audio. Warning: if you set more than 1.0, the volume will be increased" } background_thumbnail = { optional = true, type = "bool", default = false, example = false, options = [true, false,], explanation = "Generate a thumbnail for the video (put a thumbnail.png file in the assets/backgrounds directory.)" } background_thumbnail_font_family = { optional = true, default = "arial", example = "arial", explanation = "Font family for the thumbnail text" } background_thumbnail_font_size = { optional = true, type = "int", default = 96, example = 96, explanation = "Font size in pixels for the thumbnail text" } diff --git a/utils/background_audios.json b/utils/background_audios.json index bd34cef..2dcd35c 100644 --- a/utils/background_audios.json +++ b/utils/background_audios.json @@ -4,5 +4,15 @@ "https://www.youtube.com/watch?v=2p3nBYUaJz8", "minecraft.mp3", "adriPixs" + ], + "lofi":[ + "https://www.youtube.com/watch?v=BEXL80LS0-I", + "lofi.mp3", + "stompsPlaylist" + ], + "undertale":[ + "https://www.youtube.com/watch?v=TIokr8jJPkM", + "undertale.mp3", + "abby" ] } diff --git a/video_creation/background.py b/video_creation/background.py index 55b5399..4919519 100644 --- a/video_creation/background.py +++ b/video_creation/background.py @@ -115,20 +115,12 @@ def chop_background( video_choice = f"{background_config['video'][2]}-{background_config['video'][1]}" audio_choice = f"{background_config['audio'][2]}-{background_config['audio'][1]}" id = re.sub(r"[^\w\s-]", "", reddit_object["thread_id"]) - - # audioclip = audioclip.fx( volumex, 0.2) - # final_audio = mpe.CompositeAudioClip([final.audio, audioclip]) - # # lowered_audio = audio_background.multiply_volume( # todo get this to work - # # VOLUME_MULTIPLIER) # lower volume by background_audio_volume, use with fx - # final.set_audio(final_audio) background_video = VideoFileClip(f"assets/backgrounds/video/{video_choice}") background_audio = AudioFileClip(f"assets/backgrounds/audio/{audio_choice}") start_time_video, end_time_video = get_start_and_end_times(video_length, background_video.duration) start_time_audio, end_time_audio = get_start_and_end_times(video_length, background_audio.duration) - #background_audio.set_start(start_time_audio) - #background_audio.set_end(end_time_audio) - background_audio = background_audio.fx(afx.volumex,0.1) - #background_audio = background_audio.subclip(start_time_audio,end_time_audio) + background_audio = background_audio.fx(afx.volumex,0.07) + background_audio = background_audio.subclip(start_time_audio,end_time_audio) background_audio.write_audiofile(f"assets/temp/{id}/background.mp3") background_video.set_audio(background_audio) diff --git a/video_creation/final_video.py b/video_creation/final_video.py index 5e42e12..c0e7ad7 100644 --- a/video_creation/final_video.py +++ b/video_creation/final_video.py @@ -177,6 +177,8 @@ def make_final_video( screenshot_width = int((W * 45) // 100) audio = ffmpeg.input(f"assets/temp/{reddit_id}/audio.mp3") + background_audio = ffmpeg.input(f"assets/temp/{reddit_id}/background.mp3") + final_audio = ffmpeg.filter([audio, background_audio], "amix") image_clips = list() @@ -327,7 +329,7 @@ def make_final_video( with ProgressFfmpeg(length, on_update_example) as progress: ffmpeg.output( background_clip, - audio, + final_audio, path, f="mp4", **{ From 1abfc4b3218f51a227c581a71a2c9d293ae088ff Mon Sep 17 00:00:00 2001 From: Lucas Date: Fri, 21 Apr 2023 23:01:26 -0300 Subject: [PATCH 16/38] 2 samples with backgroundMusic and without it --- utils/.config.template.toml | 2 +- video_creation/background.py | 16 ++++++++++------ video_creation/final_video.py | 29 ++++++++++++++++++++++++++--- 3 files changed, 37 insertions(+), 10 deletions(-) diff --git a/utils/.config.template.toml b/utils/.config.template.toml index 75c5e4e..b4074d7 100644 --- a/utils/.config.template.toml +++ b/utils/.config.template.toml @@ -34,7 +34,7 @@ resolution_h = { optional = false, default = 1920, example = 2560, explantation [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" } -background_audio = { optional = true, type = "bool", default = false, example = false, options = ["minecraft","lofi"], explanation = "Sets a audio to play in the background (put a background.mp3 file in the assets/backgrounds directory for it to be used.)" } +background_audio = { optional = true, default = "lofi", example = "minecraft", options = ["minecraft","lofi","undertale"], explanation = "Sets a audio to play in the background (put a background.mp3 file in the assets/backgrounds directory for it to be used.)" } background_audio_volume = { optional = true, type = "float", default = 0.1, example = 0.05, explanation="Sets the volume of the background audio. Warning: if you set more than 1.0, the volume will be increased" } background_thumbnail = { optional = true, type = "bool", default = false, example = false, options = [true, false,], explanation = "Generate a thumbnail for the video (put a thumbnail.png file in the assets/backgrounds directory.)" } background_thumbnail_font_family = { optional = true, default = "arial", example = "arial", explanation = "Font family for the thumbnail text" } diff --git a/video_creation/background.py b/video_creation/background.py index 4919519..36400b2 100644 --- a/video_creation/background.py +++ b/video_creation/background.py @@ -98,16 +98,18 @@ def download_background_audio(background_config: Tuple[str, str, str]): ) print_substep("Downloading the backgrounds audio... please be patient 🙏 ") print_substep(f"Downloading {filename} from {uri}") - YouTube(uri, on_progress_callback=on_progress).streams.filter(only_audio=True).first().download("assets/backgrounds/audio", filename=f"{credit}-{filename}") + YouTube(uri, on_progress_callback=on_progress).streams.filter( + only_audio=True + ).first().download("assets/backgrounds/audio", filename=f"{credit}-{filename}") print_substep("Background audio downloaded successfully! 🎉", style="bold green") def chop_background( - background_config: Dict[str,Tuple[str, str, str, Any]], video_length: int, reddit_object: dict + background_config: Dict[str,Tuple], video_length: int, reddit_object: dict ): - """Generates the background footage to be used in the video and writes it to assets/temp/background.mp4 + """Generates the background audio and footage to be used in the video and writes it to assets/temp/background.mp3 and assets/temp/background.mp4 Args: - background_config (Tuple[str, str, str, Any]) : Current background configuration + background_config (Dict[str,Tuple]]) : Current background configuration video_length (int): Length of the clip where the background footage is to be taken out of """ @@ -119,10 +121,12 @@ def chop_background( background_audio = AudioFileClip(f"assets/backgrounds/audio/{audio_choice}") start_time_video, end_time_video = get_start_and_end_times(video_length, background_video.duration) start_time_audio, end_time_audio = get_start_and_end_times(video_length, background_audio.duration) - background_audio = background_audio.fx(afx.volumex,0.07) + # Create a audio clip + background_audio_volume = settings.config["settings"]["background"][f"background_audio_volume"] + background_audio = background_audio.fx(afx.volumex,background_audio_volume) background_audio = background_audio.subclip(start_time_audio,end_time_audio) background_audio.write_audiofile(f"assets/temp/{id}/background.mp3") - background_video.set_audio(background_audio) + #background_video.set_audio(background_audio) try: diff --git a/video_creation/final_video.py b/video_creation/final_video.py index c0e7ad7..89187ca 100644 --- a/video_creation/final_video.py +++ b/video_creation/final_video.py @@ -108,7 +108,7 @@ def make_final_video( number_of_clips: int, length: int, reddit_obj: dict, - background_config: Dict[str,Tuple[str, str, str, Any]], + background_config: Dict[str,Tuple], ): """Gathers audio clips, gathers all screenshots, stitches them together and saves the final video to assets/temp Args: @@ -262,6 +262,10 @@ def make_final_video( if not exists(f"./results/{subreddit}"): print_substep("The results folder didn't exist so I made it") os.makedirs(f"./results/{subreddit}") + + if not exists(f"./results/{subreddit}/{filename}"): + print_substep("The results folder didn't exist so I made it") + os.makedirs(f"./results/{subreddit}/{filename}") # create a thumbnail for the video settingsbackground = settings.config["settings"]["background"] @@ -324,13 +328,32 @@ def make_final_video( path = f"results/{subreddit}/{filename}" path = path[:251] - path = path + ".mp4" + #path = path + ".mp4" with ProgressFfmpeg(length, on_update_example) as progress: ffmpeg.output( background_clip, final_audio, - path, + path+f"/{filename}.mp4", + f="mp4", + **{ + "c:v": "h264", + "b:v": "20M", + "b:a": "192k", + "threads": multiprocessing.cpu_count(), + }, + ).overwrite_output().global_args("-progress", progress.output_file.name).run( + quiet=True, + overwrite_output=True, + capture_stdout=False, + capture_stderr=False, + ) + + with ProgressFfmpeg(length, on_update_example) as progress: + ffmpeg.output( + background_clip, + audio, + path+"/NoBackgroundAudio.mp4", f="mp4", **{ "c:v": "h264", From 15a4f80f994f231b47e83fbbfa9aeba201b10cbf Mon Sep 17 00:00:00 2001 From: Lucas de Almeida <105776775+propilideno@users.noreply.github.com> Date: Fri, 21 Apr 2023 23:05:48 -0300 Subject: [PATCH 17/38] 2 samples with backgroundMusic and without it --- video_creation/data/videos.json | 67 +-------------------------------- 1 file changed, 1 insertion(+), 66 deletions(-) diff --git a/video_creation/data/videos.json b/video_creation/data/videos.json index a7eb3b8..fe51488 100644 --- a/video_creation/data/videos.json +++ b/video_creation/data/videos.json @@ -1,66 +1 @@ -[ - { - "subreddit": "", - "id": "12tt2xe", - "time": "1682111299", - "background_credit": "", - "reddit_title": "skipped", - "filename": "" - }, - { - "subreddit": "", - "id": "12u9m3f", - "time": "1682114905", - "background_credit": "", - "reddit_title": "skipped", - "filename": "" - }, - { - "subreddit": "", - "id": "12u5j7a", - "time": "1682116292", - "background_credit": "", - "reddit_title": "skipped", - "filename": "" - }, - { - "subreddit": "", - "id": "12twuvx", - "time": "1682118162", - "background_credit": "", - "reddit_title": "skipped", - "filename": "" - }, - { - "subreddit": "", - "id": "12tir3d", - "time": "1682121760", - "background_credit": "", - "reddit_title": "skipped", - "filename": "" - }, - { - "subreddit": "", - "id": "12u60fn", - "time": "1682122061", - "background_credit": "", - "reddit_title": "skipped", - "filename": "" - }, - { - "subreddit": "", - "id": "12txuo4", - "time": "1682123020", - "background_credit": "", - "reddit_title": "skipped", - "filename": "" - }, - { - "subreddit": "AskReddit", - "id": "12uei9x", - "time": "1682123178", - "background_credit": "bbswitzer", - "reddit_title": "People who pick up trash on the sides of roads what is the coolest grossestmost interesting thing youve found", - "filename": "People who pick up trash on the sides of roads what is the coolest grossestmost interesting thing youve found.mp4" - } -] \ No newline at end of file +[] From 1f48c53a7451fdd17d2b8f9d6e7eca26b2489d7b Mon Sep 17 00:00:00 2001 From: Lucas Date: Sun, 23 Apr 2023 11:07:17 -0300 Subject: [PATCH 18/38] new toml config and added background audio feature --- README.md | 2 +- requirements.txt | 3 +- utils/.config.template.toml | 3 +- video_creation/background.py | 40 +++++++++------- video_creation/final_video.py | 88 ++++++++++++++++++++++++----------- 5 files changed, 89 insertions(+), 47 deletions(-) diff --git a/README.md b/README.md index e6f61a6..81e37be 100644 --- a/README.md +++ b/README.md @@ -70,7 +70,7 @@ In its current state, this bot does exactly what it needs to do. However, improv I have tried to simplify the code so anyone can read it and start contributing at any skill level. Don't be shy :) contribute! - [ ] Creating better documentation and adding a command line interface. -- [ ] Allowing the user to choose background music for their videos. +- [x] Allowing the user to choose background music for their videos. - [x] Allowing users to choose a reddit thread instead of being randomized. - [x] Allowing users to choose a background that is picked instead of the Minecraft one. - [x] Allowing users to choose between any subreddit. diff --git a/requirements.txt b/requirements.txt index 22d3d7f..634a24b 100644 --- a/requirements.txt +++ b/requirements.txt @@ -19,4 +19,5 @@ unidecode==1.3.2 spacy==3.4.1 torch==1.12.1 transformers==4.25.1 -ffmpeg-python==0.2.0 \ No newline at end of file +ffmpeg-python==0.2.0 +yt-dlp==2023.3.4 \ No newline at end of file diff --git a/utils/.config.template.toml b/utils/.config.template.toml index b4074d7..a9d6d27 100644 --- a/utils/.config.template.toml +++ b/utils/.config.template.toml @@ -35,7 +35,8 @@ resolution_h = { optional = false, default = 1920, example = 2560, explantation [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" } background_audio = { optional = true, default = "lofi", example = "minecraft", options = ["minecraft","lofi","undertale"], explanation = "Sets a audio to play in the background (put a background.mp3 file in the assets/backgrounds directory for it to be used.)" } -background_audio_volume = { optional = true, type = "float", default = 0.1, example = 0.05, explanation="Sets the volume of the background audio. Warning: if you set more than 1.0, the volume will be increased" } +background_audio_volume = { optional = true, type = "float", nmin = 0, nmax = 1, default = 0.1, example = 0.05, explanation="Sets the volume of the background audio. Type a value between 0 and 1.", oob_error = "The volume HAS to be between 0 and 1", input_error = "The volume HAS to be a float number between 0 and 1"} +allow_only_tts = { optional = true, type = "bool", default = false, example = false, explanation="Used if you want to render another video with only TTS audio in a separate folder", input_error = "The value HAS to be true or false"} background_thumbnail = { optional = true, type = "bool", default = false, example = false, options = [true, false,], explanation = "Generate a thumbnail for the video (put a thumbnail.png file in the assets/backgrounds directory.)" } background_thumbnail_font_family = { optional = true, default = "arial", example = "arial", explanation = "Font family for the thumbnail text" } background_thumbnail_font_size = { optional = true, type = "int", default = 96, example = 96, explanation = "Font size in pixels for the thumbnail text" } diff --git a/video_creation/background.py b/video_creation/background.py index 36400b2..3b896d9 100644 --- a/video_creation/background.py +++ b/video_creation/background.py @@ -5,12 +5,13 @@ from pathlib import Path from random import randrange from typing import Any, Tuple,Dict -from moviepy.editor import VideoFileClip,AudioFileClip,afx +from moviepy.editor import VideoFileClip,AudioFileClip 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 +import yt_dlp def load_background_options(): background_options = {} @@ -81,9 +82,14 @@ def download_background_video(background_config: Tuple[str, str, str, Any]): ) 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/video", filename=f"{credit}-{filename}") + ydl_opts = { + 'format': "bestvideo[height<=1080][ext=mp4]", + "outtmpl": f"assets/backgrounds/video/{credit}-{filename}", + "retries": 10, + } + + with yt_dlp.YoutubeDL(ydl_opts) as ydl: + ydl.download(uri) print_substep("Background video downloaded successfully! 🎉", style="bold green") def download_background_audio(background_config: Tuple[str, str, str]): @@ -103,6 +109,8 @@ def download_background_audio(background_config: Tuple[str, str, str]): ).first().download("assets/backgrounds/audio", filename=f"{credit}-{filename}") print_substep("Background audio downloaded successfully! 🎉", style="bold green") + + def chop_background( background_config: Dict[str,Tuple], video_length: int, reddit_object: dict ): @@ -112,23 +120,23 @@ def chop_background( background_config (Dict[str,Tuple]]) : Current background configuration video_length (int): Length of the clip where the background footage is to be taken out of """ + id = re.sub(r"[^\w\s-]", "", reddit_object["thread_id"]) + + if(settings.config["settings"]["background"][f"background_audio_volume"] == 0): + print_step("Volume was set to 0. Skipping background audio creation . . .") + else: + print_step("Finding a spot in the backgrounds audio to chop...✂️") + audio_choice = f"{background_config['audio'][2]}-{background_config['audio'][1]}" + background_audio = AudioFileClip(f"assets/backgrounds/audio/{audio_choice}") + start_time_audio, end_time_audio = get_start_and_end_times(video_length, background_audio.duration) + background_audio = background_audio.subclip(start_time_audio,end_time_audio) + background_audio.write_audiofile(f"assets/temp/{id}/background.mp3") print_step("Finding a spot in the backgrounds video to chop...✂️") video_choice = f"{background_config['video'][2]}-{background_config['video'][1]}" - audio_choice = f"{background_config['audio'][2]}-{background_config['audio'][1]}" - id = re.sub(r"[^\w\s-]", "", reddit_object["thread_id"]) background_video = VideoFileClip(f"assets/backgrounds/video/{video_choice}") - background_audio = AudioFileClip(f"assets/backgrounds/audio/{audio_choice}") start_time_video, end_time_video = get_start_and_end_times(video_length, background_video.duration) - start_time_audio, end_time_audio = get_start_and_end_times(video_length, background_audio.duration) - # Create a audio clip - background_audio_volume = settings.config["settings"]["background"][f"background_audio_volume"] - background_audio = background_audio.fx(afx.volumex,background_audio_volume) - background_audio = background_audio.subclip(start_time_audio,end_time_audio) - background_audio.write_audiofile(f"assets/temp/{id}/background.mp3") - #background_video.set_audio(background_audio) - - + # Extract video subclip try: ffmpeg_extract_subclip( f"assets/backgrounds/video/{video_choice}", diff --git a/video_creation/final_video.py b/video_creation/final_video.py index 89187ca..63c5842 100644 --- a/video_creation/final_video.py +++ b/video_creation/final_video.py @@ -103,6 +103,28 @@ def prepare_background(reddit_id: str, W: int, H: int) -> str: exit() return output_path +def merge_background_audio(audio: ffmpeg, reddit_id: str): + """Gather an audio and merge with assets/backgrounds/background.mp3 + Args: + audio (ffmpeg): The TTS final audio but without background. + reddit_id (str): The ID of subreddit + """ + background_audio_volume = settings.config["settings"]["background"]["background_audio_volume"] + if (background_audio_volume == 0): + return audio # Return the original audio + else: + # sets volume to config + bg_audio = ( + ffmpeg.input(f"assets/temp/{reddit_id}/background.mp3") + .filter( + "volume", + background_audio_volume, + ) + ) + # Merges audio and background_audio + merged_audio = ffmpeg.filter([audio, bg_audio], "amix", duration="longest") + return merged_audio # Return merged audio + def make_final_video( number_of_clips: int, @@ -122,6 +144,10 @@ def make_final_video( H: Final[int] = int(settings.config["settings"]["resolution_h"]) reddit_id = re.sub(r"[^\w\s-]", "", reddit_obj["thread_id"]) + + allowOnlyTTSFolder: bool = settings.config["settings"]["background"]["allow_only_tts"] \ + 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)) @@ -177,8 +203,7 @@ def make_final_video( screenshot_width = int((W * 45) // 100) audio = ffmpeg.input(f"assets/temp/{reddit_id}/audio.mp3") - background_audio = ffmpeg.input(f"assets/temp/{reddit_id}/background.mp3") - final_audio = ffmpeg.filter([audio, background_audio], "amix") + final_audio = merge_background_audio(audio,reddit_id) image_clips = list() @@ -263,9 +288,9 @@ def make_final_video( print_substep("The results folder didn't exist so I made it") os.makedirs(f"./results/{subreddit}") - if not exists(f"./results/{subreddit}/{filename}"): - print_substep("The results folder didn't exist so I made it") - os.makedirs(f"./results/{subreddit}/{filename}") + if not exists(f"./results/{subreddit}/OnlyTTS") and allowOnlyTTSFolder: + print_substep("The 'OnlyTTS' folder didn't exist so I made it") + os.makedirs(f"./results/{subreddit}/OnlyTTS") # create a thumbnail for the video settingsbackground = settings.config["settings"]["background"] @@ -326,9 +351,10 @@ def make_final_video( old_percentage = pbar.n pbar.update(status - old_percentage) - path = f"results/{subreddit}/{filename}" - path = path[:251] + path = f"results/{subreddit}" #path = path + ".mp4" + if(allowOnlyTTSFolder): + processingLength = 2*length with ProgressFfmpeg(length, on_update_example) as progress: ffmpeg.output( @@ -348,32 +374,38 @@ def make_final_video( capture_stdout=False, capture_stderr=False, ) - - with ProgressFfmpeg(length, on_update_example) as progress: - ffmpeg.output( - background_clip, - audio, - path+"/NoBackgroundAudio.mp4", - f="mp4", - **{ - "c:v": "h264", - "b:v": "20M", - "b:a": "192k", - "threads": multiprocessing.cpu_count(), - }, - ).overwrite_output().global_args("-progress", progress.output_file.name).run( - quiet=True, - overwrite_output=True, - capture_stdout=False, - capture_stderr=False, - ) - old_percentage = pbar.n pbar.update(100 - old_percentage) + if(allowOnlyTTSFolder): + print_step("Rendering the Only TTS Video 🎥") + with ProgressFfmpeg(length, on_update_example) as progress: + ffmpeg.output( + background_clip, + audio, + path+f"/OnlyTTS/{filename}.mp4", + f="mp4", + **{ + "c:v": "h264", + "b:v": "20M", + "b:a": "192k", + "threads": multiprocessing.cpu_count(), + }, + ).overwrite_output().global_args("-progress", progress.output_file.name).run( + quiet=True, + overwrite_output=True, + capture_stdout=False, + capture_stderr=False, + ) + old_percentage = pbar.n + pbar.update(100 - old_percentage) + pbar.close() + + + save_data(subreddit, filename + ".mp4", title, idx, background_config['video'][2]) print_step("Removing temporary files 🗑") cleanups = cleanup(reddit_id) print_substep(f"Removed {cleanups} temporary files 🗑") - print_step("Done! 🎉 The video is in the results folder 📁") + print_step("Done! 🎉 The video is in the results folder 📁") \ No newline at end of file From d9ff36b034e83865080fc7c1a6d4afdfd7908b9a Mon Sep 17 00:00:00 2001 From: Lucas Date: Sun, 23 Apr 2023 18:10:10 -0300 Subject: [PATCH 19/38] Merge with develop branch and no pytube required --- main.py | 9 +++++++-- requirements.txt | 1 - utils/.config.template.toml | 4 ++-- video_creation/background.py | 16 ++++++++++++---- video_creation/final_video.py | 4 ---- 5 files changed, 21 insertions(+), 13 deletions(-) diff --git a/main.py b/main.py index 81fb503..0a17968 100755 --- a/main.py +++ b/main.py @@ -6,6 +6,7 @@ from os import name from pathlib import Path from subprocess import Popen +import ffmpeg from prawcore import ResponseException from utils.console import print_substep from reddit.subreddit import get_subreddit_threads @@ -57,7 +58,11 @@ def main(POST_ID=None) -> None: download_background_video(bg_config["video"]) download_background_audio(bg_config["audio"]) chop_background(bg_config, length, reddit_object) - make_final_video(number_of_comments, length, reddit_object, bg_config) + try: + make_final_video(number_of_comments, length, reddit_object, bg_config) + except ffmpeg.Error as e: + print(e.stderr.decode("utf8")) + exit(1) def run_many(times) -> None: @@ -131,4 +136,4 @@ if __name__ == "__main__": f"Error: {err} \n" f'Config: {config["settings"]}' ) - raise err + raise err \ No newline at end of file diff --git a/requirements.txt b/requirements.txt index 634a24b..823493e 100644 --- a/requirements.txt +++ b/requirements.txt @@ -5,7 +5,6 @@ moviepy==1.0.3 playwright==1.23.0 praw==7.6.1 prawcore~=2.3.0 -pytube==12.1.0 requests==2.28.1 rich==13.3.1 toml==0.10.2 diff --git a/utils/.config.template.toml b/utils/.config.template.toml index a9d6d27..c8d7d61 100644 --- a/utils/.config.template.toml +++ b/utils/.config.template.toml @@ -43,11 +43,11 @@ background_thumbnail_font_size = { optional = true, type = "int", default = 96, background_thumbnail_font_color = { optional = true, default = "255,255,255", example = "255,255,255", explanation = "Font color in RGB format for the thumbnail text" } [settings.tts] -voice_choice = { optional = false, default = "tiktok", options = ["streamlabspolly", "tiktok", "googletranslate", "awspolly", "pyttsx", ], example = "tiktok", explanation = "The voice platform used for TTS generation. This can be left blank and you will be prompted to choose at runtime." } +voice_choice = { optional = false, default = "streamlabspolly", options = ["streamlabspolly", "tiktok", "googletranslate", "awspolly", "pyttsx", ], example = "tiktok", explanation = "The voice platform used for TTS generation. This can be left blank and you will be prompted to choose at runtime." } aws_polly_voice = { optional = false, default = "Matthew", example = "Matthew", explanation = "The voice used for AWS Polly" } streamlabs_polly_voice = { optional = false, default = "Matthew", example = "Matthew", explanation = "The voice used for Streamlabs Polly" } tiktok_voice = { optional = true, default = "en_us_001", example = "en_us_006", explanation = "The voice used for TikTok TTS" } -tiktok_sessionid = { optional = true, example = "c76bcc3a7625abcc27b508c7db457ff1", explanation = "TikTok sessionid needed for the TTS API request. Check documentation if you don't know how to obtain it." } +tiktok_sessionid = { optional = true, example = "c76bcc3a7625abcc27b508c7db457ff1", explanation = "TikTok sessionid needed if you're using the TikTok TTS. Check documentation if you don't know how to obtain it." } python_voice = { optional = false, default = "1", example = "1", explanation = "The index of the system tts voices (can be downloaded externally, run ptt.py to find value, start from zero)" } py_voice_num = { optional = false, default = "2", example = "2", explanation = "The number of system voices (2 are pre-installed in Windows)" } silence_duration = { optional = true, example = "0.1", explanation = "Time in seconds between TTS comments", default = 0.3, type = "float" } diff --git a/video_creation/background.py b/video_creation/background.py index 3b896d9..8c3dcee 100644 --- a/video_creation/background.py +++ b/video_creation/background.py @@ -7,7 +7,6 @@ from typing import Any, Tuple,Dict from moviepy.editor import VideoFileClip,AudioFileClip 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 @@ -104,9 +103,18 @@ def download_background_audio(background_config: Tuple[str, str, str]): ) print_substep("Downloading the backgrounds audio... please be patient 🙏 ") print_substep(f"Downloading {filename} from {uri}") - YouTube(uri, on_progress_callback=on_progress).streams.filter( - only_audio=True - ).first().download("assets/backgrounds/audio", filename=f"{credit}-{filename}") + ydl_opts = { + 'outtmpl': f'./assets/backgrounds/audio/{credit}-{filename}', + 'format': 'bestaudio/best', + 'postprocessors': [{ + 'preferredcodec': 'mp3', + 'preferredquality': '192', + }], + } + + with yt_dlp.YoutubeDL(ydl_opts) as ydl: + ydl.download([uri]) + print_substep("Background audio downloaded successfully! 🎉", style="bold green") diff --git a/video_creation/final_video.py b/video_creation/final_video.py index 63c5842..452b128 100644 --- a/video_creation/final_video.py +++ b/video_creation/final_video.py @@ -398,12 +398,8 @@ def make_final_video( ) old_percentage = pbar.n pbar.update(100 - old_percentage) - pbar.close() - - - save_data(subreddit, filename + ".mp4", title, idx, background_config['video'][2]) print_step("Removing temporary files 🗑") cleanups = cleanup(reddit_id) From 0258026ebd81e9c068fec6039b37c70e6fbee8de Mon Sep 17 00:00:00 2001 From: Lucas Date: Sun, 23 Apr 2023 18:30:54 -0300 Subject: [PATCH 20/38] fixed audio post processing audio download bug --- video_creation/background.py | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/video_creation/background.py b/video_creation/background.py index 8c3dcee..d27ee6b 100644 --- a/video_creation/background.py +++ b/video_creation/background.py @@ -7,7 +7,6 @@ from typing import Any, Tuple,Dict from moviepy.editor import VideoFileClip,AudioFileClip from moviepy.video.io.ffmpeg_tools import ffmpeg_extract_subclip -from pytube.cli import on_progress from utils import settings from utils.console import print_step, print_substep import yt_dlp @@ -106,10 +105,7 @@ def download_background_audio(background_config: Tuple[str, str, str]): ydl_opts = { 'outtmpl': f'./assets/backgrounds/audio/{credit}-{filename}', 'format': 'bestaudio/best', - 'postprocessors': [{ - 'preferredcodec': 'mp3', - 'preferredquality': '192', - }], + 'extract_audio': True, } with yt_dlp.YoutubeDL(ydl_opts) as ydl: From e488ef6e0c19ef49898c84594c52a3a9a9c60b0c Mon Sep 17 00:00:00 2001 From: Lucas Date: Mon, 24 Apr 2023 10:43:14 -0300 Subject: [PATCH 21/38] better explanation on toml and new default value --- utils/.config.template.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/utils/.config.template.toml b/utils/.config.template.toml index c8d7d61..71dcef7 100644 --- a/utils/.config.template.toml +++ b/utils/.config.template.toml @@ -34,8 +34,8 @@ resolution_h = { optional = false, default = 1920, example = 2560, explantation [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" } -background_audio = { optional = true, default = "lofi", example = "minecraft", options = ["minecraft","lofi","undertale"], explanation = "Sets a audio to play in the background (put a background.mp3 file in the assets/backgrounds directory for it to be used.)" } -background_audio_volume = { optional = true, type = "float", nmin = 0, nmax = 1, default = 0.1, example = 0.05, explanation="Sets the volume of the background audio. Type a value between 0 and 1.", oob_error = "The volume HAS to be between 0 and 1", input_error = "The volume HAS to be a float number between 0 and 1"} +background_audio = { optional = true, default = "lofi", example = "minecraft", options = ["minecraft","lofi","undertale",""], explanation = "Sets the background audio for the video" } +background_audio_volume = { optional = true, type = "float", nmin = 0, nmax = 1, default = 0.15, example = 0.05, explanation="Sets the volume of the background audio. If you don't want background audio, set it to 0.", oob_error = "The volume HAS to be between 0 and 1", input_error = "The volume HAS to be a float number between 0 and 1"} allow_only_tts = { optional = true, type = "bool", default = false, example = false, explanation="Used if you want to render another video with only TTS audio in a separate folder", input_error = "The value HAS to be true or false"} background_thumbnail = { optional = true, type = "bool", default = false, example = false, options = [true, false,], explanation = "Generate a thumbnail for the video (put a thumbnail.png file in the assets/backgrounds directory.)" } background_thumbnail_font_family = { optional = true, default = "arial", example = "arial", explanation = "Font family for the thumbnail text" } From 778d9c0c37bb970492a51b93b6a8977b8542acfa Mon Sep 17 00:00:00 2001 From: Lucas Date: Mon, 24 Apr 2023 16:35:08 -0300 Subject: [PATCH 22/38] changing allow_only_tts to enable_extra_audio --- utils/.config.template.toml | 2 +- video_creation/final_video.py | 7 ++----- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/utils/.config.template.toml b/utils/.config.template.toml index 71dcef7..d9d7582 100644 --- a/utils/.config.template.toml +++ b/utils/.config.template.toml @@ -36,7 +36,7 @@ resolution_h = { optional = false, default = 1920, example = 2560, explantation 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" } background_audio = { optional = true, default = "lofi", example = "minecraft", options = ["minecraft","lofi","undertale",""], explanation = "Sets the background audio for the video" } background_audio_volume = { optional = true, type = "float", nmin = 0, nmax = 1, default = 0.15, example = 0.05, explanation="Sets the volume of the background audio. If you don't want background audio, set it to 0.", oob_error = "The volume HAS to be between 0 and 1", input_error = "The volume HAS to be a float number between 0 and 1"} -allow_only_tts = { optional = true, type = "bool", default = false, example = false, explanation="Used if you want to render another video with only TTS audio in a separate folder", input_error = "The value HAS to be true or false"} +enable_extra_audio = { optional = true, type = "bool", default = false, example = false, explanation="Used if you want to render another video without background audio in a separate folder", input_error = "The value HAS to be true or false"} background_thumbnail = { optional = true, type = "bool", default = false, example = false, options = [true, false,], explanation = "Generate a thumbnail for the video (put a thumbnail.png file in the assets/backgrounds directory.)" } background_thumbnail_font_family = { optional = true, default = "arial", example = "arial", explanation = "Font family for the thumbnail text" } background_thumbnail_font_size = { optional = true, type = "int", default = 96, example = 96, explanation = "Font size in pixels for the thumbnail text" } diff --git a/video_creation/final_video.py b/video_creation/final_video.py index 452b128..55e0d39 100644 --- a/video_creation/final_video.py +++ b/video_creation/final_video.py @@ -145,7 +145,7 @@ def make_final_video( reddit_id = re.sub(r"[^\w\s-]", "", reddit_obj["thread_id"]) - allowOnlyTTSFolder: bool = settings.config["settings"]["background"]["allow_only_tts"] \ + allowOnlyTTSFolder: bool = settings.config["settings"]["background"]["enable_extra_audio"] \ and settings.config["settings"]["background"]["background_audio_volume"] != 0 print_step("Creating the final video 🎥") @@ -285,7 +285,7 @@ def make_final_video( subreddit = settings.config["reddit"]["thread"]["subreddit"] if not exists(f"./results/{subreddit}"): - print_substep("The results folder didn't exist so I made it") + print_substep("The 'results' folder didn't exist so I made it") os.makedirs(f"./results/{subreddit}") if not exists(f"./results/{subreddit}/OnlyTTS") and allowOnlyTTSFolder: @@ -352,9 +352,6 @@ def make_final_video( pbar.update(status - old_percentage) path = f"results/{subreddit}" - #path = path + ".mp4" - if(allowOnlyTTSFolder): - processingLength = 2*length with ProgressFfmpeg(length, on_update_example) as progress: ffmpeg.output( From d8347e08b9c2a6524823c9b030cce60c27cb06dc Mon Sep 17 00:00:00 2001 From: Lucas Date: Mon, 24 Apr 2023 23:55:18 -0300 Subject: [PATCH 23/38] Fixed issues and improvements related by Jason --- main.py | 7 ++++--- video_creation/background.py | 4 ++-- video_creation/final_video.py | 17 ++++++++++------- 3 files changed, 16 insertions(+), 12 deletions(-) diff --git a/main.py b/main.py index 0a17968..2b78629 100755 --- a/main.py +++ b/main.py @@ -51,10 +51,11 @@ def main(POST_ID=None) -> None: redditid = id(reddit_object) length, number_of_comments = save_text_to_mp3(reddit_object) length = math.ceil(length) - bg_config = {} get_screenshots_of_reddit_posts(reddit_object, number_of_comments) - bg_config["video"] = get_background_config("video") - bg_config["audio"] = get_background_config("audio") + bg_config = { + "video": get_background_config("video"), + "audio": get_background_config("audio"), + } download_background_video(bg_config["video"]) download_background_audio(bg_config["audio"]) chop_background(bg_config, length, reddit_object) diff --git a/video_creation/background.py b/video_creation/background.py index d27ee6b..010f15e 100644 --- a/video_creation/background.py +++ b/video_creation/background.py @@ -22,8 +22,8 @@ def load_background_options(): background_options["audio"] = json.load(json_file) # Remove "__comment" from backgrounds - background_options["video"].pop("__comment", None) - background_options["audio"].pop("__comment", None) + del background_options["video"]["__comment"] + del background_options["audio"]["__comment"] # Add position lambda function # (https://zulko.github.io/moviepy/ref/VideoClip/VideoClip.html#moviepy.video.VideoClip.VideoClip.set_position) diff --git a/video_creation/final_video.py b/video_creation/final_video.py index 55e0d39..ca801c5 100644 --- a/video_creation/final_video.py +++ b/video_creation/final_video.py @@ -285,11 +285,11 @@ def make_final_video( subreddit = settings.config["reddit"]["thread"]["subreddit"] if not exists(f"./results/{subreddit}"): - print_substep("The 'results' folder didn't exist so I made it") + print_substep("The 'results' folder could not be found so it was automatically created.") os.makedirs(f"./results/{subreddit}") if not exists(f"./results/{subreddit}/OnlyTTS") and allowOnlyTTSFolder: - print_substep("The 'OnlyTTS' folder didn't exist so I made it") + print_substep("The 'OnlyTTS' folder could not be found so it was automatically created.") os.makedirs(f"./results/{subreddit}/OnlyTTS") # create a thumbnail for the video @@ -297,7 +297,7 @@ def make_final_video( if settingsbackground["background_thumbnail"]: if not exists(f"./results/{subreddit}/thumbnails"): - print_substep("The results/thumbnails folder didn't exist so I made it") + print_substep("The 'results/thumbnails' folder could not be found so it was automatically created.") os.makedirs(f"./results/{subreddit}/thumbnails") # get the first file with the .png extension from assets/backgrounds and use it as a background for the thumbnail first_image = next( @@ -351,13 +351,14 @@ def make_final_video( old_percentage = pbar.n pbar.update(status - old_percentage) - path = f"results/{subreddit}" - + defaultPath = f"results/{subreddit}" with ProgressFfmpeg(length, on_update_example) as progress: + path = defaultPath + f"/{filename}" + path = path[:251] + ".mp4" #Prevent a error by limiting the path length, do not change this. ffmpeg.output( background_clip, final_audio, - path+f"/{filename}.mp4", + path, f="mp4", **{ "c:v": "h264", @@ -374,12 +375,14 @@ def make_final_video( old_percentage = pbar.n pbar.update(100 - old_percentage) if(allowOnlyTTSFolder): + path = defaultPath + f"/OnlyTTS/{filename}" + path = path[:251] + ".mp4" #Prevent a error by limiting the path length, do not change this. print_step("Rendering the Only TTS Video 🎥") with ProgressFfmpeg(length, on_update_example) as progress: ffmpeg.output( background_clip, audio, - path+f"/OnlyTTS/{filename}.mp4", + path, f="mp4", **{ "c:v": "h264", From 7613ac59e7e58ef0db56bf7720749fd2f5046d8d Mon Sep 17 00:00:00 2001 From: Lucas Date: Tue, 25 Apr 2023 00:05:51 -0300 Subject: [PATCH 24/38] added only no copyright songs --- utils/.config.template.toml | 2 +- utils/background_audios.json | 20 ++++++++++---------- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/utils/.config.template.toml b/utils/.config.template.toml index d9d7582..a360569 100644 --- a/utils/.config.template.toml +++ b/utils/.config.template.toml @@ -34,7 +34,7 @@ resolution_h = { optional = false, default = 1920, example = 2560, explantation [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" } -background_audio = { optional = true, default = "lofi", example = "minecraft", options = ["minecraft","lofi","undertale",""], explanation = "Sets the background audio for the video" } +background_audio = { optional = true, default = "lofi", example = "chill-summer", options = ["lofi","lofi-2","chill-summer",""], explanation = "Sets the background audio for the video" } background_audio_volume = { optional = true, type = "float", nmin = 0, nmax = 1, default = 0.15, example = 0.05, explanation="Sets the volume of the background audio. If you don't want background audio, set it to 0.", oob_error = "The volume HAS to be between 0 and 1", input_error = "The volume HAS to be a float number between 0 and 1"} enable_extra_audio = { optional = true, type = "bool", default = false, example = false, explanation="Used if you want to render another video without background audio in a separate folder", input_error = "The value HAS to be true or false"} background_thumbnail = { optional = true, type = "bool", default = false, example = false, options = [true, false,], explanation = "Generate a thumbnail for the video (put a thumbnail.png file in the assets/backgrounds directory.)" } diff --git a/utils/background_audios.json b/utils/background_audios.json index 2dcd35c..752436d 100644 --- a/utils/background_audios.json +++ b/utils/background_audios.json @@ -1,18 +1,18 @@ { "__comment": "Supported Backgrounds Audio. Can add/remove background audio here...", - "minecraft": [ - "https://www.youtube.com/watch?v=2p3nBYUaJz8", - "minecraft.mp3", - "adriPixs" + "lofi": [ + "https://www.youtube.com/watch?v=LTphVIore3A", + "lofi.mp3", + "Super Lofi World" ], - "lofi":[ + "lofi-2":[ "https://www.youtube.com/watch?v=BEXL80LS0-I", - "lofi.mp3", + "lofi-2.mp3", "stompsPlaylist" ], - "undertale":[ - "https://www.youtube.com/watch?v=TIokr8jJPkM", - "undertale.mp3", - "abby" + "chill-summer":[ + "https://www.youtube.com/watch?v=EZE8JagnBI8", + "chill-summer.mp3", + "Mellow Vibes Radio" ] } From 81785199379f200590678cf04db4b8d6281fb4ac Mon Sep 17 00:00:00 2001 From: Simon <65854503+OpenSourceSimon@users.noreply.github.com> Date: Fri, 28 Apr 2023 08:51:10 +0100 Subject: [PATCH 25/38] Exit on wrong Python version --- main.py | 1 + 1 file changed, 1 insertion(+) diff --git a/main.py b/main.py index d2273c6..35eddfe 100755 --- a/main.py +++ b/main.py @@ -86,6 +86,7 @@ def shutdown(): if __name__ == "__main__": if sys.version_info.major != 3 or sys.version_info.minor != 10: 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.") + exit() ffmpeg_install() # install ffmpeg if not installed directory = Path().absolute() config = settings.check_toml( From 20c39a289441f65197b3867e8d46725172fd99d2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 28 Apr 2023 11:01:23 +0000 Subject: [PATCH 26/38] Bump rich from 13.3.1 to 13.3.5 Bumps [rich](https://github.com/Textualize/rich) from 13.3.1 to 13.3.5. - [Release notes](https://github.com/Textualize/rich/releases) - [Changelog](https://github.com/Textualize/rich/blob/master/CHANGELOG.md) - [Commits](https://github.com/Textualize/rich/compare/v13.3.1...v13.3.5) --- updated-dependencies: - dependency-name: rich dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 823493e..239fa13 100644 --- a/requirements.txt +++ b/requirements.txt @@ -6,7 +6,7 @@ playwright==1.23.0 praw==7.6.1 prawcore~=2.3.0 requests==2.28.1 -rich==13.3.1 +rich==13.3.5 toml==0.10.2 translators==5.3.1 pyttsx3==2.90 From d26e82d04c6288f3811d0ad4667ebaed35090700 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 2 May 2023 11:01:23 +0000 Subject: [PATCH 27/38] Bump flask from 2.2.2 to 2.3.2 Bumps [flask](https://github.com/pallets/flask) from 2.2.2 to 2.3.2. - [Release notes](https://github.com/pallets/flask/releases) - [Changelog](https://github.com/pallets/flask/blob/main/CHANGES.rst) - [Commits](https://github.com/pallets/flask/compare/2.2.2...2.3.2) --- updated-dependencies: - dependency-name: flask dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 823493e..417c1bf 100644 --- a/requirements.txt +++ b/requirements.txt @@ -12,7 +12,7 @@ translators==5.3.1 pyttsx3==2.90 Pillow~=9.4.0 tomlkit==0.11.4 -Flask==2.2.2 +Flask==2.3.2 clean-text==0.6.0 unidecode==1.3.2 spacy==3.4.1 From 276c0679b565c291f901569d55605459c6c4c2de Mon Sep 17 00:00:00 2001 From: liamb Date: Wed, 3 May 2023 11:47:57 +1000 Subject: [PATCH 28/38] add periods fix --- TTS/engine_wrapper.py | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/TTS/engine_wrapper.py b/TTS/engine_wrapper.py index e6b92d8..f040bf7 100644 --- a/TTS/engine_wrapper.py +++ b/TTS/engine_wrapper.py @@ -55,9 +55,20 @@ class TTSEngine: self, ): # adds periods to the end of paragraphs (where people often forget to put them) so tts doesn't blend sentences for comment in self.reddit_object["comments"]: + # remove links + regex_urls = r"((http|https)\:\/\/)?[a-zA-Z0-9\.\/\?\:@\-_=#]+\.([a-zA-Z]){2,6}([a-zA-Z0-9\.\&\/\?\:@\-_=#])*" + comment["comment_body"] = re.sub(regex_urls, " ", comment["comment_body"]) comment["comment_body"] = comment["comment_body"].replace("\n", ". ") + comment["comment_body"] = re.sub(r'\bAI\b', 'A.I', comment["comment_body"]) + comment["comment_body"] = re.sub(r'\bAGI\b', 'A.G.I', comment["comment_body"]) if comment["comment_body"][-1] != ".": comment["comment_body"] += "." + comment["comment_body"] = comment["comment_body"].replace(". . .", ".") + comment["comment_body"] = comment["comment_body"].replace(".. . ", ".") + comment["comment_body"] = comment["comment_body"].replace(". . ", ".") + comment["comment_body"] = re.sub(r'\."\.', '".', comment["comment_body"]) + print(comment["comment_body"]) + def run(self) -> Tuple[int, int]: Path(self.path).mkdir(parents=True, exist_ok=True) From 165bdeb10fa4f15e443ff3a890da28629a94b329 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 3 May 2023 15:02:12 +0000 Subject: [PATCH 29/38] Bump tomlkit from 0.11.4 to 0.11.8 Bumps [tomlkit](https://github.com/sdispater/tomlkit) from 0.11.4 to 0.11.8. - [Release notes](https://github.com/sdispater/tomlkit/releases) - [Changelog](https://github.com/sdispater/tomlkit/blob/master/CHANGELOG.md) - [Commits](https://github.com/sdispater/tomlkit/compare/0.11.4...0.11.8) --- updated-dependencies: - dependency-name: tomlkit dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 551f454..fcdd273 100644 --- a/requirements.txt +++ b/requirements.txt @@ -11,7 +11,7 @@ toml==0.10.2 translators==5.3.1 pyttsx3==2.90 Pillow~=9.4.0 -tomlkit==0.11.4 +tomlkit==0.11.8 Flask==2.3.2 clean-text==0.6.0 unidecode==1.3.2 From eb7d1e944038601b968a7d26fd072aac94c3d447 Mon Sep 17 00:00:00 2001 From: xyba <62798507+xyba1337@users.noreply.github.com> Date: Wed, 3 May 2023 22:56:28 +0200 Subject: [PATCH 30/38] Reddit credentials validation in screenshot_downloader.py MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit # Description The Playwright locator timed out in line 175 without letting the user know why. The browser failed to log me in to Reddit using the incorrect credentials, which prevented it from accessing the desired post. This fix should be a much more user-friendly approach. # Issue Fixes https://github.com/elebumm/RedditVideoMakerBot/issues/1596 None # Checklist: - [❌] I am pushing changes to the **develop** branch - [❌] I am using the recommended development environment - [✅] I have performed a self-review of my own code - [✅] I have commented my code, particularly in hard-to-understand areas - [❌] I have formatted and linted my code using python-black and pylint - [✅] I have cleaned up unnecessary files - [✅] My changes generate no new warnings - [✅] My changes follow the existing code-style - [✅] My changes are relevant to the project # Any other information (e.g how to test the changes) Without my changes, you can set headless to false and run the program. You will notice a timeout exception comfing from playwright without any indications to the user as to why it happened. With my changes however, it performs a check to see if the reddit login is returning an error message, if it does it let's the user know to fix his credentials inside of config.toml. --- video_creation/screenshot_downloader.py | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/video_creation/screenshot_downloader.py b/video_creation/screenshot_downloader.py index 1c3ab5e..48ed8be 100644 --- a/video_creation/screenshot_downloader.py +++ b/video_creation/screenshot_downloader.py @@ -115,6 +115,19 @@ def get_screenshots_of_reddit_posts(reddit_object: dict, screenshot_num: int): ) page.locator("button[class$='m-full-width']").click() page.wait_for_timeout(5000) + + login_error_div = page.locator(".AnimatedForm__errorMessage").first + if login_error_div.is_visible(): + login_error_message = login_error_div.inner_text() + if login_error_message.strip() == "": + # The div element is empty, no error + pass + else: + # The div contains an error message + print_substep("Your reddit credentials are incorrect! Please modify them accordingly in the config.toml file.", style="red") + exit() + else: + pass page.wait_for_load_state() # Get the thread screenshot From 2328e969377e19562646d67fe3e60c4a5f676e7c Mon Sep 17 00:00:00 2001 From: zombie22 Date: Fri, 19 May 2023 21:25:43 +0200 Subject: [PATCH 31/38] feat: Added hard reload functionality for data refreshing --- GUI/layout.html | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/GUI/layout.html b/GUI/layout.html index d56299e..59bd5ef 100644 --- a/GUI/layout.html +++ b/GUI/layout.html @@ -56,6 +56,13 @@ .tooltip-inner { max-width: 500px !important; } + #hard-reload { + cursor: pointer; + color: darkblue; + } + #hard-reload:hover { + color: blue; + } @@ -132,11 +139,17 @@ Theme by © Bootstrap. Developers and Maintainers

-

If your data is not refreshing, try to hard reload(Ctrl + F5) and visit your local +

If your data is not refreshing, try to hard reload(Ctrl + F5) or click this and visit your local + {{ file }} file.

+ \ No newline at end of file From 8a24a9e77309327b70c40b9823ee37151bab28d6 Mon Sep 17 00:00:00 2001 From: Shayan Jizan Date: Sun, 21 May 2023 13:49:05 -0400 Subject: [PATCH 32/38] Update Dockerfile Install the ffmpeg dependency. --- Dockerfile | 1 + 1 file changed, 1 insertion(+) diff --git a/Dockerfile b/Dockerfile index 6d090c6..4cf2a71 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,6 +1,7 @@ FROM python:3.10.9-slim RUN apt update +RUN apt-get install -y ffmpeg RUN apt install python3-pip -y RUN mkdir /app From 07beeafa50f19ba699da53cae5407c6803562777 Mon Sep 17 00:00:00 2001 From: liamb13 <69778531+liamb13@users.noreply.github.com> Date: Mon, 22 May 2023 13:16:48 +1000 Subject: [PATCH 33/38] Update screenshot_downloader.py Scrolls comment into view. Without, it can break --- video_creation/screenshot_downloader.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/video_creation/screenshot_downloader.py b/video_creation/screenshot_downloader.py index ecff2f4..636a833 100644 --- a/video_creation/screenshot_downloader.py +++ b/video_creation/screenshot_downloader.py @@ -230,6 +230,8 @@ def get_screenshots_of_reddit_posts(reddit_object: dict, screenshot_num: int): zoom = settings.config["settings"]["zoom"] # zoom the body of the page page.evaluate("document.body.style.zoom="+str(zoom)) + # scroll comment into view + page.locator(f"#t1_{comment['comment_id']}").scroll_into_view_if_needed() # as zooming the body doesn't change the properties of the divs, we need to adjust for the zoom location = page.locator(f"#t1_{comment['comment_id']}").bounding_box() for i in location: From fcf6ef93e520cb5250e4ec66a44ea8053ad2bce9 Mon Sep 17 00:00:00 2001 From: Lucas Date: Fri, 26 May 2023 17:16:53 -0300 Subject: [PATCH 34/38] Fix #1649 randrange bug --- video_creation/background.py | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/video_creation/background.py b/video_creation/background.py index 010f15e..7cfdf81 100644 --- a/video_creation/background.py +++ b/video_creation/background.py @@ -47,7 +47,14 @@ def get_start_and_end_times(video_length: int, length_of_clip: int) -> Tuple[int Returns: tuple[int,int]: Start and end time of the randomized interval """ - random_time = randrange(180, int(length_of_clip) - int(video_length)) + initialValue = 180 + # Issue #1649 - Ensures that will be a valid interval in the video + while(int(length_of_clip) <= int(video_length+initialValue)): + if(initialValue == initialValue //2): + raise Exception("Your background is too short for this video length") + else: + initialValue //= 2 #Divides the initial value by 2 until reach 0 + random_time = randrange(initialValue, int(length_of_clip) - int(video_length)) return random_time, random_time + video_length @@ -157,4 +164,4 @@ def chop_background( return background_config["video"][2] # Create a tuple for downloads background (background_audio_options, background_video_options) -background_options = load_background_options() \ No newline at end of file +background_options = load_background_options() From 47f762eb0d93ce2533b05064553606ff2bfb9104 Mon Sep 17 00:00:00 2001 From: Xpl0itU <24777100+Xpl0itU@users.noreply.github.com> Date: Sat, 27 May 2023 18:06:16 +0200 Subject: [PATCH 35/38] Fix adding ffmpeg to path This fixes adding ffmpeg to the path by adding it to the user path instead of the system path, which doesn't require admin privileges to do --- utils/ffmpeg_install.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/utils/ffmpeg_install.py b/utils/ffmpeg_install.py index 5522028..1f72cfb 100644 --- a/utils/ffmpeg_install.py +++ b/utils/ffmpeg_install.py @@ -23,7 +23,7 @@ def ffmpeg_install_windows(): os.remove(f"ffmpeg/doc/{file}") os.rmdir("ffmpeg/doc") # Add to the path - subprocess.run("setx /M PATH \"%PATH%;%CD%\\ffmpeg\"", shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + subprocess.run("setx PATH \"%PATH%;%CD%\\ffmpeg\"", shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) print("FFmpeg installed successfully! Please restart your computer and then re-run the program.") exit() except Exception as e: @@ -81,4 +81,4 @@ def ffmpeg_install(): except Exception as e: print("Welcome fellow traveler! You're one of the few who have made it this far. We have no idea how you got at this error, but we're glad you're here. Please report this error to the developer, and we'll try to fix it as soon as possible. Thank you for your patience!") print(e) - return None \ No newline at end of file + return None From 3e6cc23002980944a4cfad4a4511da6f18d42337 Mon Sep 17 00:00:00 2001 From: Simon <65854503+OpenSourceSimon@users.noreply.github.com> Date: Sun, 28 May 2023 12:56:14 +0200 Subject: [PATCH 36/38] Delete codesee-arch-diagram.yml --- .github/workflows/codesee-arch-diagram.yml | 23 ---------------------- 1 file changed, 23 deletions(-) delete mode 100644 .github/workflows/codesee-arch-diagram.yml diff --git a/.github/workflows/codesee-arch-diagram.yml b/.github/workflows/codesee-arch-diagram.yml deleted file mode 100644 index a72f58b..0000000 --- a/.github/workflows/codesee-arch-diagram.yml +++ /dev/null @@ -1,23 +0,0 @@ -# This workflow was added by CodeSee. Learn more at https://codesee.io/ -# This is v2.0 of this workflow file -on: - push: - branches: - - master - pull_request_target: - types: [opened, synchronize, reopened] - -name: CodeSee - -permissions: read-all - -jobs: - codesee: - runs-on: ubuntu-latest - continue-on-error: true - name: Analyze the repo with CodeSee - steps: - - uses: Codesee-io/codesee-action@v2 - with: - codesee-token: ${{ secrets.CODESEE_ARCH_DIAG_API_TOKEN }} - codesee-url: https://app.codesee.io From 19b44b1302bd371c0f204d6c94ac7bc79b892120 Mon Sep 17 00:00:00 2001 From: Simon Date: Sun, 28 May 2023 13:10:29 +0200 Subject: [PATCH 37/38] Add random_voice --- TTS/engine_wrapper.py | 4 +--- utils/.config.template.toml | 1 + video_creation/final_video.py | 1 + 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/TTS/engine_wrapper.py b/TTS/engine_wrapper.py index f040bf7..cdd024e 100644 --- a/TTS/engine_wrapper.py +++ b/TTS/engine_wrapper.py @@ -67,8 +67,6 @@ class TTSEngine: comment["comment_body"] = comment["comment_body"].replace(".. . ", ".") comment["comment_body"] = comment["comment_body"].replace(". . ", ".") comment["comment_body"] = re.sub(r'\."\.', '".', comment["comment_body"]) - print(comment["comment_body"]) - def run(self) -> Tuple[int, int]: Path(self.path).mkdir(parents=True, exist_ok=True) @@ -152,7 +150,7 @@ class TTSEngine: print("OSError") def call_tts(self, filename: str, text: str): - self.tts_module.run(text, filepath=f"{self.path}/{filename}.mp3") + self.tts_module.run(text, filepath=f"{self.path}/{filename}.mp3", random_voice=settings.config["settings"]["tts"]["random_voice"]) # try: # self.length += MP3(f"{self.path}/{filename}.mp3").info.length # except (MutagenError, HeaderNotFoundError): diff --git a/utils/.config.template.toml b/utils/.config.template.toml index a360569..a674f53 100644 --- a/utils/.config.template.toml +++ b/utils/.config.template.toml @@ -44,6 +44,7 @@ background_thumbnail_font_color = { optional = true, default = "255,255,255", ex [settings.tts] voice_choice = { optional = false, default = "streamlabspolly", options = ["streamlabspolly", "tiktok", "googletranslate", "awspolly", "pyttsx", ], example = "tiktok", explanation = "The voice platform used for TTS generation. This can be left blank and you will be prompted to choose at runtime." } +random_voice = { optional = false, default = true, example = true, options = [true, false,], explanation = "Randomizes the voice used for each comment" } aws_polly_voice = { optional = false, default = "Matthew", example = "Matthew", explanation = "The voice used for AWS Polly" } streamlabs_polly_voice = { optional = false, default = "Matthew", example = "Matthew", explanation = "The voice used for Streamlabs Polly" } tiktok_voice = { optional = true, default = "en_us_001", example = "en_us_006", explanation = "The voice used for TikTok TTS" } diff --git a/video_creation/final_video.py b/video_creation/final_video.py index ca801c5..0ff652a 100644 --- a/video_creation/final_video.py +++ b/video_creation/final_video.py @@ -103,6 +103,7 @@ def prepare_background(reddit_id: str, W: int, H: int) -> str: exit() return output_path + def merge_background_audio(audio: ffmpeg, reddit_id: str): """Gather an audio and merge with assets/backgrounds/background.mp3 Args: From 655c5070105ed87aac204f211fbb77acf4fedb47 Mon Sep 17 00:00:00 2001 From: Simon Date: Sun, 28 May 2023 13:17:22 +0200 Subject: [PATCH 38/38] Couple of fixes including translators fix --- TTS/engine_wrapper.py | 7 ++----- video_creation/final_video.py | 9 ++++----- video_creation/screenshot_downloader.py | 10 +++++----- 3 files changed, 11 insertions(+), 15 deletions(-) diff --git a/TTS/engine_wrapper.py b/TTS/engine_wrapper.py index e6b92d8..8157032 100644 --- a/TTS/engine_wrapper.py +++ b/TTS/engine_wrapper.py @@ -3,11 +3,8 @@ import re from pathlib import Path from typing import Tuple -# import sox -# from mutagen import MutagenError -# from mutagen.mp3 import MP3, HeaderNotFoundError import numpy as np -import translators as ts +import translators from moviepy.audio.AudioClip import AudioClip from moviepy.audio.fx.volumex import volumex from moviepy.editor import AudioFileClip @@ -172,6 +169,6 @@ def process_text(text: str, clean: bool = True): new_text = sanitize_text(text) if clean else text if lang: print_substep("Translating Text...") - translated_text = ts.google(text, to_language=lang) + translated_text = translators.google(text, to_language=lang) new_text = sanitize_text(translated_text) return new_text diff --git a/video_creation/final_video.py b/video_creation/final_video.py index 4838574..68ff6aa 100644 --- a/video_creation/final_video.py +++ b/video_creation/final_video.py @@ -1,13 +1,12 @@ import multiprocessing import os import re -import shutil from os.path import exists # Needs to be imported specifically from typing import Final from typing import Tuple, Any import ffmpeg -import translators as ts +import translators from PIL import Image from rich.console import Console from rich.progress import track @@ -18,12 +17,12 @@ from utils.console import print_step, print_substep from utils.thumbnail import create_thumbnail from utils.videos import save_data -console = Console() - import tempfile import threading import time +console = Console() + class ProgressFfmpeg(threading.Thread): def __init__(self, vid_duration_seconds, progress_update_callback): @@ -73,7 +72,7 @@ def name_normalize(name: str) -> str: lang = settings.config["reddit"]["thread"]["post_lang"] if lang: print_substep("Translating filename...") - translated_name = ts.google(name, to_language=lang) + translated_name = translators.google(name, to_language=lang) return translated_name else: return name diff --git a/video_creation/screenshot_downloader.py b/video_creation/screenshot_downloader.py index 636a833..fe9a127 100644 --- a/video_creation/screenshot_downloader.py +++ b/video_creation/screenshot_downloader.py @@ -3,7 +3,7 @@ import re from pathlib import Path from typing import Dict, Final -import translators as ts +import translators from playwright.async_api import async_playwright # pylint: disable=unused-import from playwright.sync_api import ViewportSize, sync_playwright from rich.progress import track @@ -144,7 +144,7 @@ def get_screenshots_of_reddit_posts(reddit_object: dict, screenshot_num: int): if lang: print_substep("Translating post...") - texts_in_tl = ts.google( + texts_in_tl = translators.google( reddit_object["thread_title"], to_language=lang, ) @@ -158,7 +158,7 @@ def get_screenshots_of_reddit_posts(reddit_object: dict, screenshot_num: int): postcontentpath = f"assets/temp/{reddit_id}/png/title.png" try: - if(settings.config["settings"]["zoom"] != 1): + if settings.config["settings"]["zoom"] != 1: # store zoom settings zoom = settings.config["settings"]["zoom"] # zoom the body of the page @@ -216,7 +216,7 @@ def get_screenshots_of_reddit_posts(reddit_object: dict, screenshot_num: int): # translate code if settings.config["reddit"]["thread"]["post_lang"]: - comment_tl = ts.google( + comment_tl = translators.google( comment["comment_body"], to_language=settings.config["reddit"]["thread"]["post_lang"], ) @@ -225,7 +225,7 @@ def get_screenshots_of_reddit_posts(reddit_object: dict, screenshot_num: int): [comment_tl, comment["comment_id"]], ) try: - if(settings.config["settings"]["zoom"] != 1): + if settings.config["settings"]["zoom"] != 1: # store zoom settings zoom = settings.config["settings"]["zoom"] # zoom the body of the page