Merge pull request #520 from JasonLovesDoggo/master

TTS REWORK
pull/524/head
Jason 2 years ago committed by GitHub
commit 0757ace454
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -0,0 +1,13 @@
from gtts import gTTS
class GTTS:
def tts(
self,
req_text: str = "Google Text To Speech",
filename: str = "title.mp3",
random_speaker=False,
censer=False,
):
tts = gTTS(text=req_text, lang="en", slow=False)
tts.save(f"{filename}")

@ -65,16 +65,16 @@ noneng = [
# 'ok': ['en_au_002', 'en_uk_001']} # less en_us_stormtrooper more less en_us_rocket en_us_ghostface # 'ok': ['en_au_002', 'en_uk_001']} # less en_us_stormtrooper more less en_us_rocket en_us_ghostface
class TTTTSWrapper: # TikTok Text-to-Speech Wrapper class TikTok: # TikTok Text-to-Speech Wrapper
def __init__(self): def __init__(self):
self.URI_BASE = "https://api16-normal-useast5.us.tiktokv.com/media/api/text/speech/invoke/?text_speaker=" self.URI_BASE = "https://api16-normal-useast5.us.tiktokv.com/media/api/text/speech/invoke/?text_speaker="
def tts( def tts(
self, self,
req_text: str = "TikTok Text To Speech", req_text: str = "TikTok Text To Speech",
filename: str = "title.mp3", filename: str = "title.mp3",
random_speaker: bool = False, random_speaker: bool = False,
censer=False, censer=False,
): ):
req_text = req_text.replace("+", "plus").replace(" ", "+").replace("&", "and") req_text = req_text.replace("+", "plus").replace(" ", "+").replace("&", "and")
if censer: if censer:
@ -92,7 +92,7 @@ class TTTTSWrapper: # TikTok Text-to-Speech Wrapper
audio_clips = [] audio_clips = []
cbn = sox.Combiner() cbn = sox.Combiner()
#cbn.set_input_format(file_type=["mp3" for _ in chunks]) # cbn.set_input_format(file_type=["mp3" for _ in chunks])
chunkId = 0 chunkId = 0
for chunk in chunks: for chunk in chunks:
@ -130,7 +130,7 @@ class TTTTSWrapper: # TikTok Text-to-Speech Wrapper
for clip in audio_clips: for clip in audio_clips:
i = audio_clips.index(clip) # get the index of the clip i = audio_clips.index(clip) # get the index of the clip
audio_clips = ( audio_clips = (
audio_clips[:i] + [AudioFileClip(clip)] + audio_clips[i + 1:] audio_clips[:i] + [AudioFileClip(clip)] + audio_clips[i + 1 :]
) # replace the clip with an AudioFileClip ) # replace the clip with an AudioFileClip
audio_concat = concatenate_audioclips(audio_clips) audio_concat = concatenate_audioclips(audio_clips)
audio_composite = CompositeAudioClip([audio_concat]) audio_composite = CompositeAudioClip([audio_concat])

@ -0,0 +1,20 @@
from os import getenv
from dotenv import load_dotenv
from TTS.GTTS import GTTS
from TTS.TikTok import TikTok
CHOICE_DIR = {"tiktok": TikTok, "gtts": GTTS}
class TTS:
def __new__(cls):
load_dotenv()
CHOICE = getenv("TTsChoice").casefold()
valid_keys = [key.lower() for key in CHOICE_DIR.keys()]
if CHOICE not in valid_keys:
raise ValueError(
f"{CHOICE} is not valid. Please use one of these {valid_keys} options"
)
return CHOICE_DIR.get(CHOICE)()

@ -23,7 +23,7 @@ print(banner)
load_dotenv() load_dotenv()
# Modified by JasonLovesDoggo # Modified by JasonLovesDoggo
print_markdown( print_markdown(
"### Thanks for using this tool! [Feel free to contribute to this project on GitHub!](https://lewismenelaws.com) If you have any questions, feel free to reach out to me on Twitter or submit a GitHub issue." "### Thanks for using this tool! [Feel free to contribute to this project on GitHub!](https://lewismenelaws.com) If you have any questions, feel free to reach out to me on Twitter or submit a GitHub issue. You can find solutions to many common problems in the [Documentation](https://luka-hietala.gitbook.io/documentation-for-the-reddit-bot/)"
) )
time.sleep(1) time.sleep(1)

@ -2,8 +2,18 @@
from dotenv import dotenv_values from dotenv import dotenv_values
DEFAULTS = {'SUBREDDIT': "AskReddit", 'ALLOW_NSFW': "False", 'POST_ID': "", 'THEME': "DARK", 'REDDIT_2FA': "no", DEFAULTS = {
'TIMES_TO_RUN': "", 'MAX_COMMENT_LENGTH': "500", 'OPACITY': "1", 'VOICE': "en_us_001", 'STORYMODE': "False"} "SUBREDDIT": "AskReddit",
"ALLOW_NSFW": "False",
"POST_ID": "",
"THEME": "DARK",
"REDDIT_2FA": "no",
"TIMES_TO_RUN": "",
"MAX_COMMENT_LENGTH": "500",
"OPACITY": "1",
"VOICE": "en_us_001",
"STORYMODE": "False",
}
class Config: class Config:

@ -1,4 +1,3 @@
# Okay, have to admit. This code is from StackOverflow. It's so efficient, that it's probably the best way to do it. # Okay, have to admit. This code is from StackOverflow. It's so efficient, that it's probably the best way to do it.
# Although, it is edited to use less threads. # Although, it is edited to use less threads.

@ -3,6 +3,7 @@ import json
from os import getenv from os import getenv
from utils.console import print_substep from utils.console import print_substep
def get_subreddit_undone(submissions: List, subreddit): def get_subreddit_undone(submissions: List, subreddit):
""" """
recursively checks if the top submission in the list was already done. recursively checks if the top submission in the list was already done.

@ -4,7 +4,9 @@ from os import getenv
from utils.console import print_step from utils.console import print_step
def check_done(redditobj): # don't set this to be run anyplace that isn't subreddit.py bc of inspect stack def check_done(
redditobj,
): # don't set this to be run anyplace that isn't subreddit.py bc of inspect stack
"""params: """params:
reddit_object: The Reddit Object you received in askreddit.py""" reddit_object: The Reddit Object you received in askreddit.py"""
with open("./video_creation/data/videos.json", "r") as done_vids_raw: with open("./video_creation/data/videos.json", "r") as done_vids_raw:

@ -7,6 +7,7 @@ from moviepy.video.io.ffmpeg_tools import ffmpeg_extract_subclip
from moviepy.editor import VideoFileClip from moviepy.editor import VideoFileClip
from utils.console import print_step, print_substep from utils.console import print_step, print_substep
def get_start_and_end_times(video_length, length_of_clip): def get_start_and_end_times(video_length, length_of_clip):
random_time = randrange(180, int(length_of_clip) - int(video_length)) random_time = randrange(180, int(length_of_clip) - int(video_length))
return random_time, random_time + video_length return random_time, random_time + video_length
@ -17,11 +18,11 @@ def download_background():
Path("./assets/backgrounds/").mkdir(parents=True, exist_ok=True) Path("./assets/backgrounds/").mkdir(parents=True, exist_ok=True)
background_options = [ # uri , filename , credit background_options = [ # uri , filename , credit
("https://www.youtube.com/watch?v=n_Dv4JMiwK8", "parkour.mp4", "bbswitzer"), ("https://www.youtube.com/watch?v=n_Dv4JMiwK8", "parkour.mp4", "bbswitzer"),
#( # (
# "https://www.youtube.com/watch?v=2X9QGY__0II", # "https://www.youtube.com/watch?v=2X9QGY__0II",
# "rocket_league.mp4", # "rocket_league.mp4",
# "Orbital Gameplay", # "Orbital Gameplay",
#), # ),
] ]
# note: make sure the file name doesn't include an - in it # note: make sure the file name doesn't include an - in it
if not len(listdir("./assets/backgrounds")) <= len( if not len(listdir("./assets/backgrounds")) <= len(
@ -32,7 +33,7 @@ def download_background():
) )
print_substep("Downloading the backgrounds videos... please be patient 🙏 ") print_substep("Downloading the backgrounds videos... please be patient 🙏 ")
for uri, filename, credit in background_options: for uri, filename, credit in background_options:
if Path(f'assets/backgrounds/{credit}-{filename}').is_file(): if Path(f"assets/backgrounds/{credit}-{filename}").is_file():
continue # adds check to see if file exists before downloading continue # adds check to see if file exists before downloading
print_substep(f"Downloading {filename} from {uri}") print_substep(f"Downloading {filename} from {uri}")
YouTube(uri).streams.filter(res="1080p").first().download( YouTube(uri).streams.filter(res="1080p").first().download(

@ -88,7 +88,7 @@ def make_final_video(number_of_clips, length):
.resize(width=W - 100) .resize(width=W - 100)
.set_opacity(float(opacity)), .set_opacity(float(opacity)),
) )
#if os.path.exists("assets/mp3/posttext.mp3"): # if os.path.exists("assets/mp3/posttext.mp3"):
# image_clips.insert( # image_clips.insert(
# 0, # 0,
# ImageClip("assets/png/title.png") # ImageClip("assets/png/title.png")
@ -97,16 +97,13 @@ def make_final_video(number_of_clips, length):
# .resize(width=W - 100) # .resize(width=W - 100)
# .set_opacity(float(opacity)), # .set_opacity(float(opacity)),
# ) # )
#else: # else:
image_clips.insert( image_clips.insert(
0, 0,
ImageClip("assets/temp/png/title.png") ImageClip("assets/temp/png/title.png").set_duration(audio_clips[0].duration)
.set_duration(audio_clips[0].duration) # .set_duration(audixc vcco_clips[0].duration)
#.set_duration(audixc vcco_clips[0].duration) .set_position("center").resize(width=W - 100).set_opacity(float(opacity)),
.set_position("center") )
.resize(width=W - 100)
.set_opacity(float(opacity)),
)
image_concat = concatenate_videoclips(image_clips).set_position( image_concat = concatenate_videoclips(image_clips).set_position(
("center", "center") ("center", "center")
) )

@ -1,20 +1,19 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
from gtts import gTTS from os import getenv
from pathlib import Path from pathlib import Path
from os import getenv, name
import sox import sox
from mutagen import MutagenError from mutagen import MutagenError
from mutagen.mp3 import MP3, HeaderNotFoundError from mutagen.mp3 import MP3, HeaderNotFoundError
from rich.progress import track
from rich.console import Console from rich.console import Console
from rich.progress import track
from TTS.swapper import TTS
console = Console() console = Console()
import re
from utils.console import print_step, print_substep from utils.console import print_step, print_substep
from utils.voice import sanitize_text from utils.voice import sanitize_text
from video_creation.TTSwrapper import TTTTSWrapper
VIDEO_LENGTH: int = 40 # secs VIDEO_LENGTH: int = 40 # secs
@ -29,9 +28,8 @@ def save_text_to_mp3(reddit_obj):
# Create a folder for the mp3 files. # Create a folder for the mp3 files.
Path("assets/temp/mp3").mkdir(parents=True, exist_ok=True) Path("assets/temp/mp3").mkdir(parents=True, exist_ok=True)
TextToSpeech = TTS()
ttttsw = TTTTSWrapper() # tiktok text to speech wrapper TextToSpeech.tts(
ttttsw.tts(
sanitize_text(reddit_obj["thread_title"]), sanitize_text(reddit_obj["thread_title"]),
filename=f"assets/temp/mp3/title.mp3", filename=f"assets/temp/mp3/title.mp3",
random_speaker=False, random_speaker=False,
@ -41,19 +39,19 @@ def save_text_to_mp3(reddit_obj):
except HeaderNotFoundError: # note to self AudioFileClip except HeaderNotFoundError: # note to self AudioFileClip
length += sox.file_info.duration(f"assets/temp/mp3/title.mp3") length += sox.file_info.duration(f"assets/temp/mp3/title.mp3")
if getenv("STORYMODE").casefold() == "true": if getenv("STORYMODE").casefold() == "true":
ttttsw.tts( TextToSpeech.tts(
sanitize_text(reddit_obj["thread_content"]), sanitize_text(reddit_obj["thread_content"]),
filename=f"assets/temp/mp3/story_content.mp3", filename=f"assets/temp/mp3/story_content.mp3",
random_speaker=False, random_speaker=False,
) )
#'story_content' # 'story_content'
com = 0 com = 0
for comment in track((reddit_obj["comments"]), "Saving..."): for comment in track((reddit_obj["comments"]), "Saving..."):
# ! Stop creating mp3 files if the length is greater than VIDEO_LENGTH seconds. This can be longer, but this is just a good_voices starting point # ! Stop creating mp3 files if the length is greater than VIDEO_LENGTH seconds. This can be longer, but this is just a good_voices starting point
if length > VIDEO_LENGTH: if length > VIDEO_LENGTH:
break break
ttttsw.tts( TextToSpeech.tts(
sanitize_text(comment["comment_body"]), sanitize_text(comment["comment_body"]),
filename=f"assets/temp/mp3/{com}.mp3", filename=f"assets/temp/mp3/{com}.mp3",
random_speaker=False, random_speaker=False,

Loading…
Cancel
Save