backup
This commit is contained in:
1 parent
3c9bc3d0ca
commit
f491479fb7
10 files changed
+78
-60
No files matched your search
@@ -14,14 +14,16 @@ Created by Lewis Menelaws & [TMRRW](https://tmrrwinc.ca)
|
||||
|
||||
## Motivation 🤔
|
||||
|
||||
These videos on TikTok, YouTube and Instagram get MILLIONS of views across all platforms and require very little effort. The only original thing being done is the editing and gathering of all materials...
|
||||
These videos on TikTok, YouTube and Instagram get MILLIONS of views across all platforms and require very little effort.
|
||||
The only original thing being done is the editing and gathering of all materials...
|
||||
|
||||
... but what if we can automate that process? 🤔
|
||||
|
||||
## Disclaimers 🚨
|
||||
|
||||
- This is purely for fun purposes.
|
||||
- **At the moment**, this repository won't attempt to upload this content through this bot. It will give you a file that you will then have to upload manually. This is for the sake of avoiding any sort of community guideline issues.
|
||||
- **At the moment**, this repository won't attempt to upload this content through this bot. It will give you a file that
|
||||
you will then have to upload manually. This is for the sake of avoiding any sort of community guideline issues.
|
||||
|
||||
## Requirements
|
||||
|
||||
@@ -31,17 +33,21 @@ These videos on TikTok, YouTube and Instagram get MILLIONS of views across all p
|
||||
## Installation 👩💻
|
||||
|
||||
1. Clone this repository
|
||||
2. Rename `.env.template` to `.env` and replace all values with the appropriate fields. To get Reddit keys (**required**), visit [the Reddit Apps page.](https://www.reddit.com/prefs/apps) TL;DR set up an app that is a "script". Copy your keys into the `.env` file, along with whether your account uses two-factor authentication.
|
||||
2. Rename `.env.template` to `.env` and replace all values with the appropriate fields. To get Reddit keys (**
|
||||
required**), visit [the Reddit Apps page.](https://www.reddit.com/prefs/apps) TL;DR set up an app that is a "script".
|
||||
Copy your keys into the `.env` file, along with whether your account uses two-factor authentication.
|
||||
3. Run `pip3 install -r requirements.txt`
|
||||
4. install [SoX](https://sourceforge.net/projects/sox/files/sox/)
|
||||
5. Run `playwright install` and `playwright install-deps`.
|
||||
6. Run `python3 main.py`
|
||||
7. Enjoy 😎
|
||||
|
||||
## Contributing & Ways to improve 📈
|
||||
|
||||
In its current state, this bot does exactly what it needs to do. However, lots of improvements can be made.
|
||||
|
||||
I have tried to simplify the code so anyone can read it and start contributing at any skill level. Don't be shy :) contribute!
|
||||
I have tried to simplify the code so anyone can read it and start contributing at any skill level. Don't be shy :)
|
||||
contribute!
|
||||
|
||||
- [ ] Creating better documentation and adding a command line interface.
|
||||
- [x] Allowing users to choose a reddit thread instead of being randomized.
|
||||
|
||||
@@ -1,12 +1,17 @@
|
||||
import os
|
||||
import time
|
||||
|
||||
from dotenv import load_dotenv
|
||||
|
||||
from reddit.subreddit import get_subreddit_threads
|
||||
from utils.cleanup import cleanup
|
||||
from utils.console import print_markdown
|
||||
import time
|
||||
from reddit.subreddit import get_subreddit_threads
|
||||
from video_creation.background import download_background, chop_background_video
|
||||
from video_creation.voices import save_text_to_mp3
|
||||
from video_creation.screenshot_downloader import download_screenshots_of_reddit_posts
|
||||
from video_creation.final_video import make_final_video
|
||||
from video_creation.screenshot_downloader import download_screenshots_of_reddit_posts
|
||||
from video_creation.voices import save_text_to_mp3
|
||||
|
||||
load_dotenv()
|
||||
# base code by elebumm
|
||||
print_markdown(
|
||||
"### Thanks for using this tool! 😊 Feel free to contribute to this project on GitHub! (JasonLovesDoggo/RedditVideoMakerBot). If you have any questions, feel free to reach out to me on Twitter @JasonLovesDoggo or submit a GitHub issue.")
|
||||
@@ -34,9 +39,17 @@ def main():
|
||||
final_video = make_final_video(number_of_comments)
|
||||
|
||||
|
||||
def run_many(times):
|
||||
for x in range(times):
|
||||
main()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
try:
|
||||
main()
|
||||
if os.getenv('TIMES_TO_RUN'):
|
||||
run_many(int(os.getenv('TIMES_TO_RUN')))
|
||||
else:
|
||||
main()
|
||||
except KeyboardInterrupt:
|
||||
print_markdown("## Clearing temp files")
|
||||
cleanup()
|
||||
|
||||
+4
-7
@@ -1,11 +1,9 @@
|
||||
import re
|
||||
|
||||
from utils.console import print_step, print_substep
|
||||
import praw
|
||||
import random
|
||||
from dotenv import load_dotenv
|
||||
from os import getenv, environ
|
||||
|
||||
import praw
|
||||
|
||||
from utils.console import print_step, print_substep
|
||||
from utils.videos import check_done
|
||||
|
||||
TEXT_WHITELIST = set('abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ 1234567890')
|
||||
@@ -22,7 +20,6 @@ def get_subreddit_threads():
|
||||
|
||||
print_step("Getting subreddit threads...")
|
||||
content = {}
|
||||
load_dotenv()
|
||||
if getenv("REDDIT_2FA").casefold() == "yes":
|
||||
print("\nEnter your two-factor authentication code from your authenticator app.\n")
|
||||
code = input("> ")
|
||||
@@ -66,7 +63,7 @@ def get_subreddit_threads():
|
||||
for top_level_comment in submission.comments:
|
||||
content["comments"].append(
|
||||
{"comment_body": top_level_comment.body, "comment_url": top_level_comment.permalink,
|
||||
"comment_id": top_level_comment.id, })
|
||||
"comment_id": top_level_comment.id, })
|
||||
|
||||
except AttributeError as e:
|
||||
pass
|
||||
|
||||
@@ -20,4 +20,3 @@ def cleanup() -> int:
|
||||
os.remove('./assets/temp/mp3/' + file)
|
||||
return count
|
||||
return 0
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import inspect
|
||||
import json
|
||||
from os import getenv
|
||||
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
import requests, base64, random, os
|
||||
import base64
|
||||
import random
|
||||
import requests
|
||||
|
||||
# https://twitter.com/scanlime/status/1512598559769702406
|
||||
voices = [ # DISNEY VOICES
|
||||
@@ -74,4 +76,3 @@ class TTTTSWrapper: # TikTok Text-to-Speech Wrapper
|
||||
if ok_or_good == 1: # 1/10 chance of ok voice
|
||||
return random.choice(good_voices['ok'])
|
||||
return random.choice(good_voices['good']) # 9/10 chance of good voice
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
import random
|
||||
from os import listdir, environ
|
||||
from os import listdir, environ, remove
|
||||
from pathlib import Path
|
||||
from random import randrange
|
||||
from pytube import YouTube
|
||||
from moviepy.video.io.ffmpeg_tools import ffmpeg_extract_subclip
|
||||
|
||||
from moviepy.editor import VideoFileClip
|
||||
from rich.progress import Progress
|
||||
from moviepy.video.io.ffmpeg_tools import ffmpeg_extract_subclip
|
||||
from yt_dlp import YoutubeDL
|
||||
|
||||
from utils.console import print_step, print_substep
|
||||
|
||||
@@ -30,27 +30,31 @@ def download_background():
|
||||
background_options): # if there are any background videos not installed
|
||||
print_step("We need to download the backgnrounds videos. they are fairly large but it's only done once. 😎")
|
||||
print_substep("Downloading the backgrounds videos... please be patient 🙏 ")
|
||||
with Progress() as progress:
|
||||
|
||||
download_task = progress.add_task("[green]Downloading...", total=2)
|
||||
|
||||
for uri, filename, credit in background_options:
|
||||
print_substep(f"Downloading {filename} from {uri}")
|
||||
YouTube(uri).streams.filter(res="720p").first().download("assets/backgrounds",
|
||||
filename=f"{credit}-{filename}")
|
||||
progress.update(download_task, advance=1)
|
||||
for uri, filename, credit in background_options:
|
||||
filename = f"{credit}-{filename}"
|
||||
ydl_opts = {'outtmpl': f'assets/backgrounds/_raw_{filename}', 'merge_output_format': 'mp4', }
|
||||
with YoutubeDL(ydl_opts) as ydl:
|
||||
ydl.download(uri)
|
||||
videoclip = VideoFileClip(f"assets/backgrounds/{filename}")
|
||||
new_clip = videoclip.without_audio()
|
||||
new_clip.write_videofile(f"assets/backgrounds/{filename}")
|
||||
remove(f'assets/backgrounds/_raw_{filename}')
|
||||
|
||||
print_substep("Background videos downloaded successfully! 🎉", style="bold green")
|
||||
|
||||
|
||||
def chop_background_video(video_length):
|
||||
print_step("Finding a spot in the backgrounds video to chop...✂️")
|
||||
print_step("Finding a spot in the background video to chop...")
|
||||
choice = random.choice(listdir('assets/backgrounds'))
|
||||
environ["background_credit"] = choice.split('-')[0]
|
||||
|
||||
background = VideoFileClip(f"assets/backgrounds/{choice}")
|
||||
|
||||
start_time, end_time = get_start_and_end_times(video_length, background.duration)
|
||||
ffmpeg_extract_subclip(f'assets/backgrounds/{choice}', start_time, end_time,
|
||||
targetname="assets/temp/backgrounds.mp4", )
|
||||
print_substep("Background video chopped successfully! 🎉", style="bold green")
|
||||
print_substep(choice)
|
||||
ffmpeg_extract_subclip(
|
||||
f"assets/backgrounds/{choice}",
|
||||
start_time,
|
||||
end_time,
|
||||
targetname="assets/temp/background.mp4",
|
||||
)
|
||||
print_substep("Background video chopped successfully!", style="bold green")
|
||||
@@ -1,9 +1,9 @@
|
||||
[
|
||||
{
|
||||
"id": "v2kd2q",
|
||||
"time": "1654128204",
|
||||
"background_credit": "bbswitzer",
|
||||
"reddit_title": "What movie do you absolutely love yet acknowledge is not a super wellmade movie",
|
||||
"filename": "What movie do you absolutely l....mp4"
|
||||
}
|
||||
]
|
||||
{
|
||||
"id": "v2kd2q",
|
||||
"time": "1654128204",
|
||||
"background_credit": "bbswitzer",
|
||||
"reddit_title": "What movie do you absolutely love yet acknowledge is not a super wellmade movie",
|
||||
"filename": "What movie do you absolutely l....mp4"
|
||||
}
|
||||
]
|
||||
@@ -1,12 +1,13 @@
|
||||
import json
|
||||
from os import getenv
|
||||
|
||||
from playwright.sync_api import sync_playwright
|
||||
from pathlib import Path
|
||||
|
||||
from playwright.sync_api import sync_playwright, ViewportSize
|
||||
from rich.progress import track
|
||||
|
||||
from utils.console import print_step, print_substep
|
||||
|
||||
|
||||
def download_screenshots_of_reddit_posts(reddit_object, screenshot_num):
|
||||
"""Downloads screenshots of reddit posts as they are seen on the web.
|
||||
|
||||
@@ -31,15 +32,15 @@ def download_screenshots_of_reddit_posts(reddit_object, screenshot_num):
|
||||
context.add_cookies(cookies)
|
||||
# Get the thread screenshot
|
||||
page = context.new_page()
|
||||
page.set_viewport_size(ViewportSize(width=1920, height=1080))
|
||||
page.goto(reddit_object["thread_url"])
|
||||
|
||||
if page.locator('[data-testid="content-gate"]').is_visible():
|
||||
# This means the post is NSFW and requires to click the proceed button.
|
||||
if getenv("ALLOW_NSFW").casefold() == "false":
|
||||
print_substep("NSFW Post Detected. Skipping...")
|
||||
from subprocess import call
|
||||
call(["python", "main.py"])
|
||||
exit(1)
|
||||
from main import main
|
||||
main()
|
||||
|
||||
print_substep("Post is NSFW. You are spicy... :fire:")
|
||||
page.locator('[data-testid="content-gate"] button').click()
|
||||
|
||||
@@ -1,13 +1,11 @@
|
||||
from os import remove
|
||||
|
||||
import sox
|
||||
from pathlib import Path
|
||||
|
||||
import sox
|
||||
from mutagen import MutagenError
|
||||
from mutagen.mp3 import MP3, HeaderNotFoundError
|
||||
from utils.console import print_step, print_substep
|
||||
from rich.progress import track
|
||||
|
||||
from utils.console import print_step, print_substep
|
||||
from video_creation.TTSwrapper import TTTTSWrapper
|
||||
|
||||
VIDEO_LENGTH: int = 40 # secs
|
||||
@@ -29,11 +27,11 @@ def save_text_to_mp3(reddit_obj):
|
||||
ttttsw.tts(reddit_obj["thread_title"], filename=f"assets/temp/mp3/title.mp3", random_speaker=True)
|
||||
try:
|
||||
length += MP3(f"assets/temp/mp3/title.mp3").info.length
|
||||
except HeaderNotFoundError:
|
||||
length = sox.file_info.duration(f"assets/temp/mp3/title.mp3")
|
||||
except HeaderNotFoundError: # note to self AudioFileClip
|
||||
length += sox.file_info.duration(f"assets/temp/mp3/title.mp3")
|
||||
com = 0
|
||||
for comment in track((reddit_obj["comments"]), "Saving..."):
|
||||
# ! Stop creating mp3 files if the length is greater than 50 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:
|
||||
break
|
||||
|
||||
@@ -49,8 +47,8 @@ def save_text_to_mp3(reddit_obj):
|
||||
print('would have removed'
|
||||
f"assets/temp/mp3/{com}.mp3"
|
||||
f"assets/temp/png/comment_{com}.png")
|
||||
#remove(f"assets/temp/mp3/{com}.mp3")
|
||||
#remove(f"assets/temp/png/comment_{com}.png")# todo might cause odd un-syncing
|
||||
# remove(f"assets/temp/mp3/{com}.mp3")
|
||||
# remove(f"assets/temp/png/comment_{com}.png")# todo might cause odd un-syncing
|
||||
|
||||
print_substep("Saved Text to MP3 files Successfully.", style="bold green")
|
||||
# ! Return the index so we know how many screenshots of comments we need to make.
|
||||
|
||||
Reference in new issue
Block a user