Creatomate / app.py
mdnazib963's picture
Upload app.py
3f922a7 verified
import gradio as gr
import subprocess
import os
import shutil
import uuid
def get_sorted_files(file_list):
"""Sorts files by name (00.mp4, 01.mp4...)"""
if not file_list:
return []
file_list.sort(key=lambda x: x.name)
return file_list
def process_and_stitch(video_files, progress=gr.Progress()):
if not video_files:
return None, "Error: Please upload at least one video file."
# Use Absolute Paths to prevent "File Not Found" errors on Hugging Face
base_path = os.path.abspath(".")
session_id = str(uuid.uuid4())
temp_dir = os.path.join(base_path, "temp_clips", session_id)
os.makedirs(temp_dir, exist_ok=True)
sorted_videos = get_sorted_files(video_files)
processed_clips = []
clip_list_path = os.path.join(temp_dir, "clips_list.txt")
output_filename = os.path.join(temp_dir, "final_tiktok_stitch.mp4")
try:
# 1. Process each clip
for i, file_obj in enumerate(progress.tqdm(sorted_videos, desc="Styling Clips")):
input_path = file_obj.name
clip_name = os.path.join(temp_dir, f"processed_{i:03d}.mp4")
# Viral Square Aesthetic Filter
filter_complex = (
f"[0:v]scale=1080:1920:force_original_aspect_ratio=increase,crop=1080:1920,boxblur=40:5[bg];"
f"[0:v]scale=1080:1080:force_original_aspect_ratio=decrease,pad=1080:1080:(ow-iw)/2:(oh-ih)/2[fg];"
f"[bg][fg]overlay=(W-w)/2:(H-h)/2"
)
cmd = [
"ffmpeg", "-y",
"-i", input_path,
"-filter_complex", filter_complex,
"-c:v", "libx264", "-preset", "ultrafast", "-pix_fmt", "yuv420p",
"-c:a", "aac", "-b:a", "128k",
clip_name
]
result = subprocess.run(cmd, capture_output=True, text=True)
if result.returncode != 0:
return None, f"FFmpeg Error in Clip {i}: {result.stderr}"
processed_clips.append(f"file '{clip_name}'")
# 2. Create the list file for concatenation
with open(clip_list_path, "w") as f:
f.write("\n".join(processed_clips))
# 3. Merge clips
# Added -safe 0 and absolute pathing
concat_cmd = [
"ffmpeg", "-y", "-f", "concat", "-safe", "0",
"-i", clip_list_path,
"-c", "copy", output_filename
]
result_merge = subprocess.run(concat_cmd, capture_output=True, text=True)
if result_merge.returncode != 0:
return None, f"Merge Error: {result_merge.stderr}"
if not os.path.exists(output_filename):
return None, "File was not created. Check logs."
return output_filename, f"Success! {len(sorted_videos)} clips combined."
except Exception as e:
return None, f"Python Error: {str(e)}"
# --- Gradio Interface ---
with gr.Interface(
fn=process_and_stitch,
inputs=[
gr.File(file_count="multiple", label="Upload Video Clips (00.mp4, 01.mp4...)")
],
outputs=[
gr.Video(label="Final TikTok Video"),
gr.Textbox(label="Status")
],
title="TikTok Video Stitcher (Square Style)",
description="Upload clips named 00.mp4, 01.mp4 etc. It will make them square and join them."
) as app:
app.launch()