Last active
May 7, 2025 15:26
-
-
Save adityadaniel/2b850b0d036ef4b2c36dd3fe7326a3b8 to your computer and use it in GitHub Desktop.
create text overlay video
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from moviepy import * | |
import os | |
import time | |
import random | |
def main(hook: str, song_path=None): | |
video_clip = VideoFileClip("coffee-template2.mp4") # replace with your coffee template | |
video_width = video_clip.w | |
max_text_width = int(video_width * 0.4) | |
text_clip = TextClip( | |
text=hook, | |
font="TikTokDisplay-Medium.ttf", # you can use any fonts | |
font_size=24, | |
color="white", | |
text_align="center", | |
size=(max_text_width, None), # This enables text wrapping | |
method='caption', # This ensures proper text wrapping | |
stroke_color="black", # Add black outline | |
stroke_width=3 # Adjust outline thickness (increase for thicker outline) | |
) | |
text_clip = text_clip.with_position('center').with_duration(video_clip.duration) | |
hook_output = CompositeVideoClip([video_clip, text_clip]) | |
hook_temp_filename = time.strftime('%Y%m%d_%H%M%S') | |
hook_output_filename = f"video_{hook_temp_filename}.mp4" | |
hook_output.write_videofile( | |
hook_output_filename, | |
codec='libx264', | |
audio_codec='aac', | |
fps=30 | |
) | |
final_video = VideoFileClip(hook_output_filename) | |
# If no song path is provided, use a default or select a random one | |
if song_path is None: | |
# Get all songs from the songs folder | |
songs = [f"songs/{song}" for song in os.listdir("songs") if song.endswith('.mp3')] | |
if songs: | |
song_path = random.choice(songs) | |
else: | |
song_path = "songs/end_of_beginning.mp3" # make sure you have this song file, or comment it if you want to add song in TikTok composer | |
audio = AudioFileClip(song_path) | |
# If video is longer than audio, loop the audio | |
if final_video.duration > audio.duration: | |
audio = audio.with_effects([afx.AudioLoop(duration=final_video.duration)]) | |
final_video = final_video.with_audio(audio) | |
final_video.write_videofile( | |
f"video_{hook_temp_filename}_audio.mp4", | |
codec='libx264', | |
audio_codec='aac', | |
fps=30 | |
) | |
video_clip.close() | |
text_clip.close() | |
audio.close() | |
final_video.close() | |
# delete the hook output video | |
os.remove(hook_output_filename) | |
print(f"Generated video with hook and audio: {song_path}") | |
if __name__ == "__main__": | |
hooks = [ | |
"Sometimes the quiet you’re drowning in\nis the same silence where your healing begins.", | |
"In the emptiness you fear,\nyou will find the parts of yourself you forgot to love.", | |
"Loneliness isn’t proof you’re lost\nit’s proof you’re still searching for something real.", | |
"The spaces where no one\nelse can reach you are often where you finally reach yourself.", | |
"You are not abandoned in your solitude\nyou are being handed back to yourself.", | |
"Not every silence is empty.\nSome silences are full of the person you’re becoming.", | |
"The stillness that scares you today\nwill be the peace you protect tomorrow.", | |
"When no one else sees you\nit's a chance to see yourself more clearly than ever before.", | |
"Hope doesn't always roar.\nSometimes it whispers to you when you're finally alone enough to listen.", | |
"Solitude isn’t the absence of life\nit’s where life begins growing underground, unseen but unstoppable." | |
] | |
for hook in hooks: | |
# You can specify a song path here or let it choose randomly | |
main(hook.lower()) # To use a specific song: main(hook.lower(), "songs/your_song.mp3") |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment