merged develop

pull/963/head
Drugsosos 2 years ago
commit 62ac8fe0b0
No known key found for this signature in database
GPG Key ID: 8E35176FE617E28D

@ -12,11 +12,11 @@ password = { optional = false, nmin = 8, explanation = "the password of your red
random = { optional = true, options = [true, random = { optional = true, options = [true,
false, false,
], default = false, type = "bool", explanation = "If set to no, it will ask you a thread link to extract the thread, if yes it will randomize it. Default: 'False'", example = "True" } ], default = false, type = "bool", explanation = "If set to no, it will ask you a thread link to extract the thread, if yes it will randomize it. Default: 'False'", example = "True" }
subreddit = { optional = false, regex = "[_0-9a-zA-Z]+$", nmin = 3, nmax = 21, explanation = "what subreddit to pull posts from, the name of the sub, not the URL", example = "AskReddit", 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", example = "AskReddit", oob_error = "A subreddit name HAS to be between 3 and 20 characters" }
post_id = { optional = true, default = "", regex = "^((?!://|://)[+a-zA-Z])*$", explanation = "Used if you want to use a specific post.", example = "urdtfx" } post_id = { optional = true, default = "", regex = "^((?!://|://)[+a-zA-Z])*$", 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" }
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" }
[settings] [settings]
allow_nsfw = { optional = false, type = "bool", default = false, example = false, options = [true, allow_nsfw = { optional = false, type = "bool", default = false, example = false, options = [true,
false, false,
@ -29,10 +29,15 @@ opacity = { optional = false, default = 0.9, example = 0.8, explanation = "Sets
storymode = { optional = true, type = "bool", default = false, example = false, options = [true, storymode = { optional = true, type = "bool", default = false, example = false, options = [true,
false, false,
], explanation = "not yet implemented" } ], explanation = "not yet implemented" }
[settings.background]
background_choice = { optional = true, default = "minecraft", example = "minecraft", options = ["minecraft", "gta", "rocket-league", "motor-gta", ""], explanation = "Sets the background for the video" } background_choice = { optional = true, default = "minecraft", example = "minecraft", options = ["minecraft", "gta", "rocket-league", "motor-gta", ""], explanation = "Sets the background for the video" }
background_audio = { optional = true, type = "bool", default = false, example = false, options = [true, #background_audio = { optional = true, type = "bool", default = false, example = false, options = [true,
false, # false,
], explaination="Sets a audio to play in the background (put a background.mp3 file in the assets/backgrounds directory for it to be used.)" } #], explaination="Sets a audio to play in the background (put a background.mp3 file in the assets/backgrounds directory for it to be used.)" }
#background_audio_volume = { optional = true, type = "float", default = 0.3, example = 0.1, explanation="Sets the volume of the background audio. only used if the background_audio is also set to true" }
[settings.tts] [settings.tts]
choice = { optional = false, default = "", options = ["streamlabspolly", "tiktok", "googletranslate", "awspolly", ], example = "streamlabspolly", explanation = "The backend used for TTS generation. This can be left blank and you will be prompted to choose at runtime." } choice = { optional = false, default = "", options = ["streamlabspolly", "tiktok", "googletranslate", "awspolly", ], example = "streamlabspolly", explanation = "The backend used for TTS generation. This can be left blank and you will be prompted to choose at runtime." }
aws_polly_voice = { optional = false, default = "Matthew", example = "Matthew", explanation = "The voice used for AWS Polly" } aws_polly_voice = { optional = false, default = "Matthew", example = "Matthew", explanation = "The voice used for AWS Polly" }

@ -0,0 +1,281 @@
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta http-equiv="cache-control" content="no-cache"/>
<title>RedditVideoMakerBot</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.1.3/dist/css/bootstrap.min.css" integrity="sha384-MCw98/SFnGE8fJT3GXwEOngsV7Zt27NXFoaoApmYm81iuXoPkFOJwJ8ERdknLPMO" crossorigin="anonymous">
<link href="https://getbootstrap.com/docs/5.2/dist/css/bootstrap.min.css" rel="stylesheet">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.8.3/font/bootstrap-icons.css">
<style>
.bd-placeholder-img {
font-size: 1.125rem;
text-anchor: middle;
-webkit-user-select: none;
-moz-user-select: none;
user-select: none;
}
@media (min-width: 768px) {
.bd-placeholder-img-lg {
font-size: 3.5rem;
}
}
.b-example-divider {
height: 3rem;
background-color: rgba(0, 0, 0, .1);
border: solid rgba(0, 0, 0, .15);
border-width: 1px 0;
box-shadow: inset 0 .5em 1.5em rgba(0, 0, 0, .1), inset 0 .125em .5em rgba(0, 0, 0, .15);
}
.b-example-vr {
flex-shrink: 0;
width: 1.5rem;
height: 100vh;
}
.bi {
vertical-align: -.125em;
fill: currentColor;
}
.nav-scroller {
position: relative;
z-index: 2;
height: 2.75rem;
overflow-y: hidden;
}
.nav-scroller .nav {
display: flex;
flex-wrap: nowrap;
padding-bottom: 1rem;
margin-top: -1px;
overflow-x: auto;
text-align: center;
white-space: nowrap;
-webkit-overflow-scrolling: touch;
}
#tooltip {
background-color: #333;
color: white;
padding: 5px 10px;
border-radius: 4px;
font-size: 13px;
}
</style>
</head>
<body>
<header>
<div class="navbar navbar-dark bg-dark shadow-sm">
<div class="container">
<a href="#" class="navbar-brand d-flex align-items-center">
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" aria-hidden="true" class="me-2" viewBox="0 0 24 24"><path d="M23 19a2 2 0 0 1-2 2H3a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h4l2-3h6l2 3h4a2 2 0 0 1 2 2z"/><circle cx="12" cy="13" r="4"/></svg>
<strong>RedditVideoMakerBot</strong>
</a>
</div>
</div>
</header>
<main>
<div class="album py-2 bg-light">
<div class="container">
<div class="row mt-2">
<div class="col-12 col-md-3 mb-3">
<input type="text" class="form-control" placeholder="Search videos" aria-label="Search videos" onkeyup="searchFilter()">
</div>
</div>
<div class="grid row row-cols-1 row-cols-sm-2 row-cols-md-3 g-3" id="videos">
</div>
</div>
</div>
</main>
<footer class="text-muted py-5">
<div class="container">
<p class="float-end mb-1">
<a href="#">Back to top</a>
</p>
<p class="mb-1"><a href="https://getbootstrap.com/docs/5.2/examples/album/" target="_blank">Album</a> Example Theme by &copy; Bootstrap. <a href="https://github.com/elebumm/RedditVideoMakerBot/blob/master/README.md#developers-and-maintainers" target="_blank">Developers and Maintainers</a></p>
<p class="mb-0">If your data is not refreshing, try to hard reload(Ctrl + F5) and visit your local <a href="../video_creation/data/videos.json" target="_blank">videos.json</a> file.</p>
</div>
</footer>
<script src="https://code.jquery.com/jquery-3.1.1.js" integrity="sha256-16cdPddA6VdVInumRGo6IbivbERE8p7CQR3HzTBuELA=" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/popper.js@1.14.3/dist/umd/popper.min.js" integrity="sha384-ZMP7rVo3mIykV+2+9J3UJ46jBk0WLaUAdn689aCwoqbBJiSnjAK/l8WvCWPIPm49" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@4.1.3/dist/js/bootstrap.min.js" integrity="sha384-ChfqqxuZUCnJSK3+MXmPNIyE6ZbWh2IMqE241rYiqJxyMiZ6OW/JmZQ5stwEULTy" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/clipboard.js/2.0.10/clipboard.min.js"></script>
<script src="https://unpkg.com/isotope-layout@3/dist/isotope.pkgd.js"></script>
<script>
const intervals = [
{ label: 'year', seconds: 31536000 },
{ label: 'month', seconds: 2592000 },
{ label: 'day', seconds: 86400 },
{ label: 'hour', seconds: 3600 },
{ label: 'minute', seconds: 60 },
{ label: 'second', seconds: 1 }
];
function timeSince(date) {
const seconds = Math.floor((Date.now() / 1000 - date));
const interval = intervals.find(i => i.seconds < seconds);
const count = Math.floor(seconds / interval.seconds);
return `${count} ${interval.label}${count !== 1 ? 's' : ''} ago`;
}
$(document).ready(function () {
$.getJSON("../video_creation/data/videos.json",
function (data) {
data.sort((b, a) => a['time'] - b['time'])
var video = '';
$.each(data, function (key, value) {
video += '<div class="col">';
video += '<div class="card shadow-sm">';
//keeping original themed image card for future thumbnail usage video += '<svg class="bd-placeholder-img card-img-top" width="100%" height="225" xmlns="http://www.w3.org/2000/svg" role="img" aria-label="Placeholder: Thumbnail" preserveAspectRatio="xMidYMid slice" focusable="false"><title>Placeholder</title><rect width="100%" height="100%" fill="#55595c"/><text x="50%" y="50%" fill="#eceeef" dy=".3em">r/'+value.subreddit+'</text></svg>';
video += '<div class="card-body">';
video += '<p class="card-text">r/'+value.subreddit+' • '+checkTitle(value.reddit_title, value.filename)+'</p>';
video += '<div class="d-flex justify-content-between align-items-center">';
video += '<div class="btn-group">';
video += '<a href="https://www.reddit.com/r/'+value.subreddit+'/comments/'+value.id+'/" class="btn btn-sm btn-outline-secondary" target="_blank">View</a>';
video += '<a href="results/'+value.subreddit+'/'+value.filename+'" class="btn btn-sm btn-outline-secondary" download>Download</a>';
video += '</div>';
video += '<div class="btn-group">';
video += '<button type="button" data-toggle="tooltip" id="copy" data-original-title="Copy to clipboard" class="btn btn-sm btn-outline-secondary" data-clipboard-text="'+getCopyData(value.subreddit, value.reddit_title, value.filename, value.background_credit)+'"><i class="bi bi-card-text"></i></button>';
video += '<button type="button" data-toggle="tooltip" id="copy" data-original-title="Copy to clipboard" class="btn btn-sm btn-outline-secondary" data-clipboard-text="'+checkTitle(value.reddit_title, value.filename)+' #Shorts #reddit"><i class="bi bi-youtube"></i></button>';
video += '<button type="button" data-toggle="tooltip" id="copy" data-original-title="Copy to clipboard" class="btn btn-sm btn-outline-secondary" data-clipboard-text="'+checkTitle(value.reddit_title, value.filename)+' #reddit"><i class="bi bi-instagram"></i></button>';
video += '</div>';
video += '<small class="text-muted">'+timeSince(value.time)+'</small>';
video += '</div>';
video += '</div>';
video += '</div>';
video += '</div>';
});
$('#videos').append(video);
});
});
$(document).ready(function(){
$('[data-toggle="tooltip"]').tooltip();
$('[data-toggle="tooltip"]').on('click', function(){
$(this).tooltip('hide');
});
});
$('#copy').tooltip({
trigger: 'click',
placement: 'bottom'
});
function setTooltip(btn, message) {
$(btn).tooltip('hide')
.attr('data-original-title', message)
.tooltip('show');
}
function hoverTooltip(btn, message) {
$(btn).tooltip('hide')
.attr('data-original-title', message)
.tooltip('show');
}
function hideTooltip(btn) {
setTimeout(function() {
$(btn).tooltip('hide');
}, 1000);
}
function disposeTooltip(btn) {
setTimeout(function() {
$(btn).tooltip('dispose');
}, 1500);
}
var clipboard = new ClipboardJS('#copy');
clipboard.on('success', function(e) {
e.clearSelection();
console.info('Action:', e.action);
console.info('Text:', e.text);
console.info('Trigger:', e.trigger);
setTooltip(e.trigger, 'Copied!');
hideTooltip(e.trigger);
disposeTooltip(e.trigger);
});
clipboard.on('error', function(e) {
console.error('Action:', e.action);
console.error('Trigger:', e.trigger);
setTooltip(e.trigger, fallbackMessage(e.action));
hideTooltip(e.trigger);
});
function getCopyData(subreddit, reddit_title, filename, background_credit){
if (subreddit == undefined) {
subredditCopy = "";
} else {
subredditCopy = "r/" + subreddit + "\n\n";
}
const file = filename.slice(0, -4);
if (reddit_title == file) {
titleCopy = reddit_title;
} else {
titleCopy = file;
}
var copyData = "";
copyData += subredditCopy;
copyData += titleCopy;
copyData += "\n\nBackground credit: " + background_credit;
return copyData;
}
function getLink(subreddit, id, reddit_title) {
if (subreddit == undefined) {
return reddit_title;
} else {
return "<a target='_blank' href='https://www.reddit.com/r/" + subreddit + "/comments/" + id + "/'>"+ reddit_title +"</a>";
}
}
function checkTitle(reddit_title, filename) {
const file = filename.slice(0, -4);
if (reddit_title == file) {
return reddit_title;
} else {
return file;
}
}
var searchFilter = () => {
const input = document.querySelector(".form-control");
const cards = document.getElementsByClassName("col");
console.log(cards[1])
let filter = input.value
for (let i = 0; i < cards.length; i++) {
let title = cards[i].querySelector(".card-text");
if (title.innerText.toLowerCase().indexOf(filter.toLowerCase()) > -1) {
cards[i].classList.remove("d-none")
} else {
cards[i].classList.add("d-none")
}
}
}
</script>
</body>
</html>

@ -88,3 +88,5 @@ CallumIO (c.#6837) - https://github.com/CallumIO
Verq (Verq#2338) - https://github.com/CordlessCoder Verq (Verq#2338) - https://github.com/CordlessCoder
LukaHietala (Pix.#0001) - https://github.com/LukaHietala LukaHietala (Pix.#0001) - https://github.com/LukaHietala
Freebiell (Freebie#6429) - https://github.com/FreebieII

@ -1,6 +1,6 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
from boto3 import Session from boto3 import Session
from botocore.exceptions import BotoCoreError, ClientError from botocore.exceptions import BotoCoreError, ClientError, ProfileNotFound
import sys import sys
from utils import settings from utils import settings
import random import random
@ -30,36 +30,46 @@ class AWSPolly:
self.voices = voices self.voices = voices
def run(self, text, filepath, random_voice: bool = False): def run(self, text, filepath, random_voice: bool = False):
session = Session(profile_name="polly")
polly = session.client("polly")
if random_voice:
voice = self.randomvoice()
else:
if not settings.config["settings"]["tts"]["aws_polly_voice"]:
return ValueError(
f"Please set the TOML variable AWS_VOICE to a valid voice. options are: {voices}"
)
voice = str(settings.config["settings"]["tts"]["aws_polly_voice"]).capitalize()
try: try:
# Request speech synthesis session = Session(profile_name="polly")
response = polly.synthesize_speech( polly = session.client("polly")
Text=text, OutputFormat="mp3", VoiceId=voice, Engine="neural" if random_voice:
) voice = self.randomvoice()
except (BotoCoreError, ClientError) as error: else:
# The service returned an error, exit gracefully if not settings.config["settings"]["tts"]["aws_polly_voice"]:
print(error) raise ValueError(
sys.exit(-1) f"Please set the TOML variable AWS_VOICE to a valid voice. options are: {voices}"
)
voice = str(settings.config["settings"]["tts"]["aws_polly_voice"]).capitalize()
try:
# Request speech synthesis
response = polly.synthesize_speech(
Text=text, OutputFormat="mp3", VoiceId=voice, Engine="neural"
)
except (BotoCoreError, ClientError) as error:
# The service returned an error, exit gracefully
print(error)
sys.exit(-1)
# Access the audio stream from the response # Access the audio stream from the response
if "AudioStream" in response: if "AudioStream" in response:
file = open(filepath, "wb") file = open(filepath, "wb")
file.write(response["AudioStream"].read()) file.write(response["AudioStream"].read())
file.close() file.close()
# print_substep(f"Saved Text {idx} to MP3 files successfully.", style="bold green") # print_substep(f"Saved Text {idx} to MP3 files successfully.", style="bold green")
else: else:
# The response didn't contain audio data, exit gracefully # The response didn't contain audio data, exit gracefully
print("Could not stream audio") print("Could not stream audio")
sys.exit(-1)
except ProfileNotFound:
print("You need to install the AWS CLI and configure your profile")
print(
"""
Linux: https://docs.aws.amazon.com/polly/latest/dg/setup-aws-cli.html
Windows: https://docs.aws.amazon.com/polly/latest/dg/install-voice-plugin2.html
"""
)
sys.exit(-1) sys.exit(-1)
def randomvoice(self): def randomvoice(self):

@ -82,12 +82,16 @@ class TTSEngine:
r" *(((.|\n){0," + str(self.tts_module().max_chars) + "})(\.|.$))", text r" *(((.|\n){0," + str(self.tts_module().max_chars) + "})(\.|.$))", text
) )
] ]
offset = 0
idy = None
for idy, text_cut in enumerate(split_text): for idy, text_cut in enumerate(split_text):
# print(f"{idx}-{idy}: {text_cut}\n") # print(f"{idx}-{idy}: {text_cut}\n")
self.call_tts(f"{idx}-{idy}.part", text_cut) if not text_cut or text_cut.isspace():
split_files.append(AudioFileClip(f"{self.path}/{idx}-{idy}.part.mp3")) offset += 1
continue
self.call_tts(f"{idx}-{idy - offset}.part", text_cut)
split_files.append(AudioFileClip(f"{self.path}/{idx}-{idy - offset}.part.mp3"))
CompositeAudioClip([concatenate_audioclips(split_files)]).write_audiofile( CompositeAudioClip([concatenate_audioclips(split_files)]).write_audiofile(
f"{self.path}/{idx}.mp3", fps=44100, verbose=False, logger=None f"{self.path}/{idx}.mp3", fps=44100, verbose=False, logger=None
) )

@ -37,8 +37,8 @@ class StreamlabsPolly:
voice = self.randomvoice() voice = self.randomvoice()
else: else:
if not settings.config["settings"]["tts"]["streamlabs_polly_voice"]: if not settings.config["settings"]["tts"]["streamlabs_polly_voice"]:
return ValueError( raise ValueError(
f"Please set the config variable STREAMLABS_VOICE to a valid voice. options are: {voices}" f"Please set the config variable STREAMLABS_POLLY_VOICE to a valid voice. options are: {voices}"
) )
voice = str(settings.config["settings"]["tts"]["streamlabs_polly_voice"]).capitalize() voice = str(settings.config["settings"]["tts"]["streamlabs_polly_voice"]).capitalize()
body = {"voice": voice, "text": text, "service": "polly"} body = {"voice": voice, "text": text, "service": "polly"}

@ -20,7 +20,7 @@ def get_subreddit_threads(
print_substep("Logging into Reddit.") print_substep("Logging into Reddit.")
content = {} content = {}
if settings.config["reddit"]["creds"]["2fa"] == True: if settings.config["reddit"]["creds"]["2fa"]:
print("\nEnter your two-factor authentication code from your authenticator app.\n") print("\nEnter your two-factor authentication code from your authenticator app.\n")
code = input("> ") code = input("> ")
print() print()
@ -29,7 +29,7 @@ def get_subreddit_threads(
else: else:
passkey = settings.config["reddit"]["creds"]["password"] passkey = settings.config["reddit"]["creds"]["password"]
username = settings.config["reddit"]["creds"]["username"] username = settings.config["reddit"]["creds"]["username"]
if username.casefold().startswith("u/"): if str(username).casefold().startswith("u/"):
username = username[2:] username = username[2:]
reddit = praw.Reddit( reddit = praw.Reddit(
client_id=settings.config["reddit"]["creds"]["client_id"], client_id=settings.config["reddit"]["creds"]["client_id"],
@ -57,7 +57,7 @@ def get_subreddit_threads(
sub = settings.config["reddit"]["thread"]["subreddit"] sub = settings.config["reddit"]["thread"]["subreddit"]
print_substep(f"Using subreddit: r/{sub} from TOML config") print_substep(f"Using subreddit: r/{sub} from TOML config")
subreddit_choice = sub subreddit_choice = sub
if subreddit_choice.casefold().startswith("r/"): # removes the r/ from the input if str(subreddit_choice).casefold().startswith("r/"): # removes the r/ from the input
subreddit_choice = subreddit_choice[2:] subreddit_choice = subreddit_choice[2:]
subreddit = reddit.subreddit( subreddit = reddit.subreddit(
subreddit_choice subreddit_choice
@ -67,11 +67,10 @@ def get_subreddit_threads(
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(settings.config["reddit"]["thread"]["post_id"].split("+")) == 1 and len(str(settings.config["reddit"]["thread"]["post_id"]).split("+")) == 1
): ):
submission = reddit.submission(id=settings.config["reddit"]["thread"]["post_id"]) submission = reddit.submission(id=settings.config["reddit"]["thread"]["post_id"])
else: else:
threads = subreddit.hot(limit=25) threads = subreddit.hot(limit=25)
submission = get_subreddit_undone(threads, subreddit) submission = get_subreddit_undone(threads, subreddit)
submission = check_done(submission) # double-checking submission = check_done(submission) # double-checking
@ -107,6 +106,7 @@ def get_subreddit_threads(
): ):
if ( if (
top_level_comment.author is not None 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. ): # if errors occur with this change to if not.
content["comments"].append( content["comments"].append(
{ {

@ -5,7 +5,7 @@ moviepy==1.0.3
praw==7.6.0 praw==7.6.0
pytube==12.1.0 pytube==12.1.0
requests==2.28.1 requests==2.28.1
rich==12.4.4 rich==12.5.1
toml==0.10.2 toml==0.10.2
translators==5.3.1 translators==5.3.1
pyppeteer==1.0.2 pyppeteer==1.0.2

@ -34,11 +34,16 @@ def get_subreddit_undone(submissions: list, subreddit):
if submission.stickied: if submission.stickied:
print_substep("This post was pinned by moderators. Skipping...") print_substep("This post was pinned by moderators. Skipping...")
continue continue
if submission.num_comments <= int(settings.config["reddit"]["thread"]["min_comments"]):
print_substep(
f'This post has under the specified minimum of comments ({settings.config["reddit"]["thread"]["min_comments"]}). Skipping...'
)
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")
return get_subreddit_undone( return get_subreddit_undone(
subreddit.top(time_filter="hour"), subreddit subreddit.top(time_filter="hour"), subreddit
) # all of the videos in hot have already been done ) # all the videos in hot have already been done
def already_done(done_videos: list, submission) -> bool: def already_done(done_videos: list, submission) -> bool:

@ -36,7 +36,7 @@ def sleep_until(time):
# Convert datetime to unix timestamp and adjust for locality # Convert datetime to unix timestamp and adjust for locality
if isinstance(time, datetime): if isinstance(time, datetime):
# If we're on Python 3 and the user specified a timezone, convert to UTC and get tje timestamp. # If we're on Python 3 and the user specified a timezone, convert to UTC and get the timestamp.
if sys.version_info[0] >= 3 and time.tzinfo: if sys.version_info[0] >= 3 and time.tzinfo:
end = time.astimezone(timezone.utc).timestamp() end = time.astimezone(timezone.utc).timestamp()
else: else:

@ -30,7 +30,7 @@ background_options = {
"https://www.youtube.com/watch?v=2X9QGY__0II", "https://www.youtube.com/watch?v=2X9QGY__0II",
"rocket_league.mp4", "rocket_league.mp4",
"Orbital Gameplay", "Orbital Gameplay",
"top", lambda t: ("center", 200 + t),
), ),
"minecraft": ( # Minecraft parkour "minecraft": ( # Minecraft parkour
"https://www.youtube.com/watch?v=n_Dv4JMiwK8", "https://www.youtube.com/watch?v=n_Dv4JMiwK8",
@ -64,7 +64,7 @@ def get_start_and_end_times(video_length: int, length_of_clip: int) -> Tuple[int
def get_background_config(): def get_background_config():
"""Fetch the background/s configuration""" """Fetch the background/s configuration"""
try: try:
choice = str(settings.config["settings"]["background_choice"]).casefold() choice = str(settings.config["settings"]["background"]["background_choice"]).casefold()
except AttributeError: except AttributeError:
print_substep("No background selected. Picking random background'") print_substep("No background selected. Picking random background'")
choice = None choice = None

@ -5,8 +5,6 @@ import re
from os.path import exists from os.path import exists
from typing import Tuple, Any from typing import Tuple, Any
import translators as ts
from moviepy.editor import ( from moviepy.editor import (
VideoFileClip, VideoFileClip,
AudioFileClip, AudioFileClip,
@ -44,6 +42,8 @@ def name_normalize(
lang = settings.config['reddit']['thread']['post_lang'] lang = settings.config['reddit']['thread']['post_lang']
if lang: if lang:
import translators as ts
print_substep('Translating filename...') print_substep('Translating filename...')
translated_name = ts.google(name, to_language=lang) translated_name = ts.google(name, to_language=lang)
return translated_name return translated_name
@ -196,38 +196,13 @@ def make_final_video(
verbose=False, verbose=False,
threads=multiprocessing.cpu_count(), threads=multiprocessing.cpu_count(),
) )
if settings.config['settings']['background_audio']: ffmpeg_extract_subclip(
print('[bold green] Merging background audio with video') "assets/temp/temp.mp4",
if not exists('assets/backgrounds/background.mp3'): 0,
print_substep( video_duration,
'Cannot find assets/backgrounds/background.mp3 audio file didn\'t so skipping.' targetname=f'results/{subreddit}/{filename}',
) )
ffmpeg_extract_subclip( save_data(subreddit, filename, title, idx, background_config[2])
'assets/temp/temp.mp4',
0,
video_duration,
targetname=f'results/{subreddit}/{filename}',
)
else:
ffmpeg_merge_video_audio(
'assets/temp/temp.mp4',
'assets/backgrounds/background.mp3',
'assets/temp/temp_audio.mp4',
)
ffmpeg_extract_subclip( # check if this gets run
'assets/temp/temp_audio.mp4',
0,
video_duration,
targetname=f'results/{subreddit}/{filename}',
)
else:
print('debug duck')
ffmpeg_extract_subclip(
'assets/temp/temp.mp4',
0,
video_duration,
targetname=f'results/{subreddit}/{filename}',
)
print_step('Removing temporary files 🗑') print_step('Removing temporary files 🗑')
cleanups = cleanup() cleanups = cleanup()
print_substep(f'Removed {cleanups} temporary files 🗑') print_substep(f'Removed {cleanups} temporary files 🗑')

@ -29,7 +29,7 @@ def save_text_to_mp3(
""" """
voice = settings.config['settings']['tts']['choice'] voice = settings.config['settings']['tts']['choice']
if voice.casefold() not in map(lambda _: _.casefold(), TTSProviders): if str(voice).casefold() not in map(lambda _: _.casefold(), TTSProviders):
while True: while True:
print_step('Please choose one of the following TTS providers: ') print_step('Please choose one of the following TTS providers: ')
print_table(TTSProviders) print_table(TTSProviders)

Loading…
Cancel
Save