What the Finished Video Looks Like
- Background: Minecraft parkour / GTA driving / Subway Surfers / nature footage (vertical for Shorts, horizontal for long-form)
- Text overlay: Story title + subtitles synced to voice
- Audio: AI narration + background music at 10–15% volume
- Duration: 3–15 min for long-form, 30–59 sec for Shorts
Required Tools
- FFmpeg Free, open-source video processing. Install:
winget install ffmpeg (Windows) or brew install ffmpeg (Mac)
- Python 3.10+ For the automation scripts. Install from python.org
- MoviePy Python library:
pip install moviepy
- Background videos Download a 1-hour loop of Minecraft parkour / Subway Surfers from YouTube (search "gameplay no commentary"). Store locally.
Video Assembly Script
Python — assemble_video.py
from moviepy.editor import *
import os, random
BACKGROUNDS_DIR = "backgrounds" # folder with .mp4 background loops
AUDIO_DIR = "audio"
OUTPUT_DIR = "videos_ready"
MUSIC_FILE = "music/ambient.mp3" # optional background music
os.makedirs(OUTPUT_DIR, exist_ok=True)
def make_video(audio_file, output_file, title_text):
# Load voiceover
narration = AudioFileClip(audio_file)
duration = narration.duration
# Pick random background, trim to duration
bg_files = [f for f in os.listdir(BACKGROUNDS_DIR) if f.endswith(".mp4")]
bg_path = os.path.join(BACKGROUNDS_DIR, random.choice(bg_files))
bg = VideoFileClip(bg_path).without_audio()
# Random start point in background
max_start = max(0, bg.duration - duration - 5)
start_t = random.uniform(0, max_start)
bg = bg.subclip(start_t, start_t + duration)
# Resize to 1920x1080 (or 1080x1920 for Shorts)
bg = bg.resize((1920, 1080))
# Optional: add background music at low volume
try:
music = AudioFileClip(MUSIC_FILE).subclip(0, duration)
music = music.volumex(0.10)
final_audio = CompositeAudioClip([narration, music])
except:
final_audio = narration
# Title text overlay
txt = TextClip(title_text, fontsize=52, color='white', font='Arial-Bold',
stroke_color='black', stroke_width=2,
size=(1600, None), method='caption')
txt = txt.set_position(('center', 80)).set_duration(min(5, duration))
# Compose
video = CompositeVideoClip([bg, txt])
video = video.set_audio(final_audio)
video.write_videofile(output_file, fps=30, codec='libx264',
audio_codec='aac', threads=4, logger=None)
print(f"✅ Video ready: {output_file}")
# Process all audio files
for audio_file in sorted(os.listdir(AUDIO_DIR)):
if not audio_file.endswith(".mp3"):
continue
base_name = audio_file.replace(".mp3", "")
script_file = f"scripts_ready/{base_name}.txt"
output_file = f"{OUTPUT_DIR}/{base_name}.mp4"
if os.path.exists(output_file):
continue # already done
# Get title from script file
title = "Reddit Story"
if os.path.exists(script_file):
first_line = open(script_file, encoding="utf-8").readline().strip()
title = first_line[:60]
make_video(f"{AUDIO_DIR}/{audio_file}", output_file, title)
Auto-Generate Subtitles (Optional — Big CTR Boost)
Python — add_subtitles.py
import whisper, json
# pip install openai-whisper
model = whisper.load_model("base")
def transcribe_audio(audio_path):
result = model.transcribe(audio_path, word_timestamps=True)
return result["segments"]
# Use segments to add word-by-word text overlay with MoviePy
# (each segment has start/end time + text — add as TextClip per segment)
💡 Performance: On a modern PC, one 8-minute video takes about 2–4 minutes to render. You can run multiple processes in parallel. 10 videos = ~40 minutes unattended.
Full One-Click Pipeline Script
Python — run_all.py
import subprocess, datetime
print(f"\n🚀 Starting pipeline — {datetime.datetime.now()}\n")
print("📡 Step 1: Fetching Reddit stories...")
subprocess.run(["python", "fetch_reddit.py"], check=True)
print("✍️ Step 2: Formatting scripts with AI...")
subprocess.run(["python", "format_scripts.py"], check=True)
print("🎙️ Step 3: Generating voiceovers...")
subprocess.run(["python", "voiceover.py"], check=True)
print("🎬 Step 4: Assembling videos...")
subprocess.run(["python", "assemble_video.py"], check=True)
print("📤 Step 5: Uploading to YouTube...")
subprocess.run(["python", "upload_youtube.py"], check=True)
print("\n✅ All done! Videos uploaded to YouTube.")