diff --git a/.env.template b/.env.template index d9a7f2f..25b5bd8 100644 --- a/.env.template +++ b/.env.template @@ -1,3 +1,4 @@ + REDDIT_CLIENT_ID="" #fFAGRNJru1FTz70BzhT3Zg #EXPLANATION the ID of your Reddit app of SCRIPT type #RANGE 12:30 @@ -62,12 +63,18 @@ OPACITY="1" #.8 #MATCH_TYPE float #OOB_ERROR The opacity HAS to be between 0 and 1 +# If you want to translate the comments to another language, set the language code here. +# If empty, no translation will be done. +POSTLANG="" +#EXPLANATION Activates the translation feature, set the language code gor translate or leave blank + # see different voice options: todo: add docs -VOICE="Matthew" #en_us_002 +VOICE="Matthew" # e.g. en_us_002 #EXPLANATION sets the voice the TTS uses TTSCHOICE="" #EXPLANATION the backend used for TTS. Without anything specified, the user will be prompted to choose one. +# IMPORTANT NOTE: if you use translate, you need to set this gtts or set tiktok and use custom voice in your language STREAMLABS_VOICE="Joanna" #EXPLANATION Sets the voice for the Streamlabs Polly TTS Engine. Check the file for more information on different voices. diff --git a/TTS/GTTS.py b/TTS/GTTS.py index a0df172..992eeb5 100644 --- a/TTS/GTTS.py +++ b/TTS/GTTS.py @@ -1,5 +1,6 @@ #!/usr/bin/env python3 import random +import os from gtts import gTTS max_chars = 0 @@ -11,7 +12,7 @@ class GTTS: self.voices = [] def run(self, text, filepath): - tts = gTTS(text=text, lang="en", slow=False) + tts = gTTS(text=text, lang=os.getenv("POSTLANG") or "en", slow=False) tts.save(filepath) def randomvoice(self): diff --git a/TTS/engine_wrapper.py b/TTS/engine_wrapper.py index 5e4ddb0..2a560b0 100644 --- a/TTS/engine_wrapper.py +++ b/TTS/engine_wrapper.py @@ -4,6 +4,7 @@ from typing import Tuple import re from os import getenv from mutagen.mp3 import MP3 +import translators as ts from rich.progress import track from moviepy.editor import AudioFileClip, CompositeAudioClip, concatenate_audioclips from utils.console import print_step, print_substep @@ -54,7 +55,7 @@ class TTSEngine: self.reddit_object["thread_post"] != "" and getenv("STORYMODE", "").casefold() == "true" ): - self.call_tts("posttext", sanitize_text(self.reddit_object["thread_post"])) + self.call_tts("posttext", self.reddit_object["thread_post"]) idx = None for idx, comment in track( @@ -64,9 +65,9 @@ class TTSEngine: if self.length > self.max_length: break if not self.tts_module.max_chars: - self.call_tts(f"{idx}", sanitize_text(comment["comment_body"])) + self.call_tts(f"{idx}", comment["comment_body"]) else: - self.split_post(sanitize_text(comment["comment_body"]), idx) + self.split_post(comment["comment_body"], idx) print_substep("Saved Text to MP3 files successfully.", style="bold green") return self.length, idx @@ -94,5 +95,16 @@ class TTSEngine: Path(f"{self.path}/{idx}-{i}.part.mp3").unlink() def call_tts(self, filename: str, text: str): - self.tts_module.run(text=text, filepath=f"{self.path}/{filename}.mp3") + self.tts_module.run( + text=process_text(text), filepath=f"{self.path}/{filename}.mp3" + ) self.length += MP3(f"{self.path}/{filename}.mp3").info.length + + +def process_text(text: str): + lang = getenv("POSTLANG", "") + new_text = sanitize_text(text) + if lang: + print_substep("Translating Text...") + new_text = ts.google(text, to_language=lang) + return new_text diff --git a/requirements.txt b/requirements.txt index c2336e7..42c5d76 100644 --- a/requirements.txt +++ b/requirements.txt @@ -9,3 +9,4 @@ python-dotenv==0.20.0 pytube==12.1.0 requests==2.28.0 rich==12.4.4 +translators==5.2.2 diff --git a/video_creation/screenshot_downloader.py b/video_creation/screenshot_downloader.py index 6147dff..469daf4 100644 --- a/video_creation/screenshot_downloader.py +++ b/video_creation/screenshot_downloader.py @@ -1,5 +1,6 @@ import json from os import getenv +import os from pathlib import Path from playwright.async_api import async_playwright @@ -10,6 +11,8 @@ from utils.console import print_step, print_substep import json from rich.console import Console +import translators as ts + console = Console() storymode = False @@ -18,8 +21,8 @@ storymode = False def download_screenshots_of_reddit_posts(reddit_object, screenshot_num): """Downloads screenshots of reddit posts as they are seen on the web. Args: - reddit_object: The Reddit Object you received in askreddit.py - screenshot_num: The number of screenshots you want to download. + reddit_object: The Reddit Object you received in askreddit.py + screenshot_num: The number of screenshots you want to download. """ print_step("Downloading screenshots of reddit posts...") @@ -51,7 +54,22 @@ def download_screenshots_of_reddit_posts(reddit_object, screenshot_num): '[data-click-id="text"] button' ).click() # Remove "Click to see nsfw" Button in Screenshot - page.locator('[data-test-id="post-content"]').screenshot(path="assets/temp/png/title.png") + # translate code + + if getenv("POSTLANG"): + print_substep("Translating post...") + texts_in_tl = ts.google(reddit_object["thread_title"], to_language=os.getenv("POSTLANG")) + + page.evaluate( + 'tl_content => document.querySelector(\'[data-test-id="post-content"] > div:nth-child(3) > div > div\').textContent = tl_content', texts_in_tl + ) + else: + print_substep("Skipping translation...") + + page.locator('[data-test-id="post-content"]').screenshot( + path="assets/temp/png/title.png" + ) + if storymode: page.locator('[data-click-id="text"]').screenshot( path="assets/temp/png/story_content.png" @@ -60,7 +78,6 @@ def download_screenshots_of_reddit_posts(reddit_object, screenshot_num): for idx, comment in track( enumerate(reddit_object["comments"]), "Downloading screenshots..." ): - # Stop if we have reached the screenshot_num if idx >= screenshot_num: break @@ -69,7 +86,17 @@ def download_screenshots_of_reddit_posts(reddit_object, screenshot_num): page.locator('[data-testid="content-gate"] button').click() page.goto(f'https://reddit.com{comment["comment_url"]}', timeout=0) + + # translate code + + if getenv("POSTLANG"): + comment_tl = ts.google(comment["comment_body"], to_language=os.getenv("POSTLANG")) + page.evaluate( + '([tl_content, tl_id]) => document.querySelector(`#t1_${tl_id} > div:nth-child(2) > div > div[data-testid="comment"] > div`).textContent = tl_content', [comment_tl, comment['comment_id']] + ) + page.locator(f"#t1_{comment['comment_id']}").screenshot( path=f"assets/temp/png/comment_{idx}.png" ) + print_substep("Screenshots downloaded Successfully.", style="bold green")