From 11fdd7eb940e5a27a994c71eba2a73a9e6e7e23c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 2 Jan 2023 20:11:29 +0100 Subject: [PATCH 01/16] Update pillow requirement from ~=9.3.0 to ~=9.4.0 (#1421) Updates the requirements on [pillow](https://github.com/python-pillow/Pillow) to permit the latest version. - [Release notes](https://github.com/python-pillow/Pillow/releases) - [Changelog](https://github.com/python-pillow/Pillow/blob/main/CHANGES.rst) - [Commits](https://github.com/python-pillow/Pillow/compare/9.3.0...9.4.0) --- updated-dependencies: - dependency-name: pillow dependency-type: direct:production ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Simon <65854503+OpenSourceSimon@users.noreply.github.com> --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 3382509..a9564c0 100644 --- a/requirements.txt +++ b/requirements.txt @@ -11,7 +11,7 @@ rich==12.5.1 toml==0.10.2 translators==5.3.1 pyttsx3==2.90 -Pillow~=9.3.0 +Pillow~=9.4.0 tomlkit==0.11.4 Flask==2.2.2 clean-text==0.6.0 From f2e8e67a787c1cec604dd582e5a83e11345c3035 Mon Sep 17 00:00:00 2001 From: Xpl0itU Date: Mon, 2 Jan 2023 20:16:35 +0100 Subject: [PATCH 02/16] Fix path (#1410) --- utils/imagenarator.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/utils/imagenarator.py b/utils/imagenarator.py index ac53d82..8c6dc58 100644 --- a/utils/imagenarator.py +++ b/utils/imagenarator.py @@ -1,5 +1,6 @@ import re import textwrap +import os from PIL import Image, ImageDraw, ImageFont from rich.progress import track @@ -31,9 +32,9 @@ def imagemaker(theme, reddit_obj: dict, txtclr, padding=5): texts = reddit_obj["thread_post"] id = re.sub(r"[^\w\s-]", "", reddit_obj["thread_id"]) - tfont = ImageFont.truetype("fonts\\Roboto-Bold.ttf", 27) # for title + tfont = ImageFont.truetype(os.path.join("fonts", "Roboto-Bold.ttf"), 27) # for title font = ImageFont.truetype( - "fonts\\Roboto-Regular.ttf", 20 + os.path.join("fonts", "Roboto-Regular.ttf"), 20 ) # for despcription|comments size = (500, 176) From ee6363cd1e987e172c7b4faa19e34c1f54e6b37a Mon Sep 17 00:00:00 2001 From: John Toniutti Date: Mon, 2 Jan 2023 20:46:44 +0100 Subject: [PATCH 03/16] Fix and improve TikTok TTS (#1271) * feat: tiktok sessionId can be specified in the config.toml * feat: tiktok sessionId can be specified in the config.toml * Various improvements and optimizations * Add default argument * Remove an used variable * Code reformatted with black * Fixed all problems pointed out by pylint * Update TTS/TikTok.py * Apply suggestions from code review Co-authored-by: Simon <65854503+OpenSourceSimon@users.noreply.github.com> * chore: add default value for tiktok_voice Co-authored-by: Jose Collado Co-authored-by: Simon <65854503+OpenSourceSimon@users.noreply.github.com> Co-authored-by: Callum Leslie Co-authored-by: Callum Leslie --- GUI/settings.html | 13 +++ TTS/TikTok.py | 163 ++++++++++++++++++++++++------------ utils/.config.template.toml | 13 +-- 3 files changed, 128 insertions(+), 61 deletions(-) diff --git a/GUI/settings.html b/GUI/settings.html index 9013600..1f0ef2e 100644 --- a/GUI/settings.html +++ b/GUI/settings.html @@ -369,6 +369,19 @@ +
+ +
+
+
+ +
+ +
+
+
diff --git a/TTS/TikTok.py b/TTS/TikTok.py index a0f8993..543568f 100644 --- a/TTS/TikTok.py +++ b/TTS/TikTok.py @@ -1,26 +1,28 @@ +# documentation for tiktok api: https://github.com/oscie57/tiktok-voice/wiki import base64 import random +import time +from typing import Optional, Final import requests -from requests.adapters import HTTPAdapter, Retry from utils import settings -# from profanity_filter import ProfanityFilter -# pf = ProfanityFilter() -# Code by @JasonLovesDoggo -# https://twitter.com/scanlime/status/1512598559769702406 +__all__ = ["TikTok", "TikTokTTSException"] -nonhuman = [ # DISNEY VOICES +disney_voices: Final[tuple] = ( "en_us_ghostface", # Ghost Face "en_us_chewbacca", # Chewbacca "en_us_c3po", # C3PO "en_us_stitch", # Stitch "en_us_stormtrooper", # Stormtrooper "en_us_rocket", # Rocket - # ENGLISH VOICES -] -human = [ + "en_female_madam_leota", # Madame Leota + "en_male_ghosthost", # Ghost Host + "en_male_pirate", # pirate +) + +eng_voices: Final[tuple] = ( "en_au_001", # English AU - Female "en_au_002", # English AU - Male "en_uk_001", # English UK - Male 1 @@ -30,23 +32,28 @@ human = [ "en_us_006", # English US - Male 1 "en_us_007", # English US - Male 2 "en_us_009", # English US - Male 3 - "en_us_010", -] -voices = nonhuman + human + "en_us_010", # English US - Male 4 + "en_male_narration", # Narrator + "en_male_funny", # Funny + "en_female_emotional", # Peaceful + "en_male_cody", # Serious +) -noneng = [ +non_eng_voices: Final[tuple] = ( + # Western European voices "fr_001", # French - Male 1 "fr_002", # French - Male 2 "de_001", # German - Female "de_002", # German - Male "es_002", # Spanish - Male - # AMERICA VOICES + "it_male_m18" # Italian - Male + # South american voices "es_mx_002", # Spanish MX - Male "br_001", # Portuguese BR - Female 1 "br_003", # Portuguese BR - Female 2 "br_004", # Portuguese BR - Female 3 "br_005", # Portuguese BR - Male - # ASIA VOICES + # asian voices "id_001", # Indonesian - Female "jp_001", # Japanese - Female 1 "jp_003", # Japanese - Female 2 @@ -55,51 +62,97 @@ noneng = [ "kr_002", # Korean - Male 1 "kr_003", # Korean - Female "kr_004", # Korean - Male 2 -] - +) -# good_voices = {'good': ['en_us_002', 'en_us_006'], -# 'ok': ['en_au_002', 'en_uk_001']} # less en_us_stormtrooper more less en_us_rocket en_us_ghostface +vocals: Final[tuple] = ( + "en_female_f08_salut_damour", # Alto + "en_male_m03_lobby", # Tenor + "en_male_m03_sunshine_soon", # Sunshine Soon + "en_female_f08_warmy_breeze", # Warmy Breeze + "en_female_ht_f08_glorious", # Glorious + "en_male_sing_funny_it_goes_up", # It Goes Up + "en_male_m2_xhxs_m03_silly", # Chipmunk + "en_female_ht_f08_wonderful_world", # Dramatic +) -class TikTok: # TikTok Text-to-Speech Wrapper +class TikTok: + """TikTok Text-to-Speech Wrapper""" def __init__(self): - self.URI_BASE = "https://api16-normal-useast5.us.tiktokv.com/media/api/text/speech/invoke/?text_speaker=" + headers = { + "User-Agent": "com.zhiliaoapp.musically/2022600030 (Linux; U; Android 7.1.2; es_ES; SM-G988N; " + "Build/NRD90M;tt-ok/3.12.13.1)", + "Cookie": f"sessionid={settings.config['settings']['tts']['tiktok_sessionid']}", + } + + self.URI_BASE = "https://api16-normal-c-useast1a.tiktokv.com/media/api/text/speech/invoke/" self.max_chars = 300 - self.voices = {"human": human, "nonhuman": nonhuman, "noneng": noneng} - - def run(self, text, filepath, random_voice: bool = False): - # if censor: - # req_text = pf.censor(req_text) - # pass - voice = ( - self.randomvoice() - if random_voice - else ( - settings.config["settings"]["tts"]["tiktok_voice"] - or random.choice(self.voices["human"]) - ) - ) - try: - r = requests.post( - f"{self.URI_BASE}{voice}&req_text={text}&speaker_map_type=0" - ) - except requests.exceptions.SSLError: - # https://stackoverflow.com/a/47475019/18516611 - session = requests.Session() - retry = Retry(connect=3, backoff_factor=0.5) - adapter = HTTPAdapter(max_retries=retry) - session.mount("http://", adapter) - session.mount("https://", adapter) - r = session.post( - f"{self.URI_BASE}{voice}&req_text={text}&speaker_map_type=0" - ) - # print(r.text) - vstr = [r.json()["data"]["v_str"]][0] - b64d = base64.b64decode(vstr) + self._session = requests.Session() + # set the headers to the session, so we don't have to do it for every request + self._session.headers = headers + + def run(self, text: str, filepath: str, random_voice: bool = False): + if random_voice: + voice = self.random_voice() + else: + # if tiktok_voice is not set in the config file, then use a random voice + voice = settings.config["settings"]["tts"].get("tiktok_voice", None) + + # get the audio from the TikTok API + data = self.get_voices(voice=voice, text=text) + + # check if there was an error in the request + status_code = data["status_code"] + if status_code != 0: + raise TikTokTTSException(status_code, data["message"]) + + # decode data from base64 to binary + raw_voices = data["data"]["v_str"] + decoded_voices = base64.b64decode(raw_voices) + + # write voices to specified filepath with open(filepath, "wb") as out: - out.write(b64d) + out.write(decoded_voices) + + def get_voices(self, text: str, voice: Optional[str] = None) -> dict: + """If voice is not passed, the API will try to use the most fitting voice""" + # sanitize text + text = text.replace("+", "plus").replace("&", "and").replace("r/", "") + + # prepare url request + params = {"req_text": text, "speaker_map_type": 0, "aid": 1233} + + if voice is not None: + params["text_speaker"] = voice + + # send request + try: + response = self._session.post(self.URI_BASE, params=params) + except ConnectionError: + time.sleep(random.randrange(1, 7)) + response = self._session.post(self.URI_BASE, params=params) + + return response.json() + + @staticmethod + def random_voice(): + return random.choice(eng_voices) + + +class TikTokTTSException(Exception): + def __init__(self, code: int, message: str): + self._code = code + self._message = message + + def __str__(self) -> str: + if self._code == 1: + return f"Code: {self._code}, reason: probably the aid value isn't correct, message: {self._message}" + + if self._code == 2: + return f"Code: {self._code}, reason: the text is too long, message: {self._message}" + + if self._code == 4: + return f"Code: {self._code}, reason: the speaker doesn't exist, message: {self._message}" - def randomvoice(self): - return random.choice(self.voices["human"]) + return f"Code: {self._message}, reason: unknown, message: {self._message}" diff --git a/utils/.config.template.toml b/utils/.config.template.toml index 25b5797..ec5bb2a 100644 --- a/utils/.config.template.toml +++ b/utils/.config.template.toml @@ -43,11 +43,12 @@ 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 = "googletranslate", 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 = true, default = "Matthew", example = "Matthew", explanation = "The voice used for AWS Polly" } -streamlabs_polly_voice = { optional = true, default = "Matthew", example = "Matthew", explanation = "The voice used for Streamlabs Polly" } -tiktok_voice = { optional = true, default = "en_us_006", example = "en_us_006", explanation = "The voice used for TikTok TTS" } -python_voice = { optional = true, 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 = true, default = "2", example = "2", explanation = "The number of system voices (2 are pre-installed in Windows)" } +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." } +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." } +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" } no_emojis = { optional = false, type = "bool", default = false, example = false, options = [true, false,], explanation = "Whether to remove emojis from the comments" } \ No newline at end of file From 8e5b7a935dfeead3aa8f443eb0c4e968ad69069c Mon Sep 17 00:00:00 2001 From: Simon Date: Mon, 2 Jan 2023 21:01:28 +0100 Subject: [PATCH 04/16] Fix for path at background.py and added TikTok error message just in case --- TTS/TikTok.py | 6 +++++- video_creation/background.py | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/TTS/TikTok.py b/TTS/TikTok.py index 543568f..b370455 100644 --- a/TTS/TikTok.py +++ b/TTS/TikTok.py @@ -108,7 +108,11 @@ class TikTok: raise TikTokTTSException(status_code, data["message"]) # decode data from base64 to binary - raw_voices = data["data"]["v_str"] + try: + raw_voices = data["data"]["v_str"] + except: + print("The TikTok TTS returned an invalid response. Please try again later, and report this bug.") + raise TikTokTTSException(0, "Invalid response") decoded_voices = base64.b64decode(raw_voices) # write voices to specified filepath diff --git a/video_creation/background.py b/video_creation/background.py index 0405e66..0458ce6 100644 --- a/video_creation/background.py +++ b/video_creation/background.py @@ -13,7 +13,7 @@ from utils import settings from utils.console import print_step, print_substep # Load background videos -with open("utils/backgrounds.json") as json_file: +with open("./utils/backgrounds.json") as json_file: background_options = json.load(json_file) # Remove "__comment" from backgrounds From 28af1ab5acc5aadb9be3e692efb9a468b2a310ef Mon Sep 17 00:00:00 2001 From: Simon Date: Tue, 3 Jan 2023 11:01:03 +0100 Subject: [PATCH 05/16] Version 3.0 is finally here! --- main.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/main.py b/main.py index bb479d5..dcb1861 100755 --- a/main.py +++ b/main.py @@ -23,7 +23,7 @@ from video_creation.final_video import make_final_video from video_creation.screenshot_downloader import get_screenshots_of_reddit_posts from video_creation.voices import save_text_to_mp3 -__VERSION__ = "2.5.0" +__VERSION__ = "3.0" print( """ @@ -109,7 +109,7 @@ if __name__ == "__main__": shutdown() except Exception as err: print_step(f''' - Sorry, something went wrong with this test version! Try again, and feel free to report this issue at GitHub or the Discord community.\n + Sorry, something went wrong with this version! Try again, and feel free to report this issue at GitHub or the Discord community.\n Version: {__VERSION__} \n Story mode: {str(config["settings"]["storymode"])} \n Story mode method: {str(config["settings"]["storymodemethod"])} From 6fe9caaece151a1382033843f417bb9876157917 Mon Sep 17 00:00:00 2001 From: Simon Date: Tue, 3 Jan 2023 12:10:15 +0100 Subject: [PATCH 06/16] Version 3.0 is finally here! --- video_creation/final_video.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/video_creation/final_video.py b/video_creation/final_video.py index 5d9b74f..ad5ff95 100755 --- a/video_creation/final_video.py +++ b/video_creation/final_video.py @@ -269,7 +269,7 @@ def make_final_video( audio_bitrate="192k", verbose=False, threads=multiprocessing.cpu_count(), - preset="ultrafast", #TODO debug + #preset="ultrafast", # for testing purposes ) ffmpeg_extract_subclip( f"assets/temp/{reddit_id}/temp.mp4", From 521926213db7356f1520ada21cfc681ea97a6800 Mon Sep 17 00:00:00 2001 From: Simon <65854503+OpenSourceSimon@users.noreply.github.com> Date: Tue, 3 Jan 2023 16:33:29 +0100 Subject: [PATCH 07/16] Update utils/gui_utils.py Co-authored-by: Callum Leslie --- utils/gui_utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/utils/gui_utils.py b/utils/gui_utils.py index b539ff7..9d644d8 100644 --- a/utils/gui_utils.py +++ b/utils/gui_utils.py @@ -162,7 +162,7 @@ def delete_background(key): # Add background video def add_background(youtube_uri, filename, citation, position): # Validate YouTube URI - regex = re.compile(r"(?:\/|%3D|v=|vi=)([0-9A-z-_]{11})(?:[%#?&]|$)").search( + regex = re.compile(r"(?:\/|%3D|v=|vi=)([0-9A-z\-_]{11})(?:[%#?&]|$)").search( youtube_uri ) From 576e208eb7908be264766c2d598aa66392088e84 Mon Sep 17 00:00:00 2001 From: Simon <65854503+OpenSourceSimon@users.noreply.github.com> Date: Tue, 3 Jan 2023 20:13:24 +0100 Subject: [PATCH 08/16] Update README Add electro199 to developers and added fonts license --- README.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/README.md b/README.md index 4997d3f..f381452 100644 --- a/README.md +++ b/README.md @@ -81,6 +81,8 @@ I have tried to simplify the code so anyone can read it and start contributing a Please read our [contributing guidelines](CONTRIBUTING.md) for more detailed information. +### For any questions or support join the [Discord](https://discord.com/channels/897666935708352582/) server + ## Developers and maintainers. Elebumm (Lewis#6305) - https://github.com/elebumm (Founder) @@ -96,3 +98,9 @@ Verq (Verq#2338) - https://github.com/CordlessCoder LukaHietala (Pix.#0001) - https://github.com/LukaHietala Freebiell (Freebie#3263) - https://github.com/FreebieII + +Aman Raza (electro199#8130) - https://github.com/electro199 + + +## LICENSE +[Roboto Fonts](https://fonts.google.com/specimen/Roboto/about) are licensed under [Apache License V2](https://www.apache.org/licenses/LICENSE-2.0) From 671449caad1e5243c1e4081211b66219f4e04f18 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 30 Jan 2023 10:19:58 +0000 Subject: [PATCH 09/16] Bump rich from 12.5.1 to 13.3.1 Bumps [rich](https://github.com/Textualize/rich) from 12.5.1 to 13.3.1. - [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/v12.5.1...v13.3.1) --- updated-dependencies: - dependency-name: rich dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index a9564c0..6cf4689 100644 --- a/requirements.txt +++ b/requirements.txt @@ -7,7 +7,7 @@ praw==7.6.1 prawcore~=2.3.0 pytube==12.1.0 requests==2.28.1 -rich==12.5.1 +rich==13.3.1 toml==0.10.2 translators==5.3.1 pyttsx3==2.90 From 1f8ebf5eeb3e5bed07c6a0727bf67c5bca050e76 Mon Sep 17 00:00:00 2001 From: electro199 Date: Thu, 2 Feb 2023 15:56:59 +0500 Subject: [PATCH 10/16] Fixed Timeout error and improved return hinting --- TTS/TikTok.py | 7 ++++++- utils/imagenarator.py | 4 ++-- utils/voice.py | 4 ++-- video_creation/screenshot_downloader.py | 15 +++++++++++++-- 4 files changed, 23 insertions(+), 7 deletions(-) diff --git a/TTS/TikTok.py b/TTS/TikTok.py index b370455..ed21a78 100644 --- a/TTS/TikTok.py +++ b/TTS/TikTok.py @@ -79,6 +79,8 @@ vocals: Final[tuple] = ( class TikTok: """TikTok Text-to-Speech Wrapper""" def __init__(self): + if not settings.config['settings']['tts']['tiktok_sessionid']: + raise TikTokTTSException(5) headers = { "User-Agent": "com.zhiliaoapp.musically/2022600030 (Linux; U; Android 7.1.2; es_ES; SM-G988N; " "Build/NRD90M;tt-ok/3.12.13.1)", @@ -140,7 +142,7 @@ class TikTok: return response.json() @staticmethod - def random_voice(): + def random_voice() -> str: return random.choice(eng_voices) @@ -158,5 +160,8 @@ class TikTokTTSException(Exception): if self._code == 4: return f"Code: {self._code}, reason: the speaker doesn't exist, message: {self._message}" + + if self._code == 5: + return f"Would you mind add session id in config ??" return f"Code: {self._message}, reason: unknown, message: {self._message}" diff --git a/utils/imagenarator.py b/utils/imagenarator.py index 8c6dc58..8e3789e 100644 --- a/utils/imagenarator.py +++ b/utils/imagenarator.py @@ -6,7 +6,7 @@ from PIL import Image, ImageDraw, ImageFont from rich.progress import track from TTS.engine_wrapper import process_text -def draw_multiple_line_text(image, text, font, text_color, padding, wrap=50): +def draw_multiple_line_text(image, text, font, text_color, padding, wrap=50) -> None: """ Draw multiline text over given image """ @@ -24,7 +24,7 @@ def draw_multiple_line_text(image, text, font, text_color, padding, wrap=50): # theme=bgcolor,reddit_obj=reddit_object,txtclr=txtcolor -def imagemaker(theme, reddit_obj: dict, txtclr, padding=5): +def imagemaker(theme, reddit_obj: dict, txtclr, padding=5) -> None: """ Render Images for video """ diff --git a/utils/voice.py b/utils/voice.py index a88c87d..76efc20 100644 --- a/utils/voice.py +++ b/utils/voice.py @@ -13,7 +13,7 @@ if sys.version_info[0] >= 3: from datetime import timezone -def check_ratelimit(response: Response): +def check_ratelimit(response: Response) -> bool: """ Checks if the response is a ratelimit response. If it is, it sleeps for the time specified in the response. @@ -30,7 +30,7 @@ def check_ratelimit(response: Response): return True -def sleep_until(time): +def sleep_until(time) -> None: """ Pause your program until a specific end time. 'time' is either a valid datetime object or unix timestamp in seconds (i.e. seconds since Unix epoch) diff --git a/video_creation/screenshot_downloader.py b/video_creation/screenshot_downloader.py index 3a76b5b..8e537d1 100644 --- a/video_creation/screenshot_downloader.py +++ b/video_creation/screenshot_downloader.py @@ -11,6 +11,7 @@ from rich.progress import track from utils import settings from utils.console import print_step, print_substep from utils.imagenarator import imagemaker +from utils.videos import save_data __all__ = ["download_screenshots_of_reddit_posts"] @@ -105,8 +106,18 @@ def get_screenshots_of_reddit_posts(reddit_object: dict, screenshot_num: int): print_substep("Skipping translation...") postcontentpath = f"assets/temp/{reddit_id}/png/title.png" - page.locator('[data-test-id="post-content"]').screenshot(path=postcontentpath) - + try : + page.locator('[data-test-id="post-content"]').screenshot(path=postcontentpath) + + except TimeoutError as e: + print_step("unable to locate post It is possibly Due to a NSFW post or unstable internet") + resp = input("Do you want to skip the post?(y/n)") + if resp.startswith("y"): + save_data("","","skiped",reddit_id,"") + print("Now you can re run the program this post will skipped") + exit() + raise e + if storymode: page.locator('[data-click-id="text"]').first.screenshot( path=f"assets/temp/{reddit_id}/png/story_content.png" From e6e27f32407a8d8dcb3b05034a91f5b6dc5c4f6b Mon Sep 17 00:00:00 2001 From: electro199 Date: Thu, 2 Feb 2023 16:01:55 +0500 Subject: [PATCH 11/16] changed TikTokTTSException msg --- TTS/TikTok.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/TTS/TikTok.py b/TTS/TikTok.py index ed21a78..2bcbd6d 100644 --- a/TTS/TikTok.py +++ b/TTS/TikTok.py @@ -162,6 +162,6 @@ class TikTokTTSException(Exception): return f"Code: {self._code}, reason: the speaker doesn't exist, message: {self._message}" if self._code == 5: - return f"Would you mind add session id in config ??" + return f"You have to add session id in config to use titok TTS" return f"Code: {self._message}, reason: unknown, message: {self._message}" From c0916c13bb93612d2752737ded9eebad55d9acb7 Mon Sep 17 00:00:00 2001 From: electro199 Date: Thu, 2 Feb 2023 17:03:51 +0500 Subject: [PATCH 12/16] Add nsfw flag & improved error handling --- reddit/subreddit.py | 1 + video_creation/screenshot_downloader.py | 19 ++++++++++++------- 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/reddit/subreddit.py b/reddit/subreddit.py index 8fb9e9d..ed1e8cf 100644 --- a/reddit/subreddit.py +++ b/reddit/subreddit.py @@ -134,6 +134,7 @@ def get_subreddit_threads(POST_ID: str): content["thread_url"] = threadurl content["thread_title"] = submission.title content["thread_id"] = submission.id + content["is_nsfw"] = submission.over_18 content["comments"] = [] if settings.config["settings"]["storymode"]: if settings.config["settings"]["storymodemethod"] == 1: diff --git a/video_creation/screenshot_downloader.py b/video_creation/screenshot_downloader.py index 8e537d1..f7fe7db 100644 --- a/video_creation/screenshot_downloader.py +++ b/video_creation/screenshot_downloader.py @@ -110,13 +110,18 @@ def get_screenshots_of_reddit_posts(reddit_object: dict, screenshot_num: int): page.locator('[data-test-id="post-content"]').screenshot(path=postcontentpath) except TimeoutError as e: - print_step("unable to locate post It is possibly Due to a NSFW post or unstable internet") - resp = input("Do you want to skip the post?(y/n)") - if resp.startswith("y"): - save_data("","","skiped",reddit_id,"") - print("Now you can re run the program this post will skipped") - exit() - raise e + if settings.config["is_nsfw"] : + print_step("Unable to get post It is due to a NSFW post") + resp = input("Do you want to skip the post?(y/n)") + if resp.casefold().startswith("y"): + save_data("","","skiped",reddit_id,"") + print("Now you can re run the program this post will skipped") + exit() + else: + raise e + + + if storymode: page.locator('[data-click-id="text"]').first.screenshot( From bb06afa56d0511d7e4cd9ecb1e91fdfb0328ff2e Mon Sep 17 00:00:00 2001 From: Simon Date: Thu, 2 Feb 2023 15:22:30 +0100 Subject: [PATCH 13/16] Fix for NSFW --- video_creation/screenshot_downloader.py | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/video_creation/screenshot_downloader.py b/video_creation/screenshot_downloader.py index 3a76b5b..5d608b2 100644 --- a/video_creation/screenshot_downloader.py +++ b/video_creation/screenshot_downloader.py @@ -4,7 +4,6 @@ from pathlib import Path from typing import Dict, Final import translators as ts -from playwright.async_api import async_playwright # pylint: disable=unused-import from playwright.sync_api import ViewportSize, sync_playwright from rich.progress import track @@ -12,9 +11,9 @@ from utils import settings from utils.console import print_step, print_substep from utils.imagenarator import imagemaker - __all__ = ["download_screenshots_of_reddit_posts"] + def get_screenshots_of_reddit_posts(reddit_object: dict, screenshot_num: int): """Downloads screenshots of reddit posts as seen on the web. Downloads to assets/temp/png @@ -37,7 +36,7 @@ def get_screenshots_of_reddit_posts(reddit_object: dict, screenshot_num: int): with sync_playwright() as p: print_substep("Launching Headless Browser...") - browser = p.chromium.launch() # headless=False #to check for chrome view + browser = p.chromium.launch(headless=False) # headless=False #to check for chrome view context = browser.new_context() # Device scale factor (or dsf for short) allows us to increase the resolution of the screenshots # When the dsf is 1, the width of the screenshot is 600 pixels @@ -71,6 +70,20 @@ def get_screenshots_of_reddit_posts(reddit_object: dict, screenshot_num: int): context.add_cookies(cookies) # load preference cookies + # Login to Reddit + print_substep("Logging in to Reddit...") + page = context.new_page() + page.goto("https://www.reddit.com/login", timeout=0) + page.set_viewport_size(ViewportSize(width=1920, height=1080)) + page.wait_for_load_state() + + page.locator('[name="username"]').fill(settings.config["reddit"]["creds"]["username"]) + page.locator('[name="password"]').fill(settings.config["reddit"]["creds"]["password"]) + page.locator("button:has-text('Log In')").click() + + page.wait_for_load_state() # Wait for page to fully load and add 5 seconds + page.wait_for_timeout(5000) + # Get the thread screenshot page = context.new_page() page.goto(reddit_object["thread_url"], timeout=0) @@ -151,6 +164,4 @@ def get_screenshots_of_reddit_posts(reddit_object: dict, screenshot_num: int): # close browser instance when we are done using it browser.close() - - - print_substep("Screenshots downloaded Successfully.", style="bold green") \ No newline at end of file + print_substep("Screenshots downloaded Successfully.", style="bold green") From 0a383ff93b84a2e999871e703a8c4b3aeecdef93 Mon Sep 17 00:00:00 2001 From: Simon Date: Thu, 2 Feb 2023 15:38:38 +0100 Subject: [PATCH 14/16] Improved error-handeling --- video_creation/screenshot_downloader.py | 38 ++++++++++++------------- 1 file changed, 18 insertions(+), 20 deletions(-) diff --git a/video_creation/screenshot_downloader.py b/video_creation/screenshot_downloader.py index f7fe7db..2be93b4 100644 --- a/video_creation/screenshot_downloader.py +++ b/video_creation/screenshot_downloader.py @@ -4,7 +4,6 @@ from pathlib import Path from typing import Dict, Final import translators as ts -from playwright.async_api import async_playwright # pylint: disable=unused-import from playwright.sync_api import ViewportSize, sync_playwright from rich.progress import track @@ -13,9 +12,9 @@ from utils.console import print_step, print_substep from utils.imagenarator import imagemaker from utils.videos import save_data - __all__ = ["download_screenshots_of_reddit_posts"] + def get_screenshots_of_reddit_posts(reddit_object: dict, screenshot_num: int): """Downloads screenshots of reddit posts as seen on the web. Downloads to assets/temp/png @@ -106,23 +105,24 @@ def get_screenshots_of_reddit_posts(reddit_object: dict, screenshot_num: int): print_substep("Skipping translation...") postcontentpath = f"assets/temp/{reddit_id}/png/title.png" - try : + try: page.locator('[data-test-id="post-content"]').screenshot(path=postcontentpath) - - except TimeoutError as e: - if settings.config["is_nsfw"] : - print_step("Unable to get post It is due to a NSFW post") - resp = input("Do you want to skip the post?(y/n)") - if resp.casefold().startswith("y"): - save_data("","","skiped",reddit_id,"") - print("Now you can re run the program this post will skipped") - exit() + except Exception as e: + OKGREEN = '\033[92m' + WARNING = '\033[93m' + ENDC = '\033[0m' + print_step(f"{WARNING}Something went wrong!{ENDC}") + resp = input("Something went wrong with making the screenshots! Do you want to skip the post? (y/n) ") + if resp.casefold().startswith("y"): + save_data("", "", "skipped", reddit_id, "") + print(f"{OKGREEN}The post is successfully skipped! You can now restart the program and this post will skipped.{ENDC}") + resp = input("Do you want the error traceback for debugging purposes? (y/n)") + if resp.casefold().startswith("y"): + print(e) + exit() else: - raise e - - - - + exit() + if storymode: page.locator('[data-click-id="text"]').first.screenshot( path=f"assets/temp/{reddit_id}/png/story_content.png" @@ -167,6 +167,4 @@ def get_screenshots_of_reddit_posts(reddit_object: dict, screenshot_num: int): # close browser instance when we are done using it browser.close() - - - print_substep("Screenshots downloaded Successfully.", style="bold green") \ No newline at end of file + print_substep("Screenshots downloaded Successfully.", style="bold green") From 25ce2af3508894e42196ee93cf96575be44b865b Mon Sep 17 00:00:00 2001 From: Simon Date: Thu, 2 Feb 2023 15:51:43 +0100 Subject: [PATCH 15/16] Fix backgrounds bug --- utils/backgrounds.json | 8 ++++---- video_creation/screenshot_downloader.py | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/utils/backgrounds.json b/utils/backgrounds.json index 8cb01d1..6e00992 100644 --- a/utils/backgrounds.json +++ b/utils/backgrounds.json @@ -4,13 +4,13 @@ "https://www.youtube.com/watch?v=vw5L4xCPy9Q", "bike-parkour-gta.mp4", "Achy Gaming", - 480 + "center" ], "rocket-league": [ "https://www.youtube.com/watch?v=2X9QGY__0II", "rocket_league.mp4", "Orbital Gameplay", - 200 + "center" ], "minecraft": [ "https://www.youtube.com/watch?v=n_Dv4JMiwK8", @@ -22,7 +22,7 @@ "https://www.youtube.com/watch?v=qGa9kWREOnE", "gta-stunt-race.mp4", "Achy Gaming", - 480 + "center" ], "csgo-surf": [ "https://www.youtube.com/watch?v=E-8JlyO59Io", @@ -34,7 +34,7 @@ "https://www.youtube.com/watch?v=uVKxtdMgJVU", "cluster_truck.mp4", "No Copyright Gameplay", - 480 + "center" ], "minecraft-2": [ "https://www.youtube.com/watch?v=Pt5_GSKIWQM", diff --git a/video_creation/screenshot_downloader.py b/video_creation/screenshot_downloader.py index d3fbf17..71bfb70 100644 --- a/video_creation/screenshot_downloader.py +++ b/video_creation/screenshot_downloader.py @@ -38,7 +38,7 @@ def get_screenshots_of_reddit_posts(reddit_object: dict, screenshot_num: int): with sync_playwright() as p: print_substep("Launching Headless Browser...") - browser = p.chromium.launch(headless=False) # headless=False #to check for chrome view + browser = p.chromium.launch() # headless=False for debugging context = browser.new_context() # Device scale factor (or dsf for short) allows us to increase the resolution of the screenshots # When the dsf is 1, the width of the screenshot is 600 pixels From 6d177d36b74a15538a9c9560a5a70df65aa5234e Mon Sep 17 00:00:00 2001 From: Simon <65854503+OpenSourceSimon@users.noreply.github.com> Date: Thu, 2 Feb 2023 16:24:54 +0100 Subject: [PATCH 16/16] Version 3.0.1 includes a couple of bug fixes --- main.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main.py b/main.py index dcb1861..7e4d1b9 100755 --- a/main.py +++ b/main.py @@ -23,7 +23,7 @@ from video_creation.final_video import make_final_video from video_creation.screenshot_downloader import get_screenshots_of_reddit_posts from video_creation.voices import save_text_to_mp3 -__VERSION__ = "3.0" +__VERSION__ = "3.0.1" print( """