Added the stroy mode with two method and add min comment lenght
This commit is contained in:
1 parent
1bf9b34c9b
commit
1424b3edd5
8 files changed
+221
-85
No files matched your search
+31
-28
@@ -13,8 +13,7 @@ from utils.console import print_step, print_substep
|
||||
from utils.voice import sanitize_text
|
||||
from utils import settings
|
||||
|
||||
DEFAULT_MAX_LENGTH: int = 50 # video length variable
|
||||
|
||||
DEFAULT_MAX_LENGTH: int = 40 # video length variable
|
||||
|
||||
class TTSEngine:
|
||||
|
||||
@@ -40,6 +39,7 @@ class TTSEngine:
|
||||
):
|
||||
self.tts_module = tts_module()
|
||||
self.reddit_object = reddit_object
|
||||
|
||||
self.redditid = re.sub(r"[^\w\s-]", "", reddit_object["thread_id"])
|
||||
self.path = path + self.redditid + "/mp3"
|
||||
self.max_length = max_length
|
||||
@@ -48,39 +48,42 @@ class TTSEngine:
|
||||
|
||||
def run(self) -> Tuple[int, int]:
|
||||
|
||||
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
|
||||
|
||||
Path(self.path).mkdir(parents=True, exist_ok=True)
|
||||
print_step("Saving Text to MP3 files...")
|
||||
|
||||
|
||||
self.call_tts("title", process_text(self.reddit_object["thread_title"]))
|
||||
processed_text = process_text(self.reddit_object["thread_post"])
|
||||
if processed_text != "" and settings.config["settings"]["storymode"] == True:
|
||||
self.call_tts("posttext", processed_text)
|
||||
|
||||
# processed_text = ##self.reddit_object["thread_post"] != ""
|
||||
idx = None
|
||||
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:
|
||||
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"]))
|
||||
if settings.config["settings"]["storymode"] :
|
||||
if settings.config["settings"]["storymodemethode"] == 0:
|
||||
if (len(self.reddit_object["thread_post"]) > self.tts_module.max_chars):
|
||||
self.split_post(self.reddit_object["thread_post"], "postaudio")
|
||||
else :
|
||||
self.call_tts("postaudio",process_text(self.reddit_object["thread_post"]) )
|
||||
elif settings.config["settings"]["storymodemethode"] == 1:
|
||||
|
||||
for idx,text in enumerate(self.reddit_object["thread_post"]):
|
||||
self.call_tts(f"posttext-{idx}",process_text(text) )
|
||||
|
||||
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")
|
||||
return self.length, idx
|
||||
|
||||
def split_post(self, text: str, idx: int):
|
||||
def split_post(self, text: str, idx):
|
||||
split_files = []
|
||||
split_text = [
|
||||
x.group().strip()
|
||||
|
||||
+33
-23
@@ -10,6 +10,7 @@ from utils.console import print_step, print_substep
|
||||
from utils.subreddit import get_subreddit_undone
|
||||
from utils.videos import check_done
|
||||
from utils.voice import sanitize_text
|
||||
from utils.posttextparser import posttextparser
|
||||
|
||||
|
||||
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
|
||||
submission = reddit.submission(id=POST_ID)
|
||||
|
||||
elif (
|
||||
settings.config["reddit"]["thread"]["post_id"]
|
||||
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_title"] = submission.title
|
||||
content["thread_post"] = submission.selftext
|
||||
content["thread_id"] = submission.id
|
||||
content["comments"] = []
|
||||
|
||||
for top_level_comment in submission.comments:
|
||||
if isinstance(top_level_comment, MoreComments):
|
||||
continue
|
||||
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 == " ":
|
||||
if settings.config["settings"]["storymode"]:
|
||||
if settings.config["settings"]["storymodemethode"] == 1:
|
||||
content["thread_post"] = posttextparser(submission.selftext)
|
||||
else:
|
||||
content["thread_post"] =submission.selftext
|
||||
else:
|
||||
for top_level_comment in submission.comments:
|
||||
if isinstance(top_level_comment, MoreComments):
|
||||
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"]
|
||||
):
|
||||
if (
|
||||
top_level_comment.author is not None
|
||||
and sanitize_text(top_level_comment.body) is not None
|
||||
): # if errors occur with this change to if not.
|
||||
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)>= int(
|
||||
settings.config["reddit"]["thread"]["min_comment_length"]
|
||||
):
|
||||
|
||||
if (
|
||||
top_level_comment.author is not None
|
||||
and sanitize_text(top_level_comment.body) is not None
|
||||
): # if errors occur with this change to if not.
|
||||
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")
|
||||
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" }
|
||||
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" }
|
||||
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" }
|
||||
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]
|
||||
@@ -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" }
|
||||
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" }
|
||||
|
||||
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]
|
||||
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...'
|
||||
)
|
||||
continue
|
||||
if settings.config['settings']['storymode'] :
|
||||
if not submission.is_self :
|
||||
continue
|
||||
return submission
|
||||
print("all submissions have been done going by top submission order")
|
||||
VALID_TIME_FILTERS = [
|
||||
|
||||
@@ -74,10 +74,20 @@ def make_final_video(
|
||||
.resize(height=H)
|
||||
.crop(x1=1166.6, y1=0, x2=2246.6, y2=1920)
|
||||
)
|
||||
|
||||
|
||||
# Gather all audio clips
|
||||
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"))
|
||||
if settings.config["settings"]["storymode"]:
|
||||
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_composite = CompositeAudioClip([audio_concat])
|
||||
|
||||
@@ -96,27 +106,40 @@ def make_final_video(
|
||||
.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
|
||||
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)
|
||||
)
|
||||
|
||||
|
||||
|
||||
img_clip_pos = background_config[3]
|
||||
image_concat = concatenate_videoclips(image_clips).set_position(
|
||||
img_clip_pos
|
||||
@@ -143,6 +166,7 @@ def make_final_video(
|
||||
final = Video(final).add_watermark(
|
||||
text=f"Background credit: {background_config[2]}", opacity=0.4, redditid=reddit_obj
|
||||
)
|
||||
|
||||
final.write_videofile(
|
||||
f"assets/temp/{id}/temp.mp4",
|
||||
fps=30,
|
||||
@@ -156,7 +180,7 @@ def make_final_video(
|
||||
0,
|
||||
length,
|
||||
targetname=f"results/{subreddit}/{filename}",
|
||||
)
|
||||
)
|
||||
save_data(subreddit, filename, title, idx, background_config[2])
|
||||
print_step("Removing temporary files 🗑")
|
||||
cleanups = cleanup(id)
|
||||
|
||||
@@ -11,10 +11,10 @@ from playwright.async_api import async_playwright # pylint: disable=unused-impo
|
||||
from playwright.sync_api import sync_playwright, ViewportSize
|
||||
from rich.progress import track
|
||||
import translators as ts
|
||||
|
||||
from utils.imagenarator import imagemaker
|
||||
from utils.console import print_step, print_substep
|
||||
|
||||
storymode = False
|
||||
|
||||
|
||||
|
||||
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:
|
||||
print_substep("Launching Headless Browser...")
|
||||
|
||||
browser = p.chromium.launch()
|
||||
browser = p.chromium.launch() #headless=False #to check for chrome view
|
||||
context = browser.new_context()
|
||||
|
||||
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"
|
||||
page.locator('[data-test-id="post-content"]').screenshot(path= postcontentpath)
|
||||
|
||||
if storymode:
|
||||
page.locator('[data-click-id="text"]').screenshot(
|
||||
path=f"assets/temp/{id}/png/story_content.png"
|
||||
)
|
||||
if reddit_object["thread_post"] != "" and settings.config["settings"]["storymode"] == True:
|
||||
if settings.config["settings"]["storymodemethode"] == 0:
|
||||
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:
|
||||
for idx, comment in enumerate(
|
||||
track(reddit_object["comments"], "Downloading screenshots...")
|
||||
|
||||
Reference in new issue
Block a user