Added the stroy mode with two method and add min comment lenght

pull/1288/head
Syed Aman Raza 3 years ago committed by GitHub
parent 1bf9b34c9b
commit 1424b3edd5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -13,8 +13,7 @@ from utils.console import print_step, print_substep
from utils.voice import sanitize_text from utils.voice import sanitize_text
from utils import settings from utils import settings
DEFAULT_MAX_LENGTH: int = 50 # video length variable DEFAULT_MAX_LENGTH: int = 40 # video length variable
class TTSEngine: class TTSEngine:
@ -40,6 +39,7 @@ class TTSEngine:
): ):
self.tts_module = tts_module() self.tts_module = tts_module()
self.reddit_object = reddit_object self.reddit_object = reddit_object
self.redditid = re.sub(r"[^\w\s-]", "", reddit_object["thread_id"]) self.redditid = re.sub(r"[^\w\s-]", "", reddit_object["thread_id"])
self.path = path + self.redditid + "/mp3" self.path = path + self.redditid + "/mp3"
self.max_length = max_length self.max_length = max_length
@ -49,38 +49,41 @@ class TTSEngine:
def run(self) -> Tuple[int, int]: def run(self) -> Tuple[int, int]:
Path(self.path).mkdir(parents=True, exist_ok=True) Path(self.path).mkdir(parents=True, exist_ok=True)
# This file needs to be removed in case this post does not use post text, so that it won't appear in the final video
try:
Path(f"{self.path}/posttext.mp3").unlink()
except OSError:
pass
print_step("Saving Text to MP3 files...") print_step("Saving Text to MP3 files...")
self.call_tts("title", process_text(self.reddit_object["thread_title"])) self.call_tts("title", process_text(self.reddit_object["thread_title"]))
processed_text = process_text(self.reddit_object["thread_post"]) # processed_text = ##self.reddit_object["thread_post"] != ""
if processed_text != "" and settings.config["settings"]["storymode"] == True:
self.call_tts("posttext", processed_text)
idx = None idx = None
for idx, comment in track(enumerate(self.reddit_object["comments"]), "Saving..."): if settings.config["settings"]["storymode"] :
# ! Stop creating mp3 files if the length is greater than max length. if settings.config["settings"]["storymodemethode"] == 0:
if self.length > self.max_length: if (len(self.reddit_object["thread_post"]) > self.tts_module.max_chars):
self.length -= self.last_clip_length self.split_post(self.reddit_object["thread_post"], "postaudio")
idx -= 1 else :
break self.call_tts("postaudio",process_text(self.reddit_object["thread_post"]) )
if ( elif settings.config["settings"]["storymodemethode"] == 1:
len(comment["comment_body"]) > self.tts_module.max_chars
): # Split the comment if it is too long for idx,text in enumerate(self.reddit_object["thread_post"]):
self.split_post(comment["comment_body"], idx) # Split the comment self.call_tts(f"posttext-{idx}",process_text(text) )
else: # If the comment is not too long, just call the tts engine
self.call_tts(f"{idx}", process_text(comment["comment_body"])) else :
for idx, comment in track(enumerate(self.reddit_object["comments"]), "Saving..."):
# ! Stop creating mp3 files if the length is greater than max length.
if self.length > self.max_length and idx > 1:
self.length -= self.last_clip_length
idx -= 1
break
if (
len(comment["comment_body"]) > self.tts_module.max_chars
): # Split the comment if it is too long
self.split_post(comment["comment_body"], idx) # Split the comment
else: # If the comment is not too long, just call the tts engine
self.call_tts(f"{idx}", process_text(comment["comment_body"]))
print_substep("Saved Text to MP3 files successfully.", style="bold green") print_substep("Saved Text to MP3 files successfully.", style="bold green")
return self.length, idx return self.length, idx
def split_post(self, text: str, idx: int): def split_post(self, text: str, idx):
split_files = [] split_files = []
split_text = [ split_text = [
x.group().strip() x.group().strip()

@ -10,6 +10,7 @@ from utils.console import print_step, print_substep
from utils.subreddit import get_subreddit_undone from utils.subreddit import get_subreddit_undone
from utils.videos import check_done from utils.videos import check_done
from utils.voice import sanitize_text from utils.voice import sanitize_text
from utils.posttextparser import posttextparser
def get_subreddit_threads(POST_ID: str): def get_subreddit_threads(POST_ID: str):
@ -70,6 +71,7 @@ def get_subreddit_threads(POST_ID: str):
if POST_ID: # would only be called if there are multiple queued posts if POST_ID: # would only be called if there are multiple queued posts
submission = reddit.submission(id=POST_ID) submission = reddit.submission(id=POST_ID)
elif ( elif (
settings.config["reddit"]["thread"]["post_id"] settings.config["reddit"]["thread"]["post_id"]
and len(str(settings.config["reddit"]["thread"]["post_id"]).split("+")) == 1 and len(str(settings.config["reddit"]["thread"]["post_id"]).split("+")) == 1
@ -92,32 +94,40 @@ def get_subreddit_threads(POST_ID: str):
content["thread_url"] = f"https://reddit.com{submission.permalink}" content["thread_url"] = f"https://reddit.com{submission.permalink}"
content["thread_title"] = submission.title content["thread_title"] = submission.title
content["thread_post"] = submission.selftext
content["thread_id"] = submission.id content["thread_id"] = submission.id
content["comments"] = [] content["comments"] = []
if settings.config["settings"]["storymode"]:
for top_level_comment in submission.comments: if settings.config["settings"]["storymodemethode"] == 1:
if isinstance(top_level_comment, MoreComments): content["thread_post"] = posttextparser(submission.selftext)
continue else:
if top_level_comment.body in ["[removed]", "[deleted]"]: content["thread_post"] =submission.selftext
continue # # see https://github.com/JasonLovesDoggo/RedditVideoMakerBot/issues/78 else:
if not top_level_comment.stickied: for top_level_comment in submission.comments:
sanitised = sanitize_text(top_level_comment.body) if isinstance(top_level_comment, MoreComments):
if not sanitised or sanitised == " ":
continue continue
if len(top_level_comment.body) <= int( if top_level_comment.body in ["[removed]", "[deleted]"]:
continue # # see https://github.com/JasonLovesDoggo/RedditVideoMakerBot/issues/78
if not top_level_comment.stickied:
sanitised = sanitize_text(top_level_comment.body)
if not sanitised or sanitised == " ":
continue
if len(top_level_comment.body) <= int(
settings.config["reddit"]["thread"]["max_comment_length"] settings.config["reddit"]["thread"]["max_comment_length"]
): ):
if ( if len(top_level_comment.body)>= int(
top_level_comment.author is not None settings.config["reddit"]["thread"]["min_comment_length"]
and sanitize_text(top_level_comment.body) is not None ):
): # if errors occur with this change to if not.
content["comments"].append( if (
{ top_level_comment.author is not None
"comment_body": top_level_comment.body, and sanitize_text(top_level_comment.body) is not None
"comment_url": top_level_comment.permalink, ): # if errors occur with this change to if not.
"comment_id": top_level_comment.id, content["comments"].append(
} {
) "comment_body": top_level_comment.body,
"comment_url": top_level_comment.permalink,
"comment_id": top_level_comment.id,
}
)
print_substep("Received subreddit threads Successfully.", style="bold green") print_substep("Received subreddit threads Successfully.", style="bold green")
return content return content

@ -11,8 +11,9 @@ random = { optional = true, options = [true, false,], default = false, type = "b
subreddit = { optional = false, regex = "[_0-9a-zA-Z]+$", nmin = 3, explanation = "What subreddit to pull posts from, the name of the sub, not the URL. You can have multiple subreddits, add an + with no spaces.", example = "AskReddit+Redditdev", oob_error = "A subreddit name HAS to be between 3 and 20 characters" } subreddit = { optional = false, regex = "[_0-9a-zA-Z]+$", nmin = 3, explanation = "What subreddit to pull posts from, the name of the sub, not the URL. You can have multiple subreddits, add an + with no spaces.", example = "AskReddit+Redditdev", oob_error = "A subreddit name HAS to be between 3 and 20 characters" }
post_id = { optional = true, default = "", regex = "^((?!://|://)[+a-zA-Z0-9])*$", explanation = "Used if you want to use a specific post.", example = "urdtfx" } post_id = { optional = true, default = "", regex = "^((?!://|://)[+a-zA-Z0-9])*$", explanation = "Used if you want to use a specific post.", example = "urdtfx" }
max_comment_length = { default = 500, optional = false, nmin = 10, nmax = 10000, type = "int", explanation = "max number of characters a comment can have. default is 500", example = 500, oob_error = "the max comment length should be between 10 and 10000" } max_comment_length = { default = 500, optional = false, nmin = 10, nmax = 10000, type = "int", explanation = "max number of characters a comment can have. default is 500", example = 500, oob_error = "the max comment length should be between 10 and 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" } post_lang = { default = "", optional = true, explanation = "The language you would like to translate to.", example = "es-cr" }
min_comments = { default = 20, optional = false, nmin = 15, 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" } 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" }
[settings] [settings]
@ -22,7 +23,7 @@ times_to_run = { optional = false, default = 1, example = 2, explanation = "Used
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" } 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, not yet implemented" } storymode = { optional = true, type = "bool", default = false, example = false, options = [true, false,], explanation = "Only read out title and post content, not yet implemented" }
storymodemethode= { optional = true, default = 1, example = 1, explanation = "Method to for storymode. Set to an int e.g.0 or 1", type = "int", nmin = 0, oob_error = "It's very hard to run something less than once." }
[settings.background] [settings.background]
background_choice = { optional = true, default = "minecraft", example = "rocket-league", options = ["minecraft", "gta", "rocket-league", "motor-gta", "csgo-surf", "cluster-truck", ""], explanation = "Sets the background for the video based on game name" } background_choice = { optional = true, default = "minecraft", example = "rocket-league", options = ["minecraft", "gta", "rocket-league", "motor-gta", "csgo-surf", "cluster-truck", ""], explanation = "Sets the background for the video based on game name" }

@ -0,0 +1,41 @@
from PIL import Image, ImageDraw,ImageFont
import textwrap
import re
def draw_multiple_line_text(image, text, font, text_color,padding):
'''
Draw multiline text over given image
'''
draw = ImageDraw.Draw(image)
Fontperm= font.getsize(text)
image_width, image_height = image.size
lines = textwrap.wrap(text, width=50)
y=(image_height/2)-(((Fontperm[1]+(len(lines)*padding)/len(lines))*len(lines))/2) #dont touch it
for line in lines:
line_width, line_height = font.getsize(line)
draw.text(((image_width - line_width) / 2, y),
line, font=font, fill=text_color)
y += line_height + padding
def imagemaker(text,
reddit_obj,
idx='NoName',
padding=5
):
id = re.sub(r"[^\w\s-]", "", reddit_obj["thread_id"])
font=ImageFont.truetype("arial.ttf", 20)
Fontperm= font.getsize(text)
# print(Fontperm[1])
size=(500,176)
textcolor=(240,240,240)
image =Image.new('RGBA',size,(33,33,36,255))
draw = ImageDraw.Draw(image)
if len(text)>50:
draw_multiple_line_text(image, text,font, textcolor,padding)
else:
draw.text(((image.size[0]-Fontperm[0])/2,(image.size[1]-Fontperm[1])/2),font=font,text=text,align='center') #(image.size[1]/2)-(Fontperm[1]/2)
image.save(f'assets/temp/{id}/png/img{idx}.png')

@ -0,0 +1,46 @@
MAX_CHARACTER= 200
#working good
def posttextparser(obj):
text=obj#["thread_post"]
newtext=[]
# for text in text:
if len(text)>MAX_CHARACTER:
text2=text.split("\n")
for dot in text2:
if len(dot)>MAX_CHARACTER:
text3=dot.split(".")
for comma in text3:
if len(comma)> MAX_CHARACTER:
text4=comma.split(',')
newtext.extend(text4)
else:
newtext.append(comma)
else:
newtext.append(dot)
else:
newtext.append(text)
return remover(newtext)
def remover(List):
reg=['',' ','.','\n',')',"''",'"',"'",'"','""'] #add if any any unwant value found
lines=List
lines1=[]
lines2=[]
for item in lines:
for r in reg :
if item==r:
break
else:
continue
else:
lines1.append(item)
for a in lines1: #Double check
if a!='':
aa=a.strip()
lines2.append(aa)
# print(f'"{a}"')
return lines2

@ -39,6 +39,9 @@ def get_subreddit_undone(submissions: list, subreddit, times_checked=0):
f'This post has under the specified minimum of comments ({settings.config["reddit"]["thread"]["min_comments"]}). Skipping...' f'This post has under the specified minimum of comments ({settings.config["reddit"]["thread"]["min_comments"]}). Skipping...'
) )
continue continue
if settings.config['settings']['storymode'] :
if not submission.is_self :
continue
return submission return submission
print("all submissions have been done going by top submission order") print("all submissions have been done going by top submission order")
VALID_TIME_FILTERS = [ VALID_TIME_FILTERS = [

@ -76,8 +76,18 @@ def make_final_video(
) )
# Gather all audio clips # Gather all audio clips
audio_clips = [AudioFileClip(f"assets/temp/{id}/mp3/{i}.mp3") for i in range(number_of_clips)] if settings.config["settings"]["storymode"]:
audio_clips.insert(0, AudioFileClip(f"assets/temp/{id}/mp3/title.mp3")) if settings.config["settings"]["storymodemethode"] == 0:
audio_clips = [AudioFileClip(f"assets/temp/{id}/mp3/title.mp3")]
audio_clips.insert(1,AudioFileClip(f"assets/temp/{id}/mp3/postaudio.mp3"))
elif settings.config["settings"]["storymodemethode"] == 1:
#here work is not done14
audio_clips = [AudioFileClip(f"assets/temp/{id}/mp3/posttext-{i}.mp3") for i in range(number_of_clips+1)]
audio_clips.insert(0, AudioFileClip(f"assets/temp/{id}/mp3/title.mp3"))
else:
audio_clips = [AudioFileClip(f"assets/temp/{id}/mp3/{i}.mp3") for i in range(number_of_clips)]
audio_clips.insert(0, AudioFileClip(f"assets/temp/{id}/mp3/title.mp3"))
audio_concat = concatenate_audioclips(audio_clips) audio_concat = concatenate_audioclips(audio_clips)
audio_composite = CompositeAudioClip([audio_concat]) audio_composite = CompositeAudioClip([audio_concat])
@ -96,27 +106,40 @@ def make_final_video(
.crossfadein(new_transition) .crossfadein(new_transition)
.crossfadeout(new_transition), .crossfadeout(new_transition),
) )
if settings.config["settings"]["storymode"]:
if settings.config["settings"]["storymodemethode"] == 0:
if os.path.exists(f"assets/temp/{id}/png/story_content.png"):# else: story mode stuff
image_clips.insert(
1,
ImageClip(f"assets/temp/{id}/png/story_content.png")
.set_duration(audio_clips[1].duration)
.set_position("center")
.resize(width=W - 100)
.set_opacity(float(opacity)),
)
elif settings.config["settings"]["storymodemethode"] == 1:
for i in range(0, number_of_clips+1):
image_clips.append(
ImageClip(f"assets/temp/{id}/png/img{i}.png")
.set_duration(audio_clips[i + 1].duration)
.resize(width=W - 100)
.set_opacity(new_opacity)
# .crossfadein(new_transition)
# .crossfadeout(new_transition)
)
else :
for i in range(0, number_of_clips):
image_clips.append(
ImageClip(f"assets/temp/{id}/png/comment_{i}.png")
.set_duration(audio_clips[i + 1].duration)
.resize(width=W - 100)
.set_opacity(new_opacity)
.crossfadein(new_transition)
.crossfadeout(new_transition)
)
for i in range(0, number_of_clips):
image_clips.append(
ImageClip(f"assets/temp/{id}/png/comment_{i}.png")
.set_duration(audio_clips[i + 1].duration)
.resize(width=W - 100)
.set_opacity(new_opacity)
.crossfadein(new_transition)
.crossfadeout(new_transition)
)
# if os.path.exists("assets/mp3/posttext.mp3"):
# image_clips.insert(
# 0,
# ImageClip("assets/png/title.png")
# .set_duration(audio_clips[0].duration + audio_clips[1].duration)
# .set_position("center")
# .resize(width=W - 100)
# .set_opacity(float(opacity)),
# )
# else: story mode stuff
img_clip_pos = background_config[3] img_clip_pos = background_config[3]
image_concat = concatenate_videoclips(image_clips).set_position( image_concat = concatenate_videoclips(image_clips).set_position(
img_clip_pos img_clip_pos
@ -143,6 +166,7 @@ def make_final_video(
final = Video(final).add_watermark( final = Video(final).add_watermark(
text=f"Background credit: {background_config[2]}", opacity=0.4, redditid=reddit_obj text=f"Background credit: {background_config[2]}", opacity=0.4, redditid=reddit_obj
) )
final.write_videofile( final.write_videofile(
f"assets/temp/{id}/temp.mp4", f"assets/temp/{id}/temp.mp4",
fps=30, fps=30,

@ -11,10 +11,10 @@ from playwright.async_api import async_playwright # pylint: disable=unused-impo
from playwright.sync_api import sync_playwright, ViewportSize from playwright.sync_api import sync_playwright, ViewportSize
from rich.progress import track from rich.progress import track
import translators as ts import translators as ts
from utils.imagenarator import imagemaker
from utils.console import print_step, print_substep from utils.console import print_step, print_substep
storymode = False
def download_screenshots_of_reddit_posts(reddit_object: dict, screenshot_num: int): def download_screenshots_of_reddit_posts(reddit_object: dict, screenshot_num: int):
@ -32,7 +32,7 @@ def download_screenshots_of_reddit_posts(reddit_object: dict, screenshot_num: in
with sync_playwright() as p: with sync_playwright() as p:
print_substep("Launching Headless Browser...") print_substep("Launching Headless Browser...")
browser = p.chromium.launch() browser = p.chromium.launch() #headless=False #to check for chrome view
context = browser.new_context() context = browser.new_context()
if settings.config["settings"]["theme"] == "dark": if settings.config["settings"]["theme"] == "dark":
@ -76,10 +76,18 @@ def download_screenshots_of_reddit_posts(reddit_object: dict, screenshot_num: in
postcontentpath = f"assets/temp/{id}/png/title.png" postcontentpath = f"assets/temp/{id}/png/title.png"
page.locator('[data-test-id="post-content"]').screenshot(path= postcontentpath) page.locator('[data-test-id="post-content"]').screenshot(path= postcontentpath)
if storymode: if reddit_object["thread_post"] != "" and settings.config["settings"]["storymode"] == True:
page.locator('[data-click-id="text"]').screenshot( if settings.config["settings"]["storymodemethode"] == 0:
path=f"assets/temp/{id}/png/story_content.png" try : #new change
) page.locator('[data-click-id="text"]').first.screenshot(
path=f"assets/temp/{id}/png/story_content.png"
)
except:
exit
elif settings.config["settings"]["storymodemethode"] == 1:
for idx,item in enumerate(reddit_object["thread_post"]):
imagemaker(item,idx=idx,reddit_obj=reddit_object)
else: else:
for idx, comment in enumerate( for idx, comment in enumerate(
track(reddit_object["comments"], "Downloading screenshots...") track(reddit_object["comments"], "Downloading screenshots...")

Loading…
Cancel
Save