Skip to content

jdportugal/VideoEditorAPI

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

23 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

🎬 VideoEditorAPI

AI-powered video processing API with subtitle generation, karaoke effects, and editing tools.

⚑ Quick Start

Option 1: Digital Ocean App Platform (Easiest)

Deploy to DO

Option 2: One-Click Droplet Deploy

curl -fsSL https://raw.githubusercontent.com/jdportugal/VideoEditorAPI/main/install-ghcr.sh | sudo bash

Option 2: Local Development

git clone https://github.com/jdportugal/VideoEditorAPI.git
cd VideoEditorAPI
docker-compose up -d

Option 3: Manual Docker

docker run -d -p 8080:8080 ghcr.io/jdportugal/videoeditorapi:latest

🎯 Features

  • 🎀 AI Subtitles - Whisper-powered speech recognition
  • 🌟 Karaoke Effects - Word-by-word highlighting
  • βœ‚οΈ Video Editing - Split, join, trim videos
  • 🎡 Audio Mixing - Add background music
  • πŸ“Š Job Tracking - Real-time processing status

πŸ“‹ System Requirements

  • CPU: 2+ vCPUs (4+ recommended for faster processing)
  • RAM: 4GB minimum (8GB+ for large videos)
  • Storage: 25GB+ SSD
  • OS: Ubuntu 20.04+, Docker installed

πŸ› οΈ API Endpoints

Health Check

GET /health
curl http://localhost:8080/health

Response:

{"status": "healthy", "timestamp": "2024-01-01T12:00:00"}

Add Subtitles with Karaoke Effect

POST /add-subtitles
curl -X POST http://localhost:8080/add-subtitles \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://example.com/video.mp4",
    "settings": {
      "font-size": 120,
      "normal-color": "#FFF4E9"
    }
  }'

Parameters:

  • url (required): Video URL or Google Drive link
  • language (optional): Language code (default: "en")
  • settings (optional): Subtitle styling options

Styling Options:

{
  "font-size": 120,
  "font-family": "Luckiest Guy", 
  "normal-color": "#FFFFFF",
  "outline-width": 10,
  "position": "bottom-center"
}

Response:

{
  "job_id": "uuid-here",
  "status": "pending", 
  "message": "Subtitle processing started"
}

Split Video by Time

POST /split-video
curl -X POST http://localhost:8080/split-video \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://example.com/video.mp4",
    "start_time": "00:00:10,000",
    "end_time": "00:01:30,500"
  }'

Job Chaining - Split Previous Output:

curl -X POST http://localhost:8080/split-video \
  -H "Content-Type: application/json" \
  -d '{
    "job_id": "previous-job-uuid",
    "start_time": "00:00:05,000",
    "end_time": "00:00:15,000"
  }'

Parameters:

  • url OR job_id (required): Video URL or previous job ID to split
  • start_time (required): Start time for split
  • end_time (required): End time for split

Time Formats Supported:

  • "00:01:30,500" (HH:MM:SS,mmm)
  • "90.5" (seconds as string)
  • 90.5 (numeric seconds)

Join Multiple Videos

POST /join-videos
curl -X POST http://localhost:8080/join-videos \
  -H "Content-Type: application/json" \
  -d '{
    "urls": [
      "https://example.com/video1.mp4",
      "https://example.com/video2.mp4"
    ]
  }'

Add Background Music

POST /add-music
curl -X POST http://localhost:8080/add-music \
  -H "Content-Type: application/json" \
  -d '{
    "video_url": "https://example.com/video.mp4",
    "music_url": "https://example.com/music.mp3",
    "settings": {
      "volume": 0.3,
      "fade_in": 2,
      "fade_out": 3,
      "loop_music": true
    }
  }'

Music Settings:

  • volume: 0.0 to 1.0 (default: 0.5)
  • fade_in: Fade in duration in seconds
  • fade_out: Fade out duration in seconds
  • loop_music: Loop music to match video length

Check Job Status

GET /job-status/<job_id>
curl http://localhost:8080/job-status/your-job-id

Response:

{
  "job_id": "uuid-here",
  "status": "completed",
  "progress": 100,
  "video_download_url": "/download/uuid-here",
  "subtitle_download_url": "/download-subtitles/uuid-here"
}

Status Values:

  • pending - Job queued for processing
  • processing - Currently being processed
  • completed - Successfully completed
  • failed - Processing failed (check error field)

Admin Cleanup

POST /admin/cleanup
curl -X POST http://localhost:8080/admin/cleanup \
  -H "Content-Type: application/json"

Purpose: Comprehensive cleanup of all jobs and files (completed, failed, pending)

Removes:

  • All job files (jobs directory)
  • All temporary files (temp directory)
  • All uploaded files (uploads directory)
  • All static files (static directory)

Response:

{
  "status": "success",
  "message": "Comprehensive cleanup completed",
  "timestamp": "2025-11-15T11:59:04.888763",
  "cleanup_stats": {
    "jobs_removed": 10,
    "temp_files_removed": 18,
    "upload_files_removed": 1,
    "static_files_removed": 1,
    "total_size_freed": 322308966,
    "total_size_freed_formatted": "307.38 MB",
    "directories_cleaned": ["jobs", "temp", "uploads", "static"]
  }
}

⚠️ Warning: This operation is irreversible and removes ALL files regardless of status.


Download Processed Video

GET /download/<job_id>
curl http://localhost:8080/download/your-job-id -o result.mp4

Download Subtitle File

GET /download-subtitles/<job_id>  
curl http://localhost:8080/download-subtitles/your-job-id -o subtitles.srt

🎨 Subtitle Customization

Font Styles

  • font-family: "Luckiest Guy" (default), "Arial", "DejaVu-Sans-Bold"
  • font-size: 80-200 pixels (default: 120)
  • normal-color: Any hex color (default: "#FFFFFF")
  • outline-width: 0-20 pixels (default: 10)

Positioning

  • top-left, top-center, top-right
  • center-left, center-center, center-right
  • bottom-left, bottom-center, bottom-right

Karaoke Modes

  • karaoke (default): Word-by-word highlighting
  • off: Traditional sentence subtitles
  • popup: Individual word pop-ups
  • typewriter: Accumulating word display

πŸ“Š Usage Examples

Basic Subtitle Addition

curl -X POST http://localhost:8080/add-subtitles \
  -H "Content-Type: application/json" \
  -d '{"url": "https://example.com/video.mp4"}'

Custom Styling

curl -X POST http://localhost:8080/add-subtitles \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://example.com/video.mp4", 
    "settings": {
      "font-size": 140,
      "normal-color": "#FFD700",
      "outline-width": 8,
      "position": "top-center"
    }
  }'

Job Chaining Workflow

# 1. Add subtitles to original video
SUBTITLE_JOB=$(curl -s -X POST http://localhost:8080/add-subtitles \
  -H "Content-Type: application/json" \
  -d '{"url": "https://example.com/video.mp4"}' | jq -r '.job_id')

# 2. Wait for completion and get status
curl http://localhost:8080/job-status/$SUBTITLE_JOB

# 3. Split the subtitled video using job chaining
SPLIT_JOB=$(curl -s -X POST http://localhost:8080/split-video \
  -H "Content-Type: application/json" \
  -d "{\"job_id\": \"$SUBTITLE_JOB\", \"start_time\": \"00:00:10,000\", \"end_time\": \"00:00:30,000\"}" | jq -r '.job_id')

# 4. Download the final result
curl http://localhost:8080/download/$SPLIT_JOB -o final_video.mp4

Split & Process Workflow

# 1. Split video to extract segment
curl -X POST http://localhost:8080/split-video \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://example.com/long-video.mp4",
    "start_time": "00:02:00,000", 
    "end_time": "00:03:30,000"
  }'

# 2. Get job ID from response, check status
curl http://localhost:8080/job-status/JOB_ID

# 3. Download split video
curl http://localhost:8080/download/JOB_ID -o segment.mp4

# 4. Add subtitles to segment
curl -X POST http://localhost:8080/add-subtitles \
  -H "Content-Type: application/json" \
  -d '{"url": "https://yourdomain.com/segment.mp4"}'

πŸš€ Deployment Options

Digital Ocean (Recommended)

  1. Create droplet (4GB+ RAM, Ubuntu 20.04+)
  2. Run installer:
curl -fsSL https://raw.githubusercontent.com/jdportugal/VideoEditorAPI/main/install-ghcr.sh | sudo bash

Local Development

git clone https://github.com/jdportugal/VideoEditorAPI.git
cd VideoEditorAPI
docker-compose up -d

Custom Docker

docker run -d \
  --name videoeditor \
  -p 5000:5000 \
  -v ./temp:/app/temp \
  -v ./uploads:/app/uploads \
  ghcr.io/jdportugal/videoeditorapi:latest

βš™οΈ Configuration

Environment Variables

# Optional customization
FLASK_ENV=production
MAX_CONCURRENT_JOBS=4
VIDEO_MAX_DURATION=1800
WHISPER_MODEL=base
LOG_LEVEL=INFO

Volume Mounts

  • /app/temp - Temporary processing files
  • /app/uploads - User uploaded files
  • /app/jobs - Job status tracking
  • /app/logs - Application logs

πŸ”§ Troubleshooting

Check Service Status

# Docker Compose
docker-compose ps
docker-compose logs -f

# Direct Docker
docker ps
docker logs videoeditor

Common Issues

Port 8080 not accessible:

# Check firewall
sudo ufw allow 8080/tcp

# Check if service is running
curl http://localhost:8080/health

Out of disk space:

# Clean up temporary files
docker system prune -f
sudo rm -rf ./temp/*

Memory issues:

# Check resource usage
docker stats

# Increase droplet size or add swap

Job stuck in processing:

# Restart service
docker-compose restart

# Check logs for errors
docker-compose logs video-editor-api

πŸ“ˆ Performance

Processing Times (Approximate)

  • 1-minute video: 30-60 seconds
  • 5-minute video: 2-4 minutes
  • 10-minute video: 5-10 minutes

Optimization Tips

  1. Use CPU-optimized droplets for faster processing
  2. Keep videos under 500MB for best performance
  3. Ensure clear audio for better subtitle accuracy
  4. Use MP4 format for compatibility

πŸ”„ Updates & Maintenance

Auto-Updates (If using installer)

cd /opt/shortscreator
./update.sh

Manual Updates

docker-compose pull
docker-compose up -d

Health Monitoring

# Check API health
curl http://localhost:8080/health

# View recent logs
docker-compose logs --tail=50

# Monitor resources
docker stats

🌐 Integration Examples

Node.js

const axios = require('axios');

async function addSubtitles(videoUrl) {
  const response = await axios.post('http://localhost:8080/add-subtitles', {
    url: videoUrl,
    settings: {
      'font-size': 120,
      'normal-color': '#FFD700'
    }
  });
  
  return response.data.job_id;
}

async function checkJobStatus(jobId) {
  const response = await axios.get(`http://localhost:8080/job-status/${jobId}`);
  return response.data;
}

Python

import requests
import time

def add_subtitles(video_url):
    response = requests.post('http://localhost:8080/add-subtitles', json={
        'url': video_url,
        'settings': {
            'font-size': 120,
            'normal-color': '#FFD700'
        }
    })
    return response.json()['job_id']

def wait_for_completion(job_id):
    while True:
        response = requests.get(f'http://localhost:8080/job-status/{job_id}')
        status = response.json()
        
        if status['status'] == 'completed':
            return status
        elif status['status'] == 'failed':
            raise Exception(f"Job failed: {status.get('error')}")
        
        time.sleep(5)

cURL Scripts

#!/bin/bash
# process_video.sh

VIDEO_URL="$1"
API_URL="http://localhost:8080"

# Submit job
JOB_ID=$(curl -s -X POST "$API_URL/add-subtitles" \
  -H "Content-Type: application/json" \
  -d "{\"url\": \"$VIDEO_URL\"}" | jq -r '.job_id')

echo "Job ID: $JOB_ID"

# Wait for completion
while true; do
  STATUS=$(curl -s "$API_URL/job-status/$JOB_ID" | jq -r '.status')
  echo "Status: $STATUS"
  
  if [ "$STATUS" = "completed" ]; then
    echo "Downloading result..."
    curl -o "result.mp4" "$API_URL/download/$JOB_ID"
    curl -o "subtitles.srt" "$API_URL/download-subtitles/$JOB_ID" 
    break
  elif [ "$STATUS" = "failed" ]; then
    echo "Job failed!"
    exit 1
  fi
  
  sleep 5
done

πŸ“ž Support

πŸ“„ License

MIT License - Feel free to use in personal and commercial projects.


⭐ Star this repository if it helped you!

Built with Python, Flask, Whisper AI, and MoviePy.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors