From 1748c383b7d3ee6cfbb37bc9a24323d3677fca24 Mon Sep 17 00:00:00 2001 From: anthony lloyd Date: Sat, 9 Jul 2022 05:53:11 +1000 Subject: [PATCH 1/5] ffmpeg really really bad --- TTS/engine_wrapper.py | 160 +++++++++++++++++++++++++++++++++++++++++- requirements.txt | 2 + 2 files changed, 161 insertions(+), 1 deletion(-) diff --git a/TTS/engine_wrapper.py b/TTS/engine_wrapper.py index a171db7..9f52ec0 100644 --- a/TTS/engine_wrapper.py +++ b/TTS/engine_wrapper.py @@ -2,10 +2,21 @@ from pathlib import Path from typing import Tuple import re +<<<<<<< Updated upstream # import sox # from mutagen import MutagenError # from mutagen.mp3 import MP3, HeaderNotFoundError +======= +import os +from os import getenv + +import numpy as np +import ffmpeg +from moviepy.audio.AudioClip import AudioClip +from moviepy.audio.fx.volumex import volumex +from mutagen.mp3 import MP3 +>>>>>>> Stashed changes import translators as ts from rich.progress import track from moviepy.editor import AudioFileClip, CompositeAudioClip, concatenate_audioclips @@ -82,11 +93,17 @@ class TTSEngine: for x in re.finditer(rf" *((.{{0,{self.tts_module.max_chars}}})(\.|.$))", text) ] + silence_long = AudioClip(make_frame=lambda t: np.sin(440 * 2 * np.pi * t), duration=int(getenv("COMMENT_GAP")), fps=44100) + silence_long_new = volumex(silence_long, 0) + silence_long_new.write_audiofile(f"{self.path}/long_silence.mp3", fps=44100, verbose=False, logger=None) + + bruz = [] idy = None for idy, text_cut in enumerate(split_text): - # print(f"{idx}-{idy}: {text_cut}\n") + # print(f"{idx}-{idy}: {text_cut}\n") self.call_tts(f"{idx}-{idy}.part", text_cut) split_files.append(AudioFileClip(f"{self.path}/{idx}-{idy}.part.mp3")) +<<<<<<< Updated upstream CompositeAudioClip([concatenate_audioclips(split_files)]).write_audiofile( f"{self.path}/{idx}.mp3", fps=44100, verbose=False, logger=None ) @@ -100,6 +117,147 @@ class TTSEngine: # print(f"Cleaning up {self.path}/{idx}-{i}.part.mp3") # Path(f"{self.path}/{idx}-{i}.part.mp3").unlink() +======= + bruz.append(ffmpeg.input(f"{self.path}/{idx}-{idy}.part.mp3")) + if idy == len(split_text)-1: + split_files.append(AudioFileClip(f"{self.path}/long_silence.mp3")) + # print("long silence added") + bruz.append(ffmpeg.input(f"{self.path}/long_silence.mp3")) + + # with open(f"{self.path}/list.txt", 'w') as f: + # for newy in range(0, len(split_text)): + # f.write(f"{self.path}/{idx}-{newy}.part.mp3"+"\n") + # f.write(f"{self.path}/long_silence.mp3") + + if len(bruz) == 1: + stupid0 = bruz[0] + if len(bruz) == 2: + stupid0 = bruz[0] + stupid1 = bruz[1] + if len(bruz) == 3: + stupid0 = bruz[0] + stupid1 = bruz[1] + stupid2 = bruz[2] + if len(bruz) == 4: + stupid0 = bruz[0] + stupid1 = bruz[1] + stupid2 = bruz[2] + stupid3 = bruz[3] + if len(bruz) == 5: + stupid0 = bruz[0] + stupid1 = bruz[1] + stupid2 = bruz[2] + stupid3 = bruz[3] + stupid4 = bruz[4] + if len(bruz) == 5: + stupid0 = bruz[0] + stupid1 = bruz[1] + stupid2 = bruz[2] + stupid3 = bruz[3] + stupid4 = bruz[4] + stupid5 = bruz[5] + + if len(bruz) == 1: + try: + ffmpeg\ + .concat( + stupid0, + v=0, a=1 + )\ + .output(f"{self.path}/{idx}.m4a")\ + .run(capture_stdout=True, capture_stderr=True) + except ffmpeg.Error as e: + print('stdout:', e.stdout.decode('utf8')) + print('stderr:', e.stderr.decode('utf8')) + raise e + elif len(bruz) == 2: + try: + ffmpeg\ + .concat( + stupid0, + stupid1, + v=0, a=1 + )\ + .output(f"{self.path}/{idx}.m4a")\ + .run(capture_stdout=True, capture_stderr=True) + except ffmpeg.Error as e: + print('stdout:', e.stdout.decode('utf8')) + print('stderr:', e.stderr.decode('utf8')) + raise e + elif len(bruz) == 3: + try: + ffmpeg\ + .concat( + stupid0, + stupid1, + stupid2, + v=0, a=1 + )\ + .output(f"{self.path}/{idx}.m4a")\ + .run(capture_stdout=True, capture_stderr=True) + except ffmpeg.Error as e: + print('stdout:', e.stdout.decode('utf8')) + print('stderr:', e.stderr.decode('utf8')) + raise e + elif len(bruz) == 4: + try: + ffmpeg\ + .concat( + stupid0, + stupid1, + stupid2, + stupid3, + v=0, a=1 + )\ + .output(f"{self.path}/{idx}.m4a")\ + .run(capture_stdout=True, capture_stderr=True) + except ffmpeg.Error as e: + print('stdout:', e.stdout.decode('utf8')) + print('stderr:', e.stderr.decode('utf8')) + raise e + elif len(bruz) == 5: + try: + ffmpeg\ + .concat( + stupid0, + stupid1, + stupid2, + stupid3, + stupid4, + v=0, a=1 + )\ + .output(f"{self.path}/{idx}.m4a")\ + .run(capture_stdout=True, capture_stderr=True) + except ffmpeg.Error as e: + print('stdout:', e.stdout.decode('utf8')) + print('stderr:', e.stderr.decode('utf8')) + raise e + elif len(bruz) == 6: + try: + ffmpeg\ + .concat( + stupid0, + stupid1, + stupid2, + stupid3, + stupid4, + stupid5, + v=0, a=1 + )\ + .output(f"{self.path}/{idx}.m4a")\ + .run(capture_stdout=True, capture_stderr=True) + except ffmpeg.Error as e: + print('stdout:', e.stdout.decode('utf8')) + print('stderr:', e.stderr.decode('utf8')) + raise e + # CompositeAudioClip([concatenate_audioclips(split_files)]).write_audiofile( + # f"{self.path}/{idx}.mp3", fps=44100, verbose=False, logger=None + # ) + + # for i in range(0, idy + 1): + # print(f"Cleaning up {self.path}/{idx}-{i}.part.mp3") + # Path(f"{self.path}/{idx}-{i}.part.mp3").unlink() +>>>>>>> Stashed changes def call_tts(self, filename: str, text: str): self.tts_module.run(text=process_text(text), filepath=f"{self.path}/{filename}.mp3") diff --git a/requirements.txt b/requirements.txt index 7ef2ad8..1fb4672 100644 --- a/requirements.txt +++ b/requirements.txt @@ -9,3 +9,5 @@ requests==2.28.1 rich==12.4.4 toml==0.10.2 translators==5.3.1 +ffmpeg-python~= 0.2.0 +numpy~=1.23.0 \ No newline at end of file From 4f68b276f8a65a14a0510c03b8f33c0e3e18e3a1 Mon Sep 17 00:00:00 2001 From: anthony lloyd Date: Sat, 9 Jul 2022 16:56:38 +1000 Subject: [PATCH 2/5] ffmpeg version 2 may require ffmpeg being located in main folder removed additional ffmpeg dependency, now uses OS to call ffmpeg created a loop to write list of files for concatenating ffmpeg runs based off that text file, removing many lines of redundant code fixed incorrect spelling of default max length added comment sorting option into config, not implemented into config generator, choose hot or top added silence to end of audio clips, uses user defined varialbe in config, not implemented into config generator added filter to not do threads with 0 comments changed max length tts of tiktok, reduced to 270 as 300 was causing errors, not completing the mp3 --- TTS/TikTok.py | 2 +- TTS/engine_wrapper.py | 179 ++++-------------------------------------- reddit/subreddit.py | 10 ++- requirements.txt | 1 - utils/subreddit.py | 3 + 5 files changed, 27 insertions(+), 168 deletions(-) diff --git a/TTS/TikTok.py b/TTS/TikTok.py index 743118c..8b2e487 100644 --- a/TTS/TikTok.py +++ b/TTS/TikTok.py @@ -65,7 +65,7 @@ class TikTok: # TikTok Text-to-Speech Wrapper self.URI_BASE = ( "https://api16-normal-useast5.us.tiktokv.com/media/api/text/speech/invoke/?text_speaker=" ) - self.max_chars = 300 + self.max_chars = 270 self.voices = {"human": human, "nonhuman": nonhuman, "noneng": noneng} def run(self, text, filepath, random_voice: bool = False): diff --git a/TTS/engine_wrapper.py b/TTS/engine_wrapper.py index 9f52ec0..936f9c4 100644 --- a/TTS/engine_wrapper.py +++ b/TTS/engine_wrapper.py @@ -2,21 +2,15 @@ from pathlib import Path from typing import Tuple import re -<<<<<<< Updated upstream # import sox # from mutagen import MutagenError # from mutagen.mp3 import MP3, HeaderNotFoundError -======= import os -from os import getenv import numpy as np -import ffmpeg from moviepy.audio.AudioClip import AudioClip from moviepy.audio.fx.volumex import volumex -from mutagen.mp3 import MP3 ->>>>>>> Stashed changes import translators as ts from rich.progress import track from moviepy.editor import AudioFileClip, CompositeAudioClip, concatenate_audioclips @@ -24,7 +18,7 @@ from utils.console import print_step, print_substep from utils.voice import sanitize_text from utils import settings -DEFUALT_MAX_LENGTH: int = 50 # video length variable +DEFAULT_MAX_LENGTH: int = 50 # video length variable class TTSEngine: @@ -46,7 +40,7 @@ class TTSEngine: tts_module, reddit_object: dict, path: str = "assets/temp/mp3", - max_length: int = DEFUALT_MAX_LENGTH, + max_length: int = DEFAULT_MAX_LENGTH, ): self.tts_module = tts_module() self.reddit_object = reddit_object @@ -87,177 +81,34 @@ class TTSEngine: return self.length, idx def split_post(self, text: str, idx: int): - split_files = [] split_text = [ x.group().strip() for x in re.finditer(rf" *((.{{0,{self.tts_module.max_chars}}})(\.|.$))", text) ] + silence_duration = settings.config["settings"]["tts"]["silence_duration"] - silence_long = AudioClip(make_frame=lambda t: np.sin(440 * 2 * np.pi * t), duration=int(getenv("COMMENT_GAP")), fps=44100) + silence_long = AudioClip(make_frame=lambda t: np.sin(440 * 2 * np.pi * t), duration=silence_duration, fps=44100) silence_long_new = volumex(silence_long, 0) silence_long_new.write_audiofile(f"{self.path}/long_silence.mp3", fps=44100, verbose=False, logger=None) - bruz = [] idy = None for idy, text_cut in enumerate(split_text): - # print(f"{idx}-{idy}: {text_cut}\n") + # print(f"{idx}-{idy}: {text_cut}\n") self.call_tts(f"{idx}-{idy}.part", text_cut) - split_files.append(AudioFileClip(f"{self.path}/{idx}-{idy}.part.mp3")) -<<<<<<< Updated upstream - CompositeAudioClip([concatenate_audioclips(split_files)]).write_audiofile( - f"{self.path}/{idx}.mp3", fps=44100, verbose=False, logger=None - ) - for i in split_files: - name = i.filename - i.close() - Path(name).unlink() + with open(f"{self.path}/list.txt", 'w') as f: + for newy in range(0, len(split_text)): + f.write("file " + f"'{idx}-{newy}.part.mp3'"+"\n") + f.write("file " + f"'long_silence.mp3'"+"\n") - # for i in range(0, idy + 1): - # print(f"Cleaning up {self.path}/{idx}-{i}.part.mp3") + os.system("ffmpeg -f concat -y -hide_banner -loglevel panic -safe 0 " + + "-i " + f"{self.path}/list.txt " + + "-c copy " + f"{self.path}/{idx}.mp3") - # Path(f"{self.path}/{idx}-{i}.part.mp3").unlink() -======= - bruz.append(ffmpeg.input(f"{self.path}/{idx}-{idy}.part.mp3")) - if idy == len(split_text)-1: - split_files.append(AudioFileClip(f"{self.path}/long_silence.mp3")) - # print("long silence added") - bruz.append(ffmpeg.input(f"{self.path}/long_silence.mp3")) - # with open(f"{self.path}/list.txt", 'w') as f: - # for newy in range(0, len(split_text)): - # f.write(f"{self.path}/{idx}-{newy}.part.mp3"+"\n") - # f.write(f"{self.path}/long_silence.mp3") - - if len(bruz) == 1: - stupid0 = bruz[0] - if len(bruz) == 2: - stupid0 = bruz[0] - stupid1 = bruz[1] - if len(bruz) == 3: - stupid0 = bruz[0] - stupid1 = bruz[1] - stupid2 = bruz[2] - if len(bruz) == 4: - stupid0 = bruz[0] - stupid1 = bruz[1] - stupid2 = bruz[2] - stupid3 = bruz[3] - if len(bruz) == 5: - stupid0 = bruz[0] - stupid1 = bruz[1] - stupid2 = bruz[2] - stupid3 = bruz[3] - stupid4 = bruz[4] - if len(bruz) == 5: - stupid0 = bruz[0] - stupid1 = bruz[1] - stupid2 = bruz[2] - stupid3 = bruz[3] - stupid4 = bruz[4] - stupid5 = bruz[5] - - if len(bruz) == 1: - try: - ffmpeg\ - .concat( - stupid0, - v=0, a=1 - )\ - .output(f"{self.path}/{idx}.m4a")\ - .run(capture_stdout=True, capture_stderr=True) - except ffmpeg.Error as e: - print('stdout:', e.stdout.decode('utf8')) - print('stderr:', e.stderr.decode('utf8')) - raise e - elif len(bruz) == 2: - try: - ffmpeg\ - .concat( - stupid0, - stupid1, - v=0, a=1 - )\ - .output(f"{self.path}/{idx}.m4a")\ - .run(capture_stdout=True, capture_stderr=True) - except ffmpeg.Error as e: - print('stdout:', e.stdout.decode('utf8')) - print('stderr:', e.stderr.decode('utf8')) - raise e - elif len(bruz) == 3: - try: - ffmpeg\ - .concat( - stupid0, - stupid1, - stupid2, - v=0, a=1 - )\ - .output(f"{self.path}/{idx}.m4a")\ - .run(capture_stdout=True, capture_stderr=True) - except ffmpeg.Error as e: - print('stdout:', e.stdout.decode('utf8')) - print('stderr:', e.stderr.decode('utf8')) - raise e - elif len(bruz) == 4: - try: - ffmpeg\ - .concat( - stupid0, - stupid1, - stupid2, - stupid3, - v=0, a=1 - )\ - .output(f"{self.path}/{idx}.m4a")\ - .run(capture_stdout=True, capture_stderr=True) - except ffmpeg.Error as e: - print('stdout:', e.stdout.decode('utf8')) - print('stderr:', e.stderr.decode('utf8')) - raise e - elif len(bruz) == 5: - try: - ffmpeg\ - .concat( - stupid0, - stupid1, - stupid2, - stupid3, - stupid4, - v=0, a=1 - )\ - .output(f"{self.path}/{idx}.m4a")\ - .run(capture_stdout=True, capture_stderr=True) - except ffmpeg.Error as e: - print('stdout:', e.stdout.decode('utf8')) - print('stderr:', e.stderr.decode('utf8')) - raise e - elif len(bruz) == 6: - try: - ffmpeg\ - .concat( - stupid0, - stupid1, - stupid2, - stupid3, - stupid4, - stupid5, - v=0, a=1 - )\ - .output(f"{self.path}/{idx}.m4a")\ - .run(capture_stdout=True, capture_stderr=True) - except ffmpeg.Error as e: - print('stdout:', e.stdout.decode('utf8')) - print('stderr:', e.stderr.decode('utf8')) - raise e - # CompositeAudioClip([concatenate_audioclips(split_files)]).write_audiofile( - # f"{self.path}/{idx}.mp3", fps=44100, verbose=False, logger=None - # ) - - # for i in range(0, idy + 1): - # print(f"Cleaning up {self.path}/{idx}-{i}.part.mp3") - # Path(f"{self.path}/{idx}-{i}.part.mp3").unlink() ->>>>>>> Stashed changes + for i in range(0, idy + 1): + # print(f"Cleaning up {self.path}/{idx}-{i}.part.mp3") + Path(f"{self.path}/{idx}-{i}.part.mp3").unlink() def call_tts(self, filename: str, text: str): self.tts_module.run(text=process_text(text), filepath=f"{self.path}/{filename}.mp3") diff --git a/reddit/subreddit.py b/reddit/subreddit.py index b64a52a..44ef55a 100644 --- a/reddit/subreddit.py +++ b/reddit/subreddit.py @@ -67,11 +67,17 @@ def get_subreddit_threads(POST_ID: str): and len(settings.config["reddit"]["thread"]["post_id"].split("+")) == 1 ): submission = reddit.submission(id=settings.config["reddit"]["thread"]["post_id"]) - else: + comment_type = settings.config["reddit"]["thread"]["sort"] + + if str(comment_type) == "top": + threads = subreddit.top(limit=25) + else: threads = subreddit.hot(limit=25) - submission = get_subreddit_undone(threads, subreddit) + + submission = get_subreddit_undone(threads, subreddit) submission = check_done(submission) # double-checking + if submission is None or not submission.num_comments: return get_subreddit_threads(POST_ID) # submission already done. rerun upvotes = submission.score diff --git a/requirements.txt b/requirements.txt index 1fb4672..1a1a33b 100644 --- a/requirements.txt +++ b/requirements.txt @@ -9,5 +9,4 @@ requests==2.28.1 rich==12.4.4 toml==0.10.2 translators==5.3.1 -ffmpeg-python~= 0.2.0 numpy~=1.23.0 \ No newline at end of file diff --git a/utils/subreddit.py b/utils/subreddit.py index 48dceba..ac3a275 100644 --- a/utils/subreddit.py +++ b/utils/subreddit.py @@ -34,6 +34,9 @@ def get_subreddit_undone(submissions: list, subreddit): if submission.stickied: print_substep("This post was pinned by moderators. Skipping...") continue + if submission.num_comments == 0: + print_substep("This post has 0 comments. Skipping...") + continue return submission print("all submissions have been done going by top submission order") return get_subreddit_undone( From f67b6e802dca06590b09821e0112cf6c475adea4 Mon Sep 17 00:00:00 2001 From: anthony lloyd Date: Sat, 9 Jul 2022 21:52:53 +1000 Subject: [PATCH 3/5] reformatting and additional toml variables reformatted toml to be consistent added variables, sort, sort time and silence duration these variables will interact with the additional options I have added --- .config.template.toml | 60 +++++++++++++++++++------------------------ TTS/engine_wrapper.py | 5 +++- 2 files changed, 30 insertions(+), 35 deletions(-) diff --git a/.config.template.toml b/.config.template.toml index ddfa293..34bd103 100644 --- a/.config.template.toml +++ b/.config.template.toml @@ -1,40 +1,32 @@ [reddit.creds] -client_id = { optional = false, nmin = 12, nmax = 30, explanation = "the ID of your Reddit app of SCRIPT type", example = "fFAGRNJru1FTz70BzhT3Zg", regex = "^[-a-zA-Z0-9._~+/]+=*$", input_error = "The client ID can only contain printable characters.", oob_error = "The ID should be over 12 and under 30 characters, double check your input." } -client_secret = { optional = false, nmin = 20, nmax = 40, explanation = "the SECRET of your Reddit app of SCRIPT type", example = "fFAGRNJru1FTz70BzhT3Zg", regex = "^[-a-zA-Z0-9._~+/]+=*$", input_error = "The client ID can only contain printable characters.", oob_error = "The secret should be over 20 and under 40 characters, double check your input." } -username = { optional = false, nmin = 3, nmax = 20, explanation = "the username of your reddit account", example = "JasonLovesDoggo", regex = "^[-_0-9a-zA-Z]+$", oob_error = "A username HAS to be between 3 and 20 characters" } -password = { optional = false, nmin = 8, explanation = "the password of your reddit account", example = "fFAGRNJru1FTz70BzhT3Zg", oob_error = "Password too short" } -2fa = { optional = true, type = "bool", options = [true, - false, -], default = false, explanation = "Whether you have Reddit 2FA enabled, Valid options are True and False", example = true } - +client_id = { optional = false, example = "fFAGRNJru1FTz70BzhT3Zg", explanation = "the ID of your Reddit app of SCRIPT type", default = "", nmin = 12, nmax = 30, regex = "^[-a-zA-Z0-9._~+/]+=*$", oob_error = "The ID should be over 12 and under 30 characters, double check your input.", input_error = "The client ID can only contain printable characters." } +client_secret = { optional = false, example = "fFAGRNJru1FTz70BzhT3Zg", explanation = "the SECRET of your Reddit app of SCRIPT type", default = "", nmin = 20, nmax = 40, regex = "^[-a-zA-Z0-9._~+/]+=*$", oob_error = "The secret should be over 20 and under 40 characters, double check your input.", input_error = "The client ID can only contain printable characters." } +username = { optional = false, example = "JasonLovesDoggo", explanation = "the username of your reddit account", default = "", nmin = 3, nmax = 20,regex = "^[-_0-9a-zA-Z]+$", oob_error = "A username HAS to be between 3 and 20 characters" } +password = { optional = false, example = "fFAGRNJru1FTz70BzhT3Zg", explanation = "the password of your reddit account", default = "", nmin = 8, oob_error = "Password too short" } +2fa = { optional = true, example = "True", explanation = "Whether you have Reddit 2FA enabled, Valid options are True and False", default = false, options = [true, false], type = "bool" } [reddit.thread] -random = { optional = true, options = [true, - false, -], default = false, type = "bool", explanation = "If set to no, it will ask you a thread link to extract the thread, if yes it will randomize it. Default: 'False'", example = "True" } -subreddit = { optional = false, regex = "[_0-9a-zA-Z]+$", nmin = 3, nmax = 21, explanation = "what subreddit to pull posts from, the name of the sub, not the URL", example = "AskReddit", oob_error = "A subreddit name HAS to be between 3 and 20 characters" } -post_id = { optional = true, default = "", regex = "^((?!://|://)[+a-zA-Z])*$", explanation = "Used if you want to use a specific post.", example = "urdtfx" } -max_comment_length = { default = 500, optional = false, nmin = 10, nmax = 10000, type = "int", explanation = "max number of characters a comment can have. default is 500", example = 500, oob_error = "the max comment length should be between 10 and 10000" } -post_lang = { default = "", optional = true, explanation = "The language you would like to translate to.", example = "es-cr" } +random = { optional = true, example = "True", explanation = "If set to no, it will ask you a thread link to extract the thread, if yes it will randomize it.", default = false, options = [true, false, ], type = "bool" } +subreddit = { optional = false, example = "AskReddit", explanation = "what subreddit to pull posts from, the name of the sub, not the URL", default = "", nmin = 3, nmax = 21,regex = "[_0-9a-zA-Z]+$", oob_error = "A subreddit name HAS to be between 3 and 20 characters" } +post_id = { optional = true, example = "urdtfx", explanation = "Used if you want to use a specific post.", default = "", regex = "^((?!://|://)[+a-zA-Z])*$" } +max_comment_length = { optional = false, example = 500, explanation = "max number of characters a comment can have. default is 500", default = 500, type = "int", nmin = 10, nmax = 10000, oob_error = "the max comment length should be between 10 and 10000" } +post_lang = { optional = true, example = "es-cr", explanation = "The language you would like to translate to.", default = "" } +sort = { optional = true, example = "hot ,top, relevance, new", explanation = "method of sorting threads", default = "top", options = ["hot", "top", "relevance", "new"] } +sort_time = { optional = true, example = "day, hour, week, month, year, all", explanation = "time range to gather threads from", default = "all", options = ["day", "hour", "week", "month", "year", "all"] } +random = { optional = true, example = "True", explanation = "If set to no, it will ask you a thread link to extract the thread, if yes it will randomize it.", default = false, options = [true, false], type = "bool" } [settings] -allow_nsfw = { optional = false, type = "bool", default = false, example = false, options = [true, - false, -], explanation = "Whether to allow NSFW content, True or False" } -theme = { optional = false, default = "dark", example = "light", options = ["dark", - "light", -], explanation = "sets the Reddit theme, either LIGHT or DARK" } -times_to_run = { optional = false, default = 1, example = 2, explanation = "used if you want to run multiple times. set to an int e.g. 4 or 29 or 1", type = "int", nmin = 1, oob_error = "It's very hard to run something less than once." } -opacity = { optional = false, default = 0.9, example = 0.8, explanation = "Sets the opacity of the comments when overlayed over the background", type = "float", nmin = 0, nmax = 1, oob_error = "The opacity HAS to be between 0 and 1", input_error = "The opacity HAS to be a decimal number between 0 and 1" } -storymode = { optional = true, type = "bool", default = false, example = false, options = [true, - false, -], explanation = "not yet implemented" } -background_choice = { optional = true, default = "minecraft", example = "minecraft", options = ["minecraft", "gta", "rocket-league", "motor-gta", ""], explanation = "Sets the background for the video" } -background_audio = { optional = true, type = "bool", default = false, example = false, options = [true, - false, -], explaination="Sets a audio to play in the background (put a background.mp3 file in the assets/backgrounds directory for it to be used.)" } +allow_nsfw = { optional = false, example = "false", explanation = "Whether to allow NSFW content, True or False", default = false, options = [true, false], type = "bool" } +theme = { optional = false, example = "light, dark", explanation = "sets the Reddit theme, either LIGHT or DARK", default = "dark", options = ["dark", "light"] } +times_to_run = { optional = false, example = 2, explanation = "used if you want to run multiple times. set to an int e.g. 4 or 29 or 1", default = 1, type = "int", nmin = 1, oob_error = "It's very hard to run something less than once." } +opacity = { optional = false, example = 0.8, explanation = "Sets the opacity of the comments when overlayed over the background", default = 0.9, type = "float", nmin = 0, nmax = 1, oob_error = "The opacity HAS to be between 0 and 1", input_error = "The opacity HAS to be a decimal number between 0 and 1" } +storymode = { optional = true, example = false, explanation = "not yet implemented", default = false, options = [true, false], type = "bool" } +background_choice = { optional = true, example = "minecraft", explanation = "Sets the background for the video", default = "minecraft", options = ["minecraft", "gta", "rocket-league", "motor-gta",] } +background_audio = { optional = true, example = false, explaination = "Sets a audio to play in the background (put a background.mp3 file in the assets/backgrounds directory for it to be used.)", default = false, options = [true, false], type = "bool" } + [settings.tts] -choice = { optional = false, default = "", options = ["streamlabspolly", "tiktok", "googletranslate", "awspolly", ], example = "streamlabspolly", explanation = "The backend 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 = false, default = "en_us_006", example = "en_us_006", explanation = "The voice used for TikTok TTS" } +choice = { optional = false, example = "streamlabspolly", explanation = "The backend used for TTS generation. This can be left blank and you will be prompted to choose at runtime.", default = "", options = ["streamlabspolly", "tiktok", "googletranslate", "awspolly", "blank"] } +aws_polly_voice = { optional = false, example = "Matthew", explanation = "The voice used for AWS Polly", default = "Matthew" } +streamlabs_polly_voice = { optional = false, example = "Matthew", explanation = "The voice used for Streamlabs Polly", default = "Matthew" } +tiktok_voice = { optional = false, example = "en_us_006", explanation = "The voice used for TikTok TTS", default = "en_us_006" } +silence_duration = { optional = true, example = "0.1", explanation = "time in seconds between TTS comments", default = 0.3, type = "float" } diff --git a/TTS/engine_wrapper.py b/TTS/engine_wrapper.py index 936f9c4..afc1efb 100644 --- a/TTS/engine_wrapper.py +++ b/TTS/engine_wrapper.py @@ -85,7 +85,10 @@ class TTSEngine: x.group().strip() for x in re.finditer(rf" *((.{{0,{self.tts_module.max_chars}}})(\.|.$))", text) ] - silence_duration = settings.config["settings"]["tts"]["silence_duration"] + try: + silence_duration = settings.config["settings"]["tts"]["silence_duration"] + except ValueError: + silence_duration = 0.3 silence_long = AudioClip(make_frame=lambda t: np.sin(440 * 2 * np.pi * t), duration=silence_duration, fps=44100) silence_long_new = volumex(silence_long, 0) From 3b1ae5d47d1b8ff4b7b74ccb501d8c42abf4761a Mon Sep 17 00:00:00 2001 From: anthony lloyd Date: Sat, 9 Jul 2022 22:10:12 +1000 Subject: [PATCH 4/5] hotfix fixed toml template and made sorting options actually apply to the comments --- .config.template.toml | 1 - reddit/subreddit.py | 17 +++++++++++++---- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/.config.template.toml b/.config.template.toml index 34bd103..192ae3d 100644 --- a/.config.template.toml +++ b/.config.template.toml @@ -13,7 +13,6 @@ max_comment_length = { optional = false, example = 500, explanation = "max numb post_lang = { optional = true, example = "es-cr", explanation = "The language you would like to translate to.", default = "" } sort = { optional = true, example = "hot ,top, relevance, new", explanation = "method of sorting threads", default = "top", options = ["hot", "top", "relevance", "new"] } sort_time = { optional = true, example = "day, hour, week, month, year, all", explanation = "time range to gather threads from", default = "all", options = ["day", "hour", "week", "month", "year", "all"] } -random = { optional = true, example = "True", explanation = "If set to no, it will ask you a thread link to extract the thread, if yes it will randomize it.", default = false, options = [true, false], type = "bool" } [settings] allow_nsfw = { optional = false, example = "false", explanation = "Whether to allow NSFW content, True or False", default = false, options = [true, false], type = "bool" } diff --git a/reddit/subreddit.py b/reddit/subreddit.py index 44ef55a..3ad604c 100644 --- a/reddit/subreddit.py +++ b/reddit/subreddit.py @@ -70,10 +70,19 @@ def get_subreddit_threads(POST_ID: str): comment_type = settings.config["reddit"]["thread"]["sort"] - if str(comment_type) == "top": - threads = subreddit.top(limit=25) - else: - threads = subreddit.hot(limit=25) + try: + if str(comment_type) == "top": + threads = subreddit.top(limit=25) + elif str(comment_type) == "new": + threads = subreddit.new(limit=25) + elif str(comment_type) == "hot": + threads = subreddit.hot(limit=25) + elif str(comment_type) == "relevance": + threads = subreddit.relevance(limit=25) + else: + threads = subreddit.top(limit=25) + except AttributeError: + threads = subreddit.top(limit=25) submission = get_subreddit_undone(threads, subreddit) submission = check_done(submission) # double-checking From 89d2da958bac7cd7129a13d3d22c85ba11e3c36b Mon Sep 17 00:00:00 2001 From: anthony lloyd Date: Sun, 10 Jul 2022 03:03:03 +1000 Subject: [PATCH 5/5] tweaks --- .config.template.toml | 4 ++-- TTS/engine_wrapper.py | 2 +- reddit/subreddit.py | 6 ++---- video_creation/final_video.py | 2 ++ 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/.config.template.toml b/.config.template.toml index 192ae3d..ceb59c2 100644 --- a/.config.template.toml +++ b/.config.template.toml @@ -6,9 +6,9 @@ password = { optional = false, example = "fFAGRNJru1FTz70BzhT3Zg", explanation = 2fa = { optional = true, example = "True", explanation = "Whether you have Reddit 2FA enabled, Valid options are True and False", default = false, options = [true, false], type = "bool" } [reddit.thread] -random = { optional = true, example = "True", explanation = "If set to no, it will ask you a thread link to extract the thread, if yes it will randomize it.", default = false, options = [true, false, ], type = "bool" } +random = { optional = true, example = "True", explanation = "If set to false, it will ask you a thread link to extract the thread, if true it will randomize it.", default = true, options = [true, false], type = "bool" } subreddit = { optional = false, example = "AskReddit", explanation = "what subreddit to pull posts from, the name of the sub, not the URL", default = "", nmin = 3, nmax = 21,regex = "[_0-9a-zA-Z]+$", oob_error = "A subreddit name HAS to be between 3 and 20 characters" } -post_id = { optional = true, example = "urdtfx", explanation = "Used if you want to use a specific post.", default = "", regex = "^((?!://|://)[+a-zA-Z])*$" } +post_id = { optional = true, example = "urdtfx", explanation = "Used if you want to use a specific post.", regex = "^((?!://|://)[+a-zA-Z])*$" } max_comment_length = { optional = false, example = 500, explanation = "max number of characters a comment can have. default is 500", default = 500, type = "int", nmin = 10, nmax = 10000, oob_error = "the max comment length should be between 10 and 10000" } post_lang = { optional = true, example = "es-cr", explanation = "The language you would like to translate to.", default = "" } sort = { optional = true, example = "hot ,top, relevance, new", explanation = "method of sorting threads", default = "top", options = ["hot", "top", "relevance", "new"] } diff --git a/TTS/engine_wrapper.py b/TTS/engine_wrapper.py index afc1efb..f50e29f 100644 --- a/TTS/engine_wrapper.py +++ b/TTS/engine_wrapper.py @@ -18,7 +18,7 @@ from utils.console import print_step, print_substep from utils.voice import sanitize_text from utils import settings -DEFAULT_MAX_LENGTH: int = 50 # video length variable +DEFAULT_MAX_LENGTH: int = 45 # video length variable class TTSEngine: diff --git a/reddit/subreddit.py b/reddit/subreddit.py index 3ad604c..c807df1 100644 --- a/reddit/subreddit.py +++ b/reddit/subreddit.py @@ -62,10 +62,8 @@ def get_subreddit_threads(POST_ID: str): if POST_ID: # would only be called if there are multiple queued posts submission = reddit.submission(id=POST_ID) - elif ( - settings.config["reddit"]["thread"]["post_id"] - and len(settings.config["reddit"]["thread"]["post_id"].split("+")) == 1 - ): + elif (settings.config["reddit"]["thread"]["post_id"] + and len(settings.config["reddit"]["thread"]["post_id"].split("+")) == 1): submission = reddit.submission(id=settings.config["reddit"]["thread"]["post_id"]) comment_type = settings.config["reddit"]["thread"]["sort"] diff --git a/video_creation/final_video.py b/video_creation/final_video.py index f1e1f96..7853014 100755 --- a/video_creation/final_video.py +++ b/video_creation/final_video.py @@ -38,6 +38,8 @@ def name_normalize(name: str) -> str: name = re.sub(r"(\w+)\s?\/\s?(\w+)", r"\1 or \2", name) name = re.sub(r"\/", r"", name) + name = name[0:140] + lang = settings.config["reddit"]["thread"]["post_lang"] if lang: print_substep("Translating filename...")