You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
RedditVideoMakerBot/main.py

176 lines
7.8 KiB

#!/usr/bin/env python
import math
import sys
from os import name
from pathlib import Path
from subprocess import Popen
from typing import Dict, NoReturn
# Reddit pipeline disabled — Threads is the active source.
# from reddit.subreddit import get_subreddit_threads
from threads.threads_api import get_threads_posts
from utils import settings
from utils.cleanup import cleanup
from utils.checkpoint import run_step, save_checkpoint, load_checkpoint, clear_checkpoint, print_resume_status
from utils.console import print_markdown, print_step, print_substep
from utils.ffmpeg_install import ffmpeg_install
from utils.id import extract_id
from utils.version import checkversion
from video_creation.background import (
chop_background,
download_background_audio,
download_background_video,
get_background_config,
)
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.4.0"
print(
"""
██████╗ ███████╗██████╗ ██████╗ ██╗████████╗ ██╗ ██╗██╗██████╗ ███████╗ ██████╗ ███╗ ███╗ █████╗ ██╗ ██╗███████╗██████╗
██╔══██╗██╔════╝██╔══██╗██╔══██╗██║╚══██╔══╝ ██║ ██║██║██╔══██╗██╔════╝██╔═══██╗ ████╗ ████║██╔══██╗██║ ██╔╝██╔════╝██╔══██╗
██████╔╝█████╗ ██║ ██║██║ ██║██║ ██║ ██║ ██║██║██║ ██║█████╗ ██║ ██║ ██╔████╔██║███████║█████╔╝ █████╗ ██████╔╝
██╔══██╗██╔══╝ ██║ ██║██║ ██║██║ ██║ ╚██╗ ██╔╝██║██║ ██║██╔══╝ ██║ ██║ ██║╚██╔╝██║██╔══██║██╔═██╗ ██╔══╝ ██╔══██╗
██║ ██║███████╗██████╔╝██████╔╝██║ ██║ ╚████╔╝ ██║██████╔╝███████╗╚██████╔╝ ██║ ╚═╝ ██║██║ ██║██║ ██╗███████╗██║ ██║
╚═╝ ╚═╝╚══════╝╚═════╝ ╚═════╝ ╚═╝ ╚═╝ ╚═══╝ ╚═╝╚═════╝ ╚══════╝ ╚═════╝ ╚═╝ ╚═╝╚═╝ ╚═╝╚═╝ ╚═╝╚══════╝╚═╝ ╚═╝
"""
)
print_markdown(
"### Thanks for using this tool! Feel free to contribute to this project on GitHub! If you have any questions, feel free to join my Discord server or submit a GitHub issue. You can find solutions to many common problems in the documentation: https://reddit-video-maker-bot.netlify.app/"
)
checkversion(__VERSION__)
reddit_id: str
reddit_object: Dict[str, str | list]
def main(POST_URL=None) -> None:
global reddit_id, reddit_object
# Step 1: Fetch Threads post (no checkpoint — thread_id unknown yet)
reddit_object = get_threads_posts(POST_URL)
reddit_id = extract_id(reddit_object)
print_substep(f"Thread ID is {reddit_id}", style="bold blue")
save_checkpoint(reddit_id, "fetch_thread", {"result": None})
print_resume_status(reddit_id)
# Step 2: Generate TTS audio
tts_result = run_step(
reddit_id, "generate_tts",
save_text_to_mp3, reddit_object,
)
length, number_of_comments = tts_result[0], tts_result[1]
length = math.ceil(length)
# Step 3: Take screenshots
run_step(
reddit_id, "take_screenshots",
get_screenshots_of_reddit_posts, reddit_object, number_of_comments,
)
# Step 4: Download background video & audio
bg_config = {
"video": get_background_config("video"),
"audio": get_background_config("audio"),
}
run_step(
reddit_id, "download_background",
_download_backgrounds, bg_config,
)
# Step 5: Chop background
run_step(
reddit_id, "chop_background",
chop_background, bg_config, length, reddit_object,
)
# Step 6: Make final video
run_step(
reddit_id, "make_final_video",
make_final_video, number_of_comments, length, reddit_object, bg_config,
)
# Pipeline complete — clear checkpoint
clear_checkpoint(reddit_id)
print_step("Pipeline completed successfully! Checkpoint cleared.")
def _download_backgrounds(bg_config):
download_background_video(bg_config["video"])
download_background_audio(bg_config["audio"])
def run_many(times) -> None:
for x in range(1, times + 1):
print_step(
f'on the {x}{("th", "st", "nd", "rd", "th", "th", "th", "th", "th", "th")[x % 10]} iteration of {times}'
)
main()
Popen("cls" if name == "nt" else "clear", shell=True).wait()
def shutdown() -> NoReturn:
if "reddit_id" in globals():
print_markdown("## Clearing temp files")
cleanup(reddit_id)
print("Exiting...")
sys.exit()
if __name__ == "__main__":
if sys.version_info.major != 3 or sys.version_info.minor not in [10, 11, 12]:
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", f"{directory}/config.toml"
)
config is False and sys.exit()
if (
not settings.config["settings"]["tts"]["tiktok_sessionid"]
or settings.config["settings"]["tts"]["tiktok_sessionid"] == ""
) and config["settings"]["tts"]["voice_choice"] == "tiktok":
print_substep(
"TikTok voice requires a sessionid! Check our documentation on how to obtain one.",
"bold red",
)
sys.exit()
try:
threads_post_id = (
config.get("threads", {}).get("thread", {}).get("post_id", "")
if isinstance(config.get("threads", {}), dict) else ""
)
if threads_post_id:
for index, post_id in enumerate(threads_post_id.split("+")):
index += 1
print_step(
f'on the {index}{("st" if index % 10 == 1 else ("nd" if index % 10 == 2 else ("rd" if index % 10 == 3 else "th")))} post of {len(threads_post_id.split("+"))}'
)
main(post_id)
Popen("cls" if name == "nt" else "clear", shell=True).wait()
elif config["settings"]["times_to_run"]:
run_many(config["settings"]["times_to_run"])
else:
main()
except KeyboardInterrupt:
shutdown()
except Exception as err:
config["settings"]["tts"]["tiktok_sessionid"] = "REDACTED"
config["settings"]["tts"]["elevenlabs_api_key"] = "REDACTED"
config["settings"]["tts"]["openai_api_key"] = "REDACTED"
print_step(
f"Sorry, something went wrong with this version! Try again, and feel free to report this issue at GitHub or the Discord community.\n"
f"Version: {__VERSION__} \n"
f"Error: {err} \n"
f'Config: {config["settings"]}'
)
raise err