From f67aefabfd427ecddbc7052a66a70c368af1f5ff Mon Sep 17 00:00:00 2001 From: PatatjeMC Date: Sun, 5 Jun 2022 16:47:29 +0200 Subject: [PATCH 1/4] Fixed some bugs and upped background resolution Fixed the 2 most common errors that I encountered: - The "SoX error" (That's what it's called in JasonLovesDoggo's repo) - AttributeError: 'dict' object has no attribute 'title' Fixed the ending being glitchy and freezing Upped the resolution of the background cause it looked bad --- main.py | 6 ++---- reddit/subreddit.py | 2 ++ utils/videos.py | 3 +-- video_creation/background.py | 2 +- video_creation/data/videos.json | 10 +++++++++- video_creation/final_video.py | 12 ++++++++---- 6 files changed, 23 insertions(+), 12 deletions(-) mode change 100644 => 100755 main.py mode change 100644 => 100755 reddit/subreddit.py mode change 100644 => 100755 utils/videos.py mode change 100644 => 100755 video_creation/background.py mode change 100644 => 100755 video_creation/final_video.py diff --git a/main.py b/main.py old mode 100644 new mode 100755 index fd7a139..10be90b --- a/main.py +++ b/main.py @@ -20,10 +20,8 @@ def main(): def get_obj(): reddit_obj = get_subreddit_threads() for comment in (reddit_obj["comments"]): - if len(comment) > 250: - print(comment) + if len(comment["comment_body"]) > 250: reddit_obj["comments"].remove(comment) - print(reddit_obj["comments"]) return reddit_obj reddit_object = get_obj() @@ -31,7 +29,7 @@ def main(): download_screenshots_of_reddit_posts(reddit_object, number_of_comments) download_background() chop_background_video(length) - final_video = make_final_video(number_of_comments) + final_video = make_final_video(number_of_comments, length) if __name__ == '__main__': diff --git a/reddit/subreddit.py b/reddit/subreddit.py old mode 100644 new mode 100755 index 9a19c55..ff19334 --- a/reddit/subreddit.py +++ b/reddit/subreddit.py @@ -43,6 +43,8 @@ def get_subreddit_threads(): threads = subreddit.hot(limit=25) submission = list(threads)[random.randrange(0, 25)] submission = check_done(submission) + if submission == None: + return get_subreddit_threads() print_substep( f'subreddit thread is: {submission.title}\n(if you dont like this, you can change it by exiting and rerunning the program)') diff --git a/utils/videos.py b/utils/videos.py old mode 100644 new mode 100755 index 66b9a75..3af5015 --- a/utils/videos.py +++ b/utils/videos.py @@ -17,6 +17,5 @@ def check_done(redditobj): # don't set this to be run anyplace that isn't subre for video in done_videos: if video['id'] == str(redditobj): print_step('Getting new post as the current one has already been done') - from reddit.subreddit import get_subreddit_threads - return get_subreddit_threads() # recursive func + return None return redditobj diff --git a/video_creation/background.py b/video_creation/background.py old mode 100644 new mode 100755 index f146ade..10f142d --- a/video_creation/background.py +++ b/video_creation/background.py @@ -36,7 +36,7 @@ def download_background(): for uri, filename, credit in background_options: print_substep(f"Downloading {filename} from {uri}") - YouTube(uri).streams.filter(res="720p").first().download("assets/backgrounds", + YouTube(uri).streams.filter(res="1080p").first().download("assets/backgrounds", filename=f"{credit}-{filename}") progress.update(download_task, advance=1) diff --git a/video_creation/data/videos.json b/video_creation/data/videos.json index fe51488..d89118e 100644 --- a/video_creation/data/videos.json +++ b/video_creation/data/videos.json @@ -1 +1,9 @@ -[] +[ + { + "id": "v581n3", + "time": "1654440078", + "background_credit": "Orbital Gameplay", + "reddit_title": "Who is the most evil person alive today", + "filename": "Who is the most evil person al....mp4" + } +] \ No newline at end of file diff --git a/video_creation/final_video.py b/video_creation/final_video.py old mode 100644 new mode 100755 index d5fd528..157b94b --- a/video_creation/final_video.py +++ b/video_creation/final_video.py @@ -3,8 +3,8 @@ import os import time from os.path import exists -from moviepy.editor import (VideoFileClip, AudioFileClip, ImageClip, concatenate_videoclips, concatenate_audioclips, - CompositeAudioClip, CompositeVideoClip) +from moviepy.editor import VideoFileClip, AudioFileClip, ImageClip, concatenate_videoclips, concatenate_audioclips, CompositeAudioClip, CompositeVideoClip +from moviepy.video import io from utils.cleanup import cleanup from utils.console import print_step, print_substep @@ -12,7 +12,7 @@ from utils.console import print_step, print_substep W, H = 1080, 1920 -def make_final_video(number_of_clips): +def make_final_video(number_of_clips, length): print_step("Creating the final video 🎥") VideoFileClip.reW = lambda clip: clip.resize(width=W) VideoFileClip.reH = lambda clip: clip.resize(width=H) @@ -65,7 +65,11 @@ def make_final_video(number_of_clips): if not exists('./results'): print_substep('the results folder didn\'t exist so I made it') os.mkdir("./results") - final.write_videofile(f"results/{filename}", fps=30, audio_codec="aac", audio_bitrate="192k") + + final.write_videofile("temp.mp4", fps=30, audio_codec="aac", audio_bitrate="192k") + io.ffmpeg_tools.ffmpeg_extract_subclip("temp.mp4", 0, length, targetname=f"results/{filename}") + os.remove("temp.mp4") + print_step("Removing temporary files 🗑") cleanups = cleanup() print_substep(f"Removed {cleanups} temporary files 🗑") From 14d3025407a4e12844a1cb53fc817a28b8686d46 Mon Sep 17 00:00:00 2001 From: PatatjeMC Date: Sun, 5 Jun 2022 16:48:57 +0200 Subject: [PATCH 2/4] Reset videos.json Oops forgot to reset it after testing 1 last time. --- video_creation/data/videos.json | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/video_creation/data/videos.json b/video_creation/data/videos.json index d89118e..fe51488 100644 --- a/video_creation/data/videos.json +++ b/video_creation/data/videos.json @@ -1,9 +1 @@ -[ - { - "id": "v581n3", - "time": "1654440078", - "background_credit": "Orbital Gameplay", - "reddit_title": "Who is the most evil person alive today", - "filename": "Who is the most evil person al....mp4" - } -] \ No newline at end of file +[] From d095391d352bbae66153c2417e5a3042e2acb646 Mon Sep 17 00:00:00 2001 From: PatatjeMC Date: Sun, 5 Jun 2022 22:36:55 +0200 Subject: [PATCH 3/4] Error fix Moved the character limit checker cause it was being buggy and making it so some longer comments went thru but not others and it looks like that's fixed now also deleted another character limit check cause it wasn't needed anymore. and for some reason the text replace thingy was in an if statement even tho I don't think it should have been in there. --- main.py | 3 --- reddit/subreddit.py | 7 ++++--- video_creation/TTSwrapper.py | 5 +---- 3 files changed, 5 insertions(+), 10 deletions(-) diff --git a/main.py b/main.py index 10be90b..4aa0a4b 100755 --- a/main.py +++ b/main.py @@ -19,9 +19,6 @@ def main(): def get_obj(): reddit_obj = get_subreddit_threads() - for comment in (reddit_obj["comments"]): - if len(comment["comment_body"]) > 250: - reddit_obj["comments"].remove(comment) return reddit_obj reddit_object = get_obj() diff --git a/reddit/subreddit.py b/reddit/subreddit.py index ff19334..c2a59df 100755 --- a/reddit/subreddit.py +++ b/reddit/subreddit.py @@ -58,9 +58,10 @@ def get_subreddit_threads(): content["comments"] = [] 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, }) + if len(top_level_comment.body) <= 250: + content["comments"].append( + {"comment_body": top_level_comment.body, "comment_url": top_level_comment.permalink, + "comment_id": top_level_comment.id, }) except AttributeError as e: pass diff --git a/video_creation/TTSwrapper.py b/video_creation/TTSwrapper.py index e239e81..0b50b15 100644 --- a/video_creation/TTSwrapper.py +++ b/video_creation/TTSwrapper.py @@ -54,10 +54,7 @@ class TTTTSWrapper: # TikTok Text-to-Speech Wrapper self.URI_BASE = 'https://api16-normal-useast5.us.tiktokv.com/media/api/text/speech/invoke/?text_speaker=' def tts(self, req_text: str = "TikTok Text To Speech", filename: str = 'title.mp3', random_speaker: bool = False): - if len(req_text) > 299: - return ValueError("Text too long must be under 299 characters") - if random_speaker: - req_text = req_text.replace("+", "plus").replace(" ", "+").replace("&", "and") + req_text = req_text.replace("+", "plus").replace(" ", "+").replace("&", "and") voice = self.randomvoice() if random_speaker else 'en_us_002' r = requests.post(f"{self.URI_BASE}{voice}&req_text={req_text}&speaker_map_type=0") From fdc055bcd4309f984eeecff29db446c063b54df1 Mon Sep 17 00:00:00 2001 From: PatatjeMC Date: Mon, 6 Jun 2022 16:14:38 +0200 Subject: [PATCH 4/4] Unlimited comment length I added unlimited comment length by splitting the tts is parts in a way that doesn't make it sound weird. It works great for me but if someone experiences and issues just contact me. --- .env.template | 1 + reddit/subreddit.py | 6 ++--- video_creation/TTSwrapper.py | 26 +++++++++++++++---- .../{cookie.json => cookie-dark-mode.json} | 6 +++++ video_creation/data/cookie-light-mode.json | 8 ++++++ video_creation/screenshot_downloader.py | 8 +++--- 6 files changed, 44 insertions(+), 11 deletions(-) rename video_creation/data/{cookie.json => cookie-dark-mode.json} (73%) create mode 100644 video_creation/data/cookie-light-mode.json diff --git a/.env.template b/.env.template index 3cd9dd4..54e872c 100644 --- a/.env.template +++ b/.env.template @@ -6,3 +6,4 @@ SUBREDDIT="AskReddit" ALLOW_NSFW="False" POST_ID="" THEME="LIGHT" +MAX_COMMENT_LENGTH="500" diff --git a/reddit/subreddit.py b/reddit/subreddit.py index c2a59df..c7ac06d 100755 --- a/reddit/subreddit.py +++ b/reddit/subreddit.py @@ -16,7 +16,7 @@ def textify(text): def get_subreddit_threads(): """ - Returns a list of threads from the AskReddit subreddit. + Returns a list of threads from the selected subreddit. """ print_step("Getting subreddit threads...") @@ -24,7 +24,7 @@ def get_subreddit_threads(): content = {} load_dotenv() reddit = praw.Reddit(client_id=getenv("REDDIT_CLIENT_ID"), client_secret=getenv("REDDIT_CLIENT_SECRET"), - user_agent="Accessing AskReddit threads", username=getenv("REDDIT_USERNAME"), + user_agent="Accessing subreddit threads", username=getenv("REDDIT_USERNAME"), password=getenv("REDDIT_PASSWORD"), ) """ Ask user for subreddit input @@ -58,7 +58,7 @@ def get_subreddit_threads(): content["comments"] = [] for top_level_comment in submission.comments: - if len(top_level_comment.body) <= 250: + if len(top_level_comment.body) <= int(environ["MAX_COMMENT_LENGTH"]): content["comments"].append( {"comment_body": top_level_comment.body, "comment_url": top_level_comment.permalink, "comment_id": top_level_comment.id, }) diff --git a/video_creation/TTSwrapper.py b/video_creation/TTSwrapper.py index 0b50b15..6fa9d97 100644 --- a/video_creation/TTSwrapper.py +++ b/video_creation/TTSwrapper.py @@ -1,4 +1,6 @@ import requests, base64, random, os +import re +from moviepy.editor import AudioFileClip, concatenate_audioclips, CompositeAudioClip # https://twitter.com/scanlime/status/1512598559769702406 voices = [ # DISNEY VOICES @@ -55,15 +57,29 @@ class TTTTSWrapper: # TikTok Text-to-Speech Wrapper def tts(self, req_text: str = "TikTok Text To Speech", filename: str = 'title.mp3', random_speaker: bool = False): req_text = req_text.replace("+", "plus").replace(" ", "+").replace("&", "and") + voice = self.randomvoice() if random_speaker else 'en_us_002' - r = requests.post(f"{self.URI_BASE}{voice}&req_text={req_text}&speaker_map_type=0") - vstr = [r.json()["data"]["v_str"]][0] + chunks = [m.group().strip() for m in re.finditer(r' *((.{0,200})(\.|.$))',req_text)] + + audio_clips = [] + + chunkId = 0 + for chunk in chunks: + r = requests.post(f"{self.URI_BASE}{voice}&req_text={chunk}&speaker_map_type=0") + vstr = [r.json()["data"]["v_str"]][0] + b64d = base64.b64decode(vstr) + + with open(f"{filename}-{chunkId}", "wb") as out: + out.write(b64d) + + audio_clips.append(AudioFileClip(f"{filename}-{chunkId}")) - b64d = base64.b64decode(vstr) + chunkId = chunkId+1; - with open(filename, "wb") as out: - out.write(b64d) + audio_concat = concatenate_audioclips(audio_clips) + audio_composite = CompositeAudioClip([audio_concat]) + audio_composite.write_audiofile(filename, 44100, 2, 2000, None) @staticmethod def randomvoice(): diff --git a/video_creation/data/cookie.json b/video_creation/data/cookie-dark-mode.json similarity index 73% rename from video_creation/data/cookie.json rename to video_creation/data/cookie-dark-mode.json index 2e4e116..1ed51a9 100644 --- a/video_creation/data/cookie.json +++ b/video_creation/data/cookie-dark-mode.json @@ -4,5 +4,11 @@ "value": "eyJwcmVmcyI6eyJ0b3BDb250ZW50RGlzbWlzc2FsVGltZSI6MCwiZ2xvYmFsVGhlbWUiOiJSRURESVQiLCJuaWdodG1vZGUiOnRydWUsImNvbGxhcHNlZFRyYXlTZWN0aW9ucyI6eyJmYXZvcml0ZXMiOmZhbHNlLCJtdWx0aXMiOmZhbHNlLCJtb2RlcmF0aW5nIjpmYWxzZSwic3Vic2NyaXB0aW9ucyI6ZmFsc2UsInByb2ZpbGVzIjpmYWxzZX0sInRvcENvbnRlbnRUaW1lc0Rpc21pc3NlZCI6MH19", "domain": ".reddit.com", "path": "/" + }, + { + "name": "eu_cookie", + "value": "{%22opted%22:true%2C%22nonessential%22:false}", + "domain": ".reddit.com", + "path": "/" } ] diff --git a/video_creation/data/cookie-light-mode.json b/video_creation/data/cookie-light-mode.json new file mode 100644 index 0000000..87eeec9 --- /dev/null +++ b/video_creation/data/cookie-light-mode.json @@ -0,0 +1,8 @@ +[ + { + "name": "eu_cookie", + "value": "{%22opted%22:true%2C%22nonessential%22:false}", + "domain": ".reddit.com", + "path": "/" + } +] diff --git a/video_creation/screenshot_downloader.py b/video_creation/screenshot_downloader.py index 12ea28d..48797c3 100644 --- a/video_creation/screenshot_downloader.py +++ b/video_creation/screenshot_downloader.py @@ -26,9 +26,11 @@ def download_screenshots_of_reddit_posts(reddit_object, screenshot_num): context = browser.new_context() if getenv("THEME").upper() == "DARK": - cookie_file = open('./video_creation/data/cookie.json') - cookies = json.load(cookie_file) - context.add_cookies(cookies) + cookie_file = open('./video_creation/data/cookie-dark-mode.json') + else: + cookie_file = open('./video_creation/data/cookie-light-mode.json') + cookies = json.load(cookie_file) + context.add_cookies(cookies) # Get the thread screenshot page = context.new_page() page.goto(reddit_object["thread_url"])