Fix multiple errors and improve code readability

- Resolved 'StreamingData' error

- Fixed ffmpeg compatibility issues, particularly with M1 Macs

- Replaced pytube with yt-dl for better up-to-date functionality and M1 support

- Enhanced code readability and provided clear comments for beginners to understand the code easily
pull/1632/head
Mihai 2 years ago
parent f2d89a10dd
commit e613b47626

@ -5,45 +5,33 @@ from pathlib import Path
from random import randrange
from typing import Any, Tuple
import yt_dlp
from moviepy.editor import VideoFileClip
from moviepy.video.io.ffmpeg_tools import ffmpeg_extract_subclip
from pytube import YouTube
from pytube.cli import on_progress
from utils import settings
from utils.console import print_step, print_substep
# Load background videos
# Load background video configurations from the JSON file
with open("./utils/backgrounds.json") as json_file:
background_options = json.load(json_file)
# Remove "__comment" from backgrounds
# Remove any comments from the JSON file
background_options.pop("__comment", None)
# Add position lambda function
# (https://zulko.github.io/moviepy/ref/VideoClip/VideoClip.html#moviepy.video.VideoClip.VideoClip.set_position)
# Set the position of the background video in the final output
for name in list(background_options.keys()):
pos = background_options[name][3]
if pos != "center":
background_options[name][3] = lambda t: ("center", pos + t)
# Function to generate a random start and end time for the background video
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.
Args:
video_length (int): Length of the video
length_of_clip (int): Length of the video to be used as the background
Returns:
tuple[int,int]: Start and end time of the randomized interval
"""
random_time = randrange(180, int(length_of_clip) - int(video_length))
return random_time, random_time + video_length
# Function to get the background configuration from the settings
def get_background_config():
"""Fetch the background/s configuration"""
try:
choice = str(
settings.config["settings"]["background"]["background_choice"]
@ -52,18 +40,14 @@ def get_background_config():
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]
# Function to download the background video from YouTube
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)
# note: make sure the file name doesn't include an - in it
uri, filename, credit, _ = background_config
if Path(f"assets/backgrounds/{credit}-{filename}").is_file():
return
@ -72,28 +56,34 @@ def download_background(background_config: Tuple[str, str, str, Any]):
)
print_substep("Downloading the backgrounds videos... please be patient 🙏 ")
print_substep(f"Downloading {filename} from {uri}")
YouTube(uri, on_progress_callback=on_progress).streams.filter(
res="1080p"
).first().download("assets/backgrounds", filename=f"{credit}-{filename}")
# Set the download option for yt-dlp
ydl_opts = {
'outtmpl': f'assets/backgrounds/{credit}-{filename}',
'format': 'bestvideo[height<=1080][ext=mp4]+bestaudio[ext=m4a]/best[height<=1080][ext=mp4]'
}
# Download the video with yt-dlp
with yt_dlp.YoutubeDL(ydl_opts) as ydl:
ydl.download([uri])
print_substep("Background video downloaded successfully! 🎉", style="bold green")
def chop_background_video(
background_config: Tuple[str, str, str, Any], video_length: int, reddit_object: dict
):
"""Generates the background footage to be used in the video and writes it to assets/temp/background.mp4
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
"""
print_step("Finding a spot in the backgrounds video to chop...✂️")
choice = f"{background_config[2]}-{background_config[1]}"
id = re.sub(r"[^\w\s-]", "", reddit_object["thread_id"])
# Load the background video
background = VideoFileClip(f"assets/backgrounds/{choice}")
# Get the start and end times for the portion to extract
start_time, end_time = get_start_and_end_times(video_length, background.duration)
# Extract the portion of the video
try:
ffmpeg_extract_subclip(
f"assets/backgrounds/{choice}",
@ -106,5 +96,7 @@ def chop_background_video(
with VideoFileClip(f"assets/backgrounds/{choice}") as video:
new = video.subclip(start_time, end_time)
new.write_videofile(f"assets/temp/{id}/background.mp4")
# Output a success message
print_substep("Background video chopped successfully!", style="bold green")
return background_config[2]

@ -1,7 +1,6 @@
import multiprocessing
import os
import re
import shutil
from os.path import exists # Needs to be imported specifically
from typing import Final
from typing import Tuple, Any

Loading…
Cancel
Save