3 ms·
Here is my moviepy code: import asyncio from moviepy.editor import VideoFileClip, clips_array, vfx def merge_shorts_sync(content_duration: int, satisfaction_
by Monnadre 2y ago
Here is my moviepy code:
import asyncio
from moviepy.editor import VideoFileClip, clips_array, vfx
def merge_shorts_sync(content_duration: int, satisfaction_duration: int, content_path: str = "content.mp4", satisfaction_path: str = "satisfaction.mp4", output_path: str = "final.mp4") -> None:
# User-specified proportions
p1 = 0.6 # first clip will occupy 60% of the final height
p2 = 1 - p1 # second clip will occupy 40% of the final height
# Load the video clips
content_clip = VideoFileClip(content_path)
satisfaction_clip = VideoFileClip(satisfaction_path)
# Adjust satisfaction clip duration relative to content clip
if content_duration > satisfaction_duration:
speed_factor = satisfaction_duration / content_duration
satisfaction_clip = satisfaction_clip.fx(vfx.speedx, speed_factor)
else:
satisfaction_clip = satisfaction_clip.subclip(0, content_duration)
# Use the height of the content clip as target
target_height = content_clip.h
# Resize clips to target height
content_clip_resized = content_clip.resize(height=target_height)
satisfaction_clip_resized = satisfaction_clip.resize(height=target_height)
# Helper to crop a clip centrally by a vertical proportion
def crop_central(clip, proportion):
current_height = clip.h
target_crop_height = current_height * proportion
top_crop = (current_height - target_crop_height) / 2
return clip.crop(y1=top_crop, y2=top_crop + target_crop_height)
# Crop each clip according to the desired proportions
content_clip_cropped = crop_central(content_clip_resized, p1)
satisfaction_clip_cropped = crop_central(satisfaction_clip_resized, p2)
if abs(p1 + p2 - 1) > 1e-6:
raise ValueError("The sum of the proportions p1 and p2 must equal 1.")
# Stack clips vertically (the final height will match target_height)
final_clip = clips_array([[content_clip_cropped],
[satisfaction_clip_cropped]])
# Export the final video
final_clip.write_videofile(output_path, codec="libx264", fps=content_clip.fps, audio_codec="aac")
async def merge_shorts(content_duration: int, satisfaction_duration: int, content_path: str = "content.mp4", satisfaction_path: str = "satisfaction.mp4", output_path: str = "final.mp4") -> None:
# Offload the synchronous video processing to a separate thread
await asyncio.to_thread(merge_shorts_sync, content_duration, satisfaction_duration, content_path, satisfaction_path, output_path)
If you want to create a script that autogenerate videos, we can continue on discord.