feat: Bot modifications

- Modified the bot to work with audios with small duration even for long videos.
- Added video scheduling functionality.
- Added some creepy background videos.
- Better text synchronization in storymode.
pull/2058/head
Mohamed Moataz 1 year ago
parent b784a4c86f
commit e56d09212e

1
.gitignore vendored

@ -239,6 +239,7 @@ out
results/*
reddit-bot-351418-5560ebc49cac.json
/.idea
/test
*.pyc
video_creation/data/videos.json
video_creation/data/envvars.txt

@ -1,5 +1,7 @@
#!/usr/bin/env python
import math
import time
import schedule
import sys
from os import name
from pathlib import Path
@ -50,6 +52,7 @@ def main(POST_ID=None) -> None:
redditid = id(reddit_object)
length, number_of_comments = save_text_to_mp3(reddit_object)
length = math.ceil(length)
# length, number_of_comments = 360, 43
get_screenshots_of_reddit_posts(reddit_object, number_of_comments)
bg_config = {
"video": get_background_config("video"),
@ -78,6 +81,26 @@ def shutdown() -> NoReturn:
print("Exiting...")
sys.exit()
def run():
if config["reddit"]["thread"]["post_id"]:
for index, post_id in enumerate(config["reddit"]["thread"]["post_id"].split("+")):
index += 1
print_step(
f'on the {index}{("st" if index % 10 == 1 else ("nd" if index % 10 == 2 else ("rd" if index % 10 == 3 else "th")))} post of {len(config["reddit"]["thread"]["post_id"].split("+"))}'
)
main(post_id)
Popen("cls" if name == "nt" else "clear", shell=True).wait()
elif config["settings"]["times_to_run"]:
run_many(config["settings"]["times_to_run"])
else:
main()
print_substep("The video was created successfully! 🎉", style="bold green")
print_substep(
f'Next run will be in {settings.config["settings"]["run_every"]} hours.',
style="bold green"
)
if __name__ == "__main__":
if sys.version_info.major != 3 or sys.version_info.minor != 10:
@ -102,18 +125,11 @@ if __name__ == "__main__":
)
sys.exit()
try:
if config["reddit"]["thread"]["post_id"]:
for index, post_id in enumerate(config["reddit"]["thread"]["post_id"].split("+")):
index += 1
print_step(
f'on the {index}{("st" if index % 10 == 1 else ("nd" if index % 10 == 2 else ("rd" if index % 10 == 3 else "th")))} post of {len(config["reddit"]["thread"]["post_id"].split("+"))}'
)
main(post_id)
Popen("cls" if name == "nt" else "clear", shell=True).wait()
elif config["settings"]["times_to_run"]:
run_many(config["settings"]["times_to_run"])
else:
main()
run()
schedule.every(settings.config["settings"]["run_every"]).hours.do(run)
while True:
schedule.run_pending()
time.sleep(1)
except KeyboardInterrupt:
shutdown()
except ResponseException:

Binary file not shown.

@ -31,9 +31,10 @@ storymode_max_length = { optional = true, default = 1000, example = 1000, explan
resolution_w = { optional = false, default = 1080, example = 1440, explantation = "Sets the width in pixels of the final video" }
resolution_h = { optional = false, default = 1920, example = 2560, explantation = "Sets the height in pixels of the final video" }
zoom = { optional = true, default = 1, example = 1.1, explanation = "Sets the browser zoom level. Useful if you want the text larger.", type = "float", nmin = 0.1, nmax = 2, oob_error = "The text is really difficult to read at a zoom level higher than 2" }
run_every = { optional = false, default = 24, example = 5, explanation = "How often should the bot create a video (in hours).", type = "int", nmin = 1, nmax = 48, oob_error = "Please choose a number between 1 and 24." }
[settings.background]
background_video = { optional = true, default = "minecraft", example = "rocket-league", options = ["minecraft", "gta", "rocket-league", "motor-gta", "csgo-surf", "cluster-truck", "minecraft-2","multiversus","fall-guys","steep", ""], explanation = "Sets the background for the video based on game name" }
background_video = { optional = true, default = "minecraft", example = "rocket-league", options = ["mudrunner", "granny-remake", ""], explanation = "Sets the background for the video based on game name" }
background_audio = { optional = true, default = "lofi", example = "chill-summer", options = ["lofi","lofi-2","chill-summer", "eerie",""], explanation = "Sets the background audio for the video" }
background_audio_volume = { optional = true, type = "float", nmin = 0, nmax = 1, default = 0.15, example = 0.05, explanation="Sets the volume of the background audio. If you don't want background audio, set it to 0.", oob_error = "The volume HAS to be between 0 and 1", input_error = "The volume HAS to be a float number between 0 and 1"}
enable_extra_audio = { optional = true, type = "bool", default = false, example = false, explanation="Used if you want to render another video without background audio in a separate folder", input_error = "The value HAS to be true or false"}
@ -49,8 +50,8 @@ elevenlabs_voice_name = { optional = false, default = "Bella", example = "Bella"
elevenlabs_api_key = { optional = true, example = "21f13f91f54d741e2ae27d2ab1b99d59", explanation = "Elevenlabs API key" }
unreal_speech_api_key = { optional = true, example = "21f13f91f54d741e2ae27d2ab1b99d59", explanation = "Unreal Speech API key" }
unreal_speech_voice_name = { optional = false, default = "Liv", example = "Liv", explanation = "The voice used for Unreal Speech", options = ["Scarlett", "Amy", "Liv", "Dan", "Will", ] }
unreal_speech_voice_pitch = { optional = false, default = "1", example = "1.2", explanation = "The pitch of the voice used for Unreal Speech (0.5 to 1.5)", type = "float" }
unreal_speech_voice_speed = { optional = false, default = "0", example = "-0.15", explanation = "The speed of the voice used for Unreal Speech (-1.0 to 1.0)", type = "float" }
unreal_speech_voice_pitch = { optional = false, default = "1", example = "1.2", nmin = 0.5, nmax = 1.5, explanation = "The pitch of the voice used for Unreal Speech (0.5 to 1.5)", type = "float" }
unreal_speech_voice_speed = { optional = false, default = "0", example = "-0.15", nmin = -1.0, nmax = 1.0, explanation = "The speed of the voice used for Unreal Speech (-1.0 to 1.0)", type = "float" }
aws_polly_voice = { optional = false, default = "Matthew", example = "Matthew", explanation = "The voice used for AWS Polly" }
streamlabs_polly_voice = { optional = false, default = "Matthew", example = "Matthew", explanation = "The voice used for Streamlabs Polly" }
tiktok_voice = { optional = true, default = "en_us_001", example = "en_us_006", explanation = "The voice used for TikTok TTS" }

@ -1,23 +1,13 @@
{
"__comment": "Supported Backgrounds Audio. Can add/remove background audio here...",
"lofi": [
"https://www.youtube.com/watch?v=LTphVIore3A",
"lofi.mp3",
"Super Lofi World"
],
"lofi-2":[
"https://www.youtube.com/watch?v=BEXL80LS0-I",
"lofi-2.mp3",
"stompsPlaylist"
],
"eerie":[
"https://www.youtube.com/watch?v=OozBNFEa4PM",
"eerie.mp3",
"Royalty Free Music"
],
"chill-summer":[
"https://www.youtube.com/watch?v=EZE8JagnBI8",
"chill-summer.mp3",
"Mellow Vibes Radio"
"hybrid":[
"https://www.youtube.com/watch?v=QbqkR5VNaU8",
"hybrid.mp3",
"Royalty Free Music"
]
}

@ -1,63 +1,15 @@
{
"__comment": "Supported Backgrounds. Can add/remove background video here...",
"motor-gta": [
"https://www.youtube.com/watch?v=vw5L4xCPy9Q",
"bike-parkour-gta.mp4",
"Achy Gaming",
"center"
],
"rocket-league": [
"https://www.youtube.com/watch?v=2X9QGY__0II",
"rocket_league.mp4",
"Orbital Gameplay",
"center"
],
"minecraft": [
"https://www.youtube.com/watch?v=n_Dv4JMiwK8",
"parkour.mp4",
"bbswitzer",
"center"
],
"gta": [
"https://www.youtube.com/watch?v=qGa9kWREOnE",
"gta-stunt-race.mp4",
"Achy Gaming",
"center"
],
"csgo-surf": [
"https://www.youtube.com/watch?v=E-8JlyO59Io",
"csgo-surf.mp4",
"Aki",
"center"
],
"cluster-truck": [
"https://www.youtube.com/watch?v=uVKxtdMgJVU",
"cluster_truck.mp4",
"No Copyright Gameplay",
"center"
],
"minecraft-2": [
"https://www.youtube.com/watch?v=Pt5_GSKIWQM",
"minecraft-2.mp4",
"Itslpsn",
"center"
],
"multiversus": [
"https://www.youtube.com/watch?v=66oK1Mktz6g",
"multiversus.mp4",
"MKIceAndFire",
"center"
],
"fall-guys": [
"https://www.youtube.com/watch?v=oGSsgACIc6Q",
"fall-guys.mp4",
"Throneful",
"mudrunner": [
"https://www.youtube.com/watch?v=YsfkZoXv4s8",
"mudrunner.mp4",
"joel",
"center"
],
"steep": [
"https://www.youtube.com/watch?v=EnGiQrWBrko",
"steep.mp4",
"joel",
"granny-remake": [
"https://www.youtube.com/watch?v=Ynjc1EcRExk",
"granny.mp4",
"Dope Gameplays",
"center"
]
}
}

@ -57,6 +57,7 @@ def imagemaker(theme, reddit_obj: dict, txtclr, padding=5, transparent=False) ->
"""
Render Images for video
"""
# return
title = process_text(reddit_obj["thread_title"], False)
texts = process_post(reddit_obj["thread_post"])
id = re.sub(r"[^\w\s-]", "", reddit_obj["thread_id"])

@ -1,6 +1,6 @@
def process_post(reddit_thread_post):
texts = reddit_thread_post
threshold = 60
threshold = 80
for i in range(len(texts)):
if len(texts[i]) > threshold:
texts[i] = split_text(texts[i], threshold)
@ -10,11 +10,6 @@ def split_text(text, threshold):
text = text.split(' ')
new_text = ''
texts = []
# for i in range(threshold+1,1,-1):
# if (len(text) / i) - (len(text) // i) >= 0.7:
# threshold = i
# # print("Found:", threshold)
# break
for i in text:
if new_text == '':
@ -22,9 +17,17 @@ def split_text(text, threshold):
continue
new_text += ' ' + i
if len(new_text) >= threshold:
texts.append(new_text)
new_text = ''
if len(new_text) >= int(0.75 * threshold):
go = True
# Make sure that the text left is not so short
if i != text[-1]:
left = ' '.join(text[i+1:])
if len(left) < int(0.25 * threshold):
go = False
if go:
texts.append(new_text)
new_text = ''
if new_text != '':
texts.append(new_text)

@ -1,9 +1,12 @@
import json
import os
import random
import re
import math
from pathlib import Path
from random import randrange
from typing import Any, Tuple, Dict
from pydub import AudioSegment
from moviepy.editor import VideoFileClip, AudioFileClip
from moviepy.video.io.ffmpeg_tools import ffmpeg_extract_subclip
@ -116,7 +119,18 @@ def download_background_audio(background_config: Tuple[str, str, str]):
with yt_dlp.YoutubeDL(ydl_opts) as ydl:
ydl.download([uri])
sound = AudioSegment.from_file(f"./assets/backgrounds/audio/{credit}-{filename}")
new_sound = sound[:]
loops = math.ceil(1800 / sound.duration_seconds)
for _ in range(loops):
new_sound += sound
os.remove(f"./assets/backgrounds/audio/{credit}-{filename}")
new_sound.export(f"./assets/backgrounds/audio/{credit}-{filename}", format="mp3")
print_substep("Background audio downloaded successfully! 🎉", style="bold green")
print(f"The audio duration was extended to be: {new_sound.duration_seconds} seconds")
def chop_background(background_config: Dict[str, Tuple], video_length: int, reddit_object: dict):

@ -159,8 +159,8 @@ def make_final_video(
print_step("Creating the final video 🎥")
# background_clip = ffmpeg.input(prepare_background(reddit_id, W=W, H=H))
background_clip = ffmpeg.input(f"assets/temp/{reddit_id}/background_noaudio.mp4")
background_clip = ffmpeg.input(prepare_background(reddit_id, W=W, H=H))
# background_clip = ffmpeg.input(f"assets/temp/{reddit_id}/background_noaudio.mp4")
# Gather all audio clips
audio_clips = list()
@ -174,12 +174,12 @@ def make_final_video(
audio_clips = [ffmpeg.input(f"assets/temp/{reddit_id}/mp3/title.mp3")]
audio_clips.insert(1, ffmpeg.input(f"assets/temp/{reddit_id}/mp3/postaudio.mp3"))
elif settings.config["settings"]["storymodemethod"] == 1:
# audio_clips = [
# ffmpeg.input(f"assets/temp/{reddit_id}/mp3/postaudio-{i}.mp3")
# for i in track(range(number_of_clips + 1), "Collecting the audio files...")
# ]
# audio_clips.insert(0, ffmpeg.input(f"assets/temp/{reddit_id}/mp3/title.mp3"))
pass
audio_clips = [
ffmpeg.input(f"assets/temp/{reddit_id}/mp3/postaudio-{i}.mp3")
for i in track(range(number_of_clips + 1), "Collecting the audio files...")
]
audio_clips.insert(0, ffmpeg.input(f"assets/temp/{reddit_id}/mp3/title.mp3"))
# pass
else:
audio_clips = [
@ -195,10 +195,11 @@ def make_final_video(
0,
float(ffmpeg.probe(f"assets/temp/{reddit_id}/mp3/title.mp3")["format"]["duration"]),
)
# audio_concat = ffmpeg.concat(*audio_clips, a=1, v=0)
# ffmpeg.output(
# audio_concat, f"assets/temp/{reddit_id}/audio.mp3", **{"b:a": "192k"}
# ).overwrite_output().run(quiet=True)
# Comment those as well when testing
audio_concat = ffmpeg.concat(*audio_clips, a=1, v=0)
ffmpeg.output(
audio_concat, f"assets/temp/{reddit_id}/audio.mp3", **{"b:a": "192k"}
).overwrite_output().run(quiet=True)
console.log(f"[bold green] Video Will Be: {length} Seconds Long")

Loading…
Cancel
Save