Merge pull request from electro199/dev

Bug fixes
pull/1607/head
Simon 2 years ago committed by GitHub
commit af58375dd3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

2
.gitignore vendored

@ -244,4 +244,4 @@ video_creation/data/videos.json
video_creation/data/envvars.txt
config.toml
video_creation/data/videos.json
*.exe

@ -14,7 +14,9 @@ from utils import settings
from utils.console import print_step, print_substep
from utils.voice import sanitize_text
DEFAULT_MAX_LENGTH: int = 50 # video length variable
DEFAULT_MAX_LENGTH: int = 50 # Video length variable, edit this on your own risk. It should work, but it's not supported
class TTSEngine:
@ -74,7 +76,7 @@ class TTSEngine:
self.add_periods()
self.call_tts("title", process_text(self.reddit_object["thread_title"]))
# processed_text = ##self.reddit_object["thread_post"] != ""
idx = None
idx = 0
if settings.config["settings"]["storymode"]:
if settings.config["settings"]["storymodemethod"] == 0:

@ -1,12 +1,11 @@
#!/usr/bin/env python
import math
import sys
from logging import error
from os import name
from pathlib import Path
from subprocess import Popen
from typing import NoReturn
import ffmpeg
from prawcore import ResponseException
from utils.console import print_substep
from reddit.subreddit import get_subreddit_threads
@ -59,11 +58,7 @@ 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)
try:
make_final_video(number_of_comments, length, reddit_object, bg_config)
except ffmpeg.Error as e:
print(e.stderr.decode("utf8"))
exit(1)
make_final_video(number_of_comments, length, reddit_object, bg_config)
def run_many(times) -> None:
@ -75,31 +70,26 @@ def run_many(times) -> None:
Popen("cls" if name == "nt" else "clear", shell=True).wait()
def shutdown():
try:
redditid
except NameError:
print("Exiting...")
exit()
else:
def shutdown() -> NoReturn:
if "redditid" in globals():
print_markdown("## Clearing temp files")
cleanup(redditid)
print("Exiting...")
exit()
print("Exiting...")
sys.exit()
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
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.")
sys.exit()
ffmpeg_install()
directory = Path().absolute()
config = settings.check_toml(
f"{directory}/utils/.config.template.toml", "config.toml"
f"{directory}/utils/.config.template.toml", f"{directory}/config.toml"
)
config is False and exit()
config is False and sys.exit()
if (
not settings.config["settings"]["tts"]["tiktok_sessionid"]
or settings.config["settings"]["tts"]["tiktok_sessionid"] == ""
@ -108,7 +98,7 @@ if __name__ == "__main__":
"TikTok voice requires a sessionid! Check our documentation on how to obtain one.",
"bold red",
)
exit()
sys.exit()
try:
if config["reddit"]["thread"]["post_id"]:
for index, post_id in enumerate(
@ -127,10 +117,8 @@ if __name__ == "__main__":
except KeyboardInterrupt:
shutdown()
except ResponseException:
# error for invalid credentials
print_markdown("## Invalid credentials")
print_markdown("Please check your credentials in the config.toml file")
shutdown()
except Exception as err:
config["settings"]["tts"]["tiktok_sessionid"] = "REDACTED"

@ -0,0 +1,15 @@
@echo off
set VENV_DIR=.venv
if exist "%VENV_DIR%" (
echo Activating virtual environment...
call "%VENV_DIR%\Scripts\activate.bat"
)
echo Running Python script...
python main.py
if errorlevel 1 (
echo An error occurred. Press any key to exit.
pause >nul
)

@ -14,7 +14,6 @@ max_comment_length = { default = 500, optional = false, nmin = 10, nmax = 10000,
min_comment_length = { default = 1, optional = true, nmin = 0, nmax = 10000, type = "int", explanation = "min_comment_length number of characters a comment can have. default is 0", example = 50, oob_error = "the max comment length should be between 1 and 100" }
post_lang = { default = "", optional = true, explanation = "The language you would like to translate to.", example = "es-cr", options = ['','af', 'ak', 'am', 'ar', 'as', 'ay', 'az', 'be', 'bg', 'bho', 'bm', 'bn', 'bs', 'ca', 'ceb', 'ckb', 'co', 'cs', 'cy', 'da', 'de', 'doi', 'dv', 'ee', 'el', 'en', 'en-US', 'eo', 'es', 'et', 'eu', 'fa', 'fi', 'fr', 'fy', 'ga', 'gd', 'gl', 'gn', 'gom', 'gu', 'ha', 'haw', 'hi', 'hmn', 'hr', 'ht', 'hu', 'hy', 'id', 'ig', 'ilo', 'is', 'it', 'iw', 'ja', 'jw', 'ka', 'kk', 'km', 'kn', 'ko', 'kri', 'ku', 'ky', 'la', 'lb', 'lg', 'ln', 'lo', 'lt', 'lus', 'lv', 'mai', 'mg', 'mi', 'mk', 'ml', 'mn', 'mni-Mtei', 'mr', 'ms', 'mt', 'my', 'ne', 'nl', 'no', 'nso', 'ny', 'om', 'or', 'pa', 'pl', 'ps', 'pt', 'qu', 'ro', 'ru', 'rw', 'sa', 'sd', 'si', 'sk', 'sl', 'sm', 'sn', 'so', 'sq', 'sr', 'st', 'su', 'sv', 'sw', 'ta', 'te', 'tg', 'th', 'ti', 'tk', 'tl', 'tr', 'ts', 'tt', 'ug', 'uk', 'ur', 'uz', 'vi', 'xh', 'yi', 'yo', 'zh-CN', 'zh-TW', 'zu'] }
min_comments = { default = 20, optional = false, nmin = 10, type = "int", explanation = "The minimum number of comments a post should have to be included. default is 20", example = 29, oob_error = "the minimum number of comments should be between 15 and 999999" }
#post_url = { optional = true, default = "", regex = "^https:\\/\\/www\\.reddit\\.com\\/r\\/[a-zA-Z0-9]+\\/comments\\/[a-zA-Z0-9]+\\/[a-zA-Z0-9_]+\\/$", explanation = "Not working currently Use if you want to use a specific post.", example = "https://www.reddit.com/r/buildapc/comments/yzh07p/have_you_switched_to_windows_11/" }
[ai]
ai_similarity_enabled = {optional = true, option = [true, false], default = false, type = "bool", explanation = "Threads read from Reddit are sorted based on their similarity to the keywords given below"}
@ -25,7 +24,7 @@ allow_nsfw = { optional = false, type = "bool", default = false, example = false
theme = { optional = false, default = "dark", example = "light", options = ["dark", "light", "transparent", ], explanation = "Sets the Reddit theme, either LIGHT or DARK. For story mode you can also use a transparent background." }
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" }
transition = { optional = true, default = 0.2, example = 0.2, explanation = "Sets the transition time (in seconds) between the comments. Set to 0 if you want to disable it.", type = "float", nmin = 0, nmax = 2, oob_error = "The transition HAS to be between 0 and 2", input_error = "The opacity HAS to be a decimal number between 0 and 2" }
#transition = { optional = true, default = 0.2, example = 0.2, explanation = "Sets the transition time (in seconds) between the comments. Set to 0 if you want to disable it.", type = "float", nmin = 0, nmax = 2, oob_error = "The transition HAS to be between 0 and 2", input_error = "The opacity HAS to be a decimal number between 0 and 2" }
storymode = { optional = true, type = "bool", default = false, example = false, options = [true, false,], explanation = "Only read out title and post content, great for subreddits with stories" }
storymodemethod= { optional = true, default = 1, example = 1, explanation = "Style that's used for the storymode. Set to 0 for single picture display in whole video, set to 1 for fancy looking video ", type = "int", nmin = 0, oob_error = "It's very hard to run something less than once.", options = [0, 1] }
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." }
@ -54,5 +53,5 @@ tiktok_voice = { optional = true, default = "en_us_001", example = "en_us_006",
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" }
#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" }

@ -1,29 +1,20 @@
import os
from os.path import exists
import shutil
def _listdir(d): # listdir with full path
return [os.path.join(d, f) for f in os.listdir(d)]
def cleanup(id) -> int:
def cleanup(reddit_id) -> int:
"""Deletes all temporary assets in assets/temp
Returns:
int: How many files were deleted
"""
if exists(f"../assets/temp/{id}/"):
count = 0
files = [f for f in os.listdir(f"../assets/temp/{id}/") if f.endswith(".mp4")]
count += len(files)
for f in files:
os.remove(f"../assets/temp/{id}/{f}")
REMOVE_DIRS = [f"../assets/temp/{id}/mp3/", f"../assets/temp/{id}/png/"]
for d in REMOVE_DIRS:
if exists(d):
count += len(_listdir(d))
for f in _listdir(d):
os.remove(f)
os.rmdir(d)
os.rmdir(f"../assets/temp/{id}/")
return count
directory = f"../assets/temp/{reddit_id}/"
if exists(directory):
shutil.rmtree(directory)
return 1

@ -17,22 +17,16 @@ def ffmpeg_install_windows():
os.rename("ffmpeg-master-latest-win64-gpl", "ffmpeg")
# Move the files inside bin to the root
for file in os.listdir("ffmpeg/bin"):
os.rename(f"ffmpeg/bin/{file}", f"ffmpeg/{file}")
os.rename(f"ffmpeg/bin/{file}", f"./{file}")
os.rmdir("ffmpeg/bin")
for file in os.listdir("ffmpeg/doc"):
os.remove(f"ffmpeg/doc/{file}")
os.rmdir("ffmpeg/doc")
# Add to the path
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()
os.remove("ffmpeg/LICENSE.txt")
os.rmdir("ffmpeg/")
print("FFmpeg installed successfully! Please restart your computer and then re-run the program.")
except Exception as e:
print(
"An error occurred while trying to install FFmpeg. Please try again. Otherwise, please install FFmpeg manually and try again."
@ -79,17 +73,12 @@ def ffmpeg_install_mac():
def ffmpeg_install():
try:
# Try to run the FFmpeg command
subprocess.run(
["ffmpeg", "-version"],
check=True,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
)
print(
"FFmpeg is installed on this system! If you are seeing this error for the second time, restart your computer."
)
subprocess.run(['ffmpeg', '-version'], check=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
except FileNotFoundError as e:
print("FFmpeg is not installed on this system.")
# Check if there's ffmpeg.exe in the current directory
if os.path.exists("./ffmpeg.exe"):
print('FFmpeg is installed on this system! If you are seeing this error for the second time, restart your computer.')
print('FFmpeg is not installed on this system.')
resp = input(
"We can try to automatically install it for you. Would you like to do that? (y/n): "
)

@ -1,4 +1,7 @@
import os
import re
import time
from typing import List
import spacy
@ -7,25 +10,25 @@ from utils.voice import sanitize_text
# working good
def posttextparser(obj):
text = re.sub("\n", "", obj)
def posttextparser(obj, *, tried: bool = False) -> List[str]:
text: str = re.sub("\n", " ", obj)
try:
nlp = spacy.load("en_core_web_sm")
except OSError:
except OSError as e:
if not tried:
os.system("python -m spacy download en_core_web_sm")
time.sleep(5)
return posttextparser(obj, tried=True)
print_step(
"The spacy model can't load. You need to install it with the command \npython -m spacy download en_core_web_sm"
)
exit()
"The spacy model can't load. You need to install it with the command \npython -m spacy download en_core_web_sm ")
raise e
doc = nlp(text)
newtext: list = []
# to check for space str
for line in doc.sents:
if sanitize_text(line.text):
newtext.append(line.text)
# print(line)
return newtext

@ -26,8 +26,6 @@ def load_background_options():
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)
for name in list(background_options["video"].keys()):
pos = background_options["video"][name][3]

@ -11,11 +11,11 @@ from PIL import Image
from rich.console import Console
from rich.progress import track
from utils import settings
from utils.cleanup import cleanup
from utils.console import print_step, print_substep
from utils.thumbnail import create_thumbnail
from utils.videos import save_data
from utils import settings
import tempfile
import threading
@ -97,9 +97,9 @@ def prepare_background(reddit_id: str, W: int, H: int) -> str:
)
try:
output.run(quiet=True)
except Exception as e:
print(e)
exit()
except ffmpeg.Error as e:
print(e.stderr.decode("utf8"))
exit(1)
return output_path
@ -352,7 +352,7 @@ def make_final_video(
text=text,
x=f"(w-text_w)",
y=f"(h-text_h)",
fontsize=12,
fontsize=5,
fontcolor="White",
fontfile=os.path.join("fonts", "Roboto-Regular.ttf"),
)
@ -362,7 +362,7 @@ def make_final_video(
pbar = tqdm(total=100, desc="Progress: ", bar_format="{l_bar}{bar}", unit=" %")
def on_update_example(progress):
def on_update_example(progress) -> None:
status = round(progress * 100, 2)
old_percentage = pbar.n
pbar.update(status - old_percentage)
@ -399,25 +399,28 @@ def make_final_video(
) # 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="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,
)
try:
ffmpeg.output(
background_clip,
audio,
path,
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,
)
except ffmpeg.Error as e:
print(e.stderr.decode("utf8"))
exit(1)
old_percentage = pbar.n
pbar.update(100 - old_percentage)
pbar.close()

@ -237,7 +237,7 @@ def get_screenshots_of_reddit_posts(reddit_object: dict, screenshot_num: int):
page.goto(f'https://reddit.com{comment["comment_url"]}', timeout=0)
# translate code
# translate code
if settings.config["reddit"]["thread"]["post_lang"]:
comment_tl = translators.google(
@ -282,3 +282,4 @@ def get_screenshots_of_reddit_posts(reddit_object: dict, screenshot_num: int):
browser.close()
print_substep("Screenshots downloaded Successfully.", style="bold green")

Loading…
Cancel
Save