@ -1,15 +1,53 @@
import random
import random
from os import listdir , environ
from os import listdir , environ , getenv
from pathlib import Path
from pathlib import Path
import random
from random import randrange
from random import randrange
from typing import Tuple
from typing import Any , Tuple
from dotenv import load_dotenv
from moviepy . editor import VideoFileClip
from moviepy . editor import VideoFileClip
from moviepy . video . io . ffmpeg_tools import ffmpeg_extract_subclip
from moviepy . video . io . ffmpeg_tools import ffmpeg_extract_subclip
from pytube import YouTube
from pytube import YouTube
from pytube . cli import on_progress
from utils . console import print_step , print_substep
from utils . console import print_step , print_substep
# Supported Background. Can add/remove background video here....
# <key>-<value> : key -> used as keyword for .env file. value -> background configuration
# Format (value):
# 1. Youtube URI
# 2. filename
# 3. Citation (owner of the video)
# 4. Position of image clips in the background. See moviepy reference for more information. (https://zulko.github.io/moviepy/ref/VideoClip/VideoClip.html#moviepy.video.VideoClip.VideoClip.set_position)
background_options = {
" motor-gta " : ( # Motor-GTA Racing
" https://www.youtube.com/watch?v=vw5L4xCPy9Q " ,
" bike-parkour-gta.mp4 " ,
" Achy Gaming " ,
lambda t : ( ' center ' , 480 + t )
) ,
" rocket-league " : ( # Rocket League
" https://www.youtube.com/watch?v=2X9QGY__0II " ,
" rocket_league.mp4 " ,
" Orbital Gameplay " ,
" top "
) ,
" minecraft " : ( # Minecraft parkour
" https://www.youtube.com/watch?v=n_Dv4JMiwK8 " ,
" parkour.mp4 " ,
" bbswitzer " ,
" center "
) ,
" gta " : ( # GTA Stunt Race
" https://www.youtube.com/watch?v=qGa9kWREOnE " ,
" gta-stunt-race.mp4 " ,
" Achy Gaming " ,
lambda t : ( ' center ' , 480 + t )
)
}
def get_start_and_end_times ( video_length : int , length_of_clip : int ) - > Tuple [ int , int ] :
def get_start_and_end_times ( video_length : int , length_of_clip : int ) - > Tuple [ int , int ] :
""" Generates a random interval of time to be used as the background of the video.
""" Generates a random interval of time to be used as the background of the video.
@ -25,49 +63,58 @@ def get_start_and_end_times(video_length: int, length_of_clip: int) -> Tuple[int
return random_time , random_time + video_length
return random_time , random_time + video_length
def download_background ( ) :
def get_background_config ( ) :
""" Downloads the backgrounds/s video from YouTube. """
""" Fetch the background/s configuration """
load_dotenv ( )
try :
choice = getenv ( " BackgroundChoice " ) . casefold ( )
except AttributeError :
print_substep ( " No background selected. Picking random background ' " )
choice = None
# Handle default / not supported background using default option.
# Default : pick random from supported background.
if not choice or choice not in background_options :
choice = random . choice ( list ( background_options . keys ( ) ) )
return background_options [ choice ]
def download_background ( background_config : Tuple [ str , str , str , Any ] ) :
""" Downloads the background/s video from YouTube. """
Path ( " ./assets/backgrounds/ " ) . mkdir ( parents = True , exist_ok = True )
Path ( " ./assets/backgrounds/ " ) . mkdir ( parents = True , exist_ok = True )
background_options = [ # uri , filename , credit
( " https://www.youtube.com/watch?v=n_Dv4JMiwK8 " , " parkour.mp4 " , " bbswitzer " ) ,
# (
# "https://www.youtube.com/watch?v=2X9QGY__0II",
# "rocket_league.mp4",
# "Orbital Gameplay",
# ),
]
# note: make sure the file name doesn't include an - in it
# note: make sure the file name doesn't include an - in it
if not len ( listdir ( " ./assets/backgrounds " ) ) > = len (
uri , filename , credit , _ = background_config
background_options
if Path ( f " assets/backgrounds/ { credit } - { filename } " ) . is_file ( ) :
) : # if there are any background videos not installed
return
print_step (
print_step (
" We need to download the backgrounds videos. they are fairly large but it ' s only done once. 😎 "
" We need to download the backgrounds videos. they are fairly large but it ' s only done once. 😎 "
)
)
print_substep ( " Downloading the backgrounds videos... please be patient 🙏 " )
print_substep ( " Downloading the backgrounds videos... please be patient 🙏 " )
for uri , filename , credit in background_options :
print_substep ( f " Downloading { filename } from { uri } " )
if Path ( f " assets/backgrounds/ { credit } - { filename } " ) . is_file ( ) :
YouTube ( uri , on_progress_callback = on_progress ) . streams . filter ( res = " 1080p " ) . first ( ) . download (
continue # adds check to see if file exists before downloading
" assets/backgrounds " , filename = f " { credit } - { filename } "
print_substep ( f " Downloading { filename } from { uri } " )
)
YouTube ( uri ) . streams . filter ( res = " 1080p " ) . first ( ) . download (
print_substep ( " Background videos downloaded successfully! 🎉 " ,
" assets/backgrounds " , filename = f " { credit } - { filename } "
style = " bold green " )
)
print_substep ( " Background videos downloaded successfully! 🎉 " , style = " bold green " )
def chop_background_video ( background_config : Tuple [ str , str , str , Any ] , video_length : int ) :
def chop_background_video ( video_length : int ) :
""" Generates the background footage to be used in the video and writes it to assets/temp/background.mp4
""" Generates the background footage to be used in the video and writes it to assets/temp/background.mp4
Args :
Args :
background_config ( Tuple [ str , str , str , Any ] ) : Current background configuration
video_length ( int ) : Length of the clip where the background footage is to be taken out of
video_length ( int ) : Length of the clip where the background footage is to be taken out of
"""
"""
print_step ( " Finding a spot in the backgrounds video to chop...✂️ " )
print_step ( " Finding a spot in the backgrounds video to chop...✂️ " )
choice = random . choice ( listdir ( " assets/backgrounds " ) )
choice = f " { background_config [ 2 ] } - { background_config [ 1 ] } "
environ [ " background_credit " ] = choice . split ( " - " ) [ 0 ]
environ [ " background_credit " ] = choice . split ( " - " ) [ 0 ]
background = VideoFileClip ( f " assets/backgrounds/ { choice } " )
background = VideoFileClip ( f " assets/backgrounds/ { choice } " )
start_time , end_time = get_start_and_end_times ( video_length , background . duration )
start_time , end_time = get_start_and_end_times (
video_length , background . duration )
try :
try :
ffmpeg_extract_subclip (
ffmpeg_extract_subclip (
f " assets/backgrounds/ { choice } " ,
f " assets/backgrounds/ { choice } " ,