Skip to content

lachlanchen/LazyEdit

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

486 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

English · العربية · Español · Français · 日本語 · 한국어 · Tiếng Việt · 中文 (简体) · 中文(繁體) · Deutsch · Русский

LazyingArt banner

LazyEdit

AI-assisted video workflow for generation, subtitle processing, metadata, and optional publishing.
Upload or generate -> transcribe -> translate/polish -> burn subtitles -> caption/keyframes -> metadata -> publish

License: Apache-2.0 Python 3.10+ Backend: Tornado Frontend: Expo Platform: Linux FFmpeg required PostgreSQL supported Stage A/B/C enabled AutoPublish optional i18n: 11 languages Last commit Contributors

LazyEdit Studio publish workflow demo
Studio publish workflow with platform selection, live preview, process status, and queue tracking.

📌 Quick Facts

LazyEdit is an end-to-end AI-assisted video workflow for creation, processing, and optional publishing. It combines prompt-based generation (Stage A/B/C), media processing APIs, subtitle rendering, keyframe captioning, metadata generation, and AutoPublish handoff.

Quick fact Value
📘 Canonical README README.md (this file)
🌐 Language variants i18n/README.*.md (single language bar is intentionally kept at top)
🧠 Backend entrypoint app.py (Tornado)
🖥️ Frontend app app/ (Expo web/mobile)
🧩 Runtime styles python app.py (manual), ./start_lazyedit.sh (tmux), optional lazyedit.service
🎯 Primary references README.md, references/QUICKSTART.md, references/API_GUIDE.md, references/APP_GUIDE.md
🛠️ Ops references references/DEPLOYMENT_SYSTEMS.md, references/TMUX_SESSIONS.md, references/LAZYEDIT_DATABASE_SPLIT_FROM_ECHOMIND.md, references/LOCAL_DNS_HOST_CACHE.md, references/XIAOHONGSHU_AUTOPUBLISH_LAYOUT_CHANGE_2026_03.md

🧭 Contents

✨ Overview

LazyEdit is built around a Tornado backend (app.py) and an Expo frontend (app/).

Note: If repo/runtime details differ by machine, preserve existing defaults and override via environment variables instead of deleting machine-specific fallbacks.

Why teams use it Practical result
Unified operator flow Upload/generate/remix/publish from one workflow
API-first design Easy to script and integrate with other tools
Local-first runtime Works with tmux + service-based deployment patterns
Step What happens
1 Upload or generate video
2 Transcribe and optionally translate subtitles
3 Burn multilingual subtitles with layout controls
4 Generate keyframes, captions, and metadata
5 Package and optionally publish via AutoPublish

Pipeline focus

  • Upload, generation, remix, and library management from a single operator UI.
  • API-first processing flow for transcription, subtitle polish/translation, burn-in, and metadata.
  • Optional generation-provider integrations (Veo / Venice / A2E / Sora helpers in agi/).
  • Optional publish handoff through AutoPublish.

🎯 At a Glance

Area Included in LazyEdit Status
Core app Tornado API backend + Expo web/mobile frontend
Media pipeline ASR, subtitle translation/polish, burn-in, keyframes, captions, metadata
Generation Stage A/B/C and provider helper routes (agi/)
Distribution Optional AutoPublish handoff 🟡 Optional
Runtime model Local-first scripts, tmux workflows, optional systemd service

🏗️ Architecture Snapshot

The repository is organized as an API-first media pipeline with a UI layer:

  • app.py is the Tornado entrypoint and route orchestrator for upload, processing, generation, publish handoff, and media serving.
  • lazyedit/ contains modular pipeline building blocks (DB persistence, translation, subtitle burn-in, captions, metadata, provider adapters).
  • app/ is an Expo Router app (web/mobile) that drives upload, processing, preview, and publishing flows.
  • config.py centralizes environment loading and default/fallback runtime paths.
  • start_lazyedit.sh and lazyedit_config.sh provide reproducible tmux-based local/deployed run modes.
Layer Main paths Responsibility
API & orchestration app.py, config.py Endpoints, routing, env resolution
Processing core lazyedit/, agi/ Subtitle/caption/metadata pipeline + providers
UI app/ Operator experience (web/mobile via Expo)
Runtime scripts start_lazyedit.sh, lazyedit_config.sh, install_lazyedit.sh Local/service startup and ops

High-level flow:

Upload/Generate -> Transcribe -> Translate/Polish -> Burn Subtitles -> Keyframes/Captions -> Metadata -> Optional AutoPublish

🎬 Demos

Screens below show the main operator path from ingestion to metadata generation.

Home upload
Home · Upload
Home generate
Home · Generate
Home remix
Home · Remix
Library list
Library
Video overview
Video overview
Translation preview
Translation preview
Burn slots
Burn slots
Burn layout
Burn layout
Keyframes and captions
Keyframes + captions
Metadata generator
Metadata generator

🧩 Features

  • ✨ Prompt-based generation workflow (Stage A/B/C) with Sora and Veo integration paths.
  • 🧵 Full processing pipeline: transcription -> subtitle polish/translation -> burn-in -> keyframes -> captions -> metadata.
  • 🌏 Multilingual subtitle composition with furigana/IPA/romaji-related support paths.
  • 🔌 API-first backend with upload, processing, media serving, and publish queue endpoints.
  • 🚚 Optional AutoPublish integration for social-platform handoff.
  • 🖥️ Combined backend + Expo workflow supported via tmux launch scripts.

🌍 Documentation & i18n

  • Canonical source: README.md
  • Language variants: i18n/README.*.md
  • Language navigation: keep a single language-options line at the top of each README (no duplicate language bars)
  • Current languages in this repo: Arabic, German, English, Spanish, French, Japanese, Korean, Russian, Vietnamese, Simplified Chinese, Traditional Chinese

If there is ever a mismatch between translations and English docs, treat this English README as source of truth, then update each language file one-by-one.

i18n policy Rule
Canonical source Keep README.md as source of truth
Language bar Exactly one language-options line at top

🗂️ Project Structure

LazyEdit/
├── app.py                           # Tornado backend entrypoint and API orchestration
├── app/                             # Expo frontend (web/mobile)
├── lazyedit/                        # Core pipeline modules (translation, metadata, burner, DB, templates)
├── agi/                             # Generation provider abstraction (Sora/Veo/A2E/Venice routes)
├── DATA/                            # Runtime media input/output (symlink in this workspace)
├── translation_logs/                # Translation logs
├── temp/                            # Temporary runtime files
├── install_lazyedit.sh              # systemd installer (expects config/start/stop scripts)
├── start_lazyedit.sh                # tmux launcher for backend + Expo
├── stop_lazyedit.sh                 # tmux stop helper
├── lazyedit_config.sh               # Deployment/runtime shell config
├── config.py                        # Environment/config resolution (ports, paths, autopublish URL)
├── .env.example                     # Environment override template
├── references/                      # Additional docs (API guide, quickstart, deployment notes)
├── AutoPublish/                     # Submodule (optional publishing pipeline)
├── AutoPubMonitor/                  # Submodule (monitor/sync automation)
├── whisper_with_lang_detect/        # Submodule (ASR/VAD)
├── vit-gpt2-image-captioning/       # Submodule (primary captioner)
├── clip-gpt-captioning/             # Submodule (fallback captioner)
└── furigana/                        # External dependency in workflow (tracked submodule in this checkout)

Submodule/external dependency note:

  • Git submodules in this repository include AutoPublish, AutoPubMonitor, whisper_with_lang_detect, vit-gpt2-image-captioning, clip-gpt-captioning, and furigana.
  • Operational guidance treats furigana and echomind as external/read-only in this repo workflow. If uncertain, preserve upstream and avoid editing in place.

✅ Prerequisites

Dependency Notes
Linux environment systemd/tmux scripts are Linux-oriented
Python 3.10+ Use Conda env lazyedit
Node.js 20+ + npm Required for Expo app in app/
FFmpeg Must be available on PATH
PostgreSQL Local peer auth or DSN-based connection
Git submodules Required for key pipelines

🚀 Installation

  1. Clone and initialize submodules:
git clone [email protected]:lachlanchen/LazyEdit.git
cd LazyEdit
git submodule update --init --recursive
  1. Activate Conda environment:
source ~/miniconda3/etc/profile.d/conda.sh
conda activate lazyedit
  1. Optional system-level install (service mode):
chmod +x install_lazyedit.sh
sudo ./install_lazyedit.sh --start /path/to/lazyedit

Service install notes:

  • install_lazyedit.sh installs ffmpeg and tmux, validates the lazyedit conda env plus Node/npm/npx, then creates or updates lazyedit.service.
  • Use --start to restart the service immediately after install/update.
  • Re-running the installer is safe; already-installed packages are skipped and the service file is refreshed in place.
  • It does not generate lazyedit_config.sh, start_lazyedit.sh, or stop_lazyedit.sh; these must already exist and be correct.

⚡ Quick Start

Backend + frontend local run (minimal path):

source ~/miniconda3/etc/profile.d/conda.sh
conda activate lazyedit
python app.py

In a second shell:

cd app
npm install
EXPO_PUBLIC_API_URL="http://localhost:8787" npx expo start --web --port 8091

Optional local database bootstrap:

createdb lazyedit_db || true
psql -d lazyedit_db -tAc "SELECT 'ok'"

Or use the repeat-safe helper:

sudo ./scripts/prepare_lazyedit_db.sh

Runtime profiles

Profile Start command Default backend Default frontend
Local dev (manual) python app.py + Expo command 8787 8091 (example command)
Tmux orchestrated ./start_lazyedit.sh 18787 18791
systemd service sudo systemctl start lazyedit.service Config/env-driven N/A

🧭 Command Cheat Sheet

Task Command
Initialize submodules git submodule update --init --recursive
Start backend only python app.py
Start backend + Expo (tmux) ./start_lazyedit.sh
Stop tmux run ./stop_lazyedit.sh
Open tmux session tmux attach -t lazyedit
Service status sudo systemctl status lazyedit.service
Service logs sudo journalctl -u lazyedit.service
DB smoke test python db_smoke_test.py
Pytest smoke test pytest tests/test_db_smoke.py

🛠️ Usage

Development: backend only

source ~/miniconda3/etc/profile.d/conda.sh
conda activate lazyedit
python app.py

Alternate entry used in current deployment scripts:

python app.py -m lazyedit

Backend default URL: http://localhost:8787 (from config.py, override with PORT or LAZYEDIT_PORT).

Development: backend + Expo app (tmux)

./start_lazyedit.sh

Default start_lazyedit.sh ports:

  • Backend: 18787
  • Expo web: 18791
  • EXPO_PUBLIC_API_URL=http://localhost:18787

Attach to session:

tmux attach -t lazyedit

Stop session:

./stop_lazyedit.sh

Service management

sudo systemctl start lazyedit.service
sudo systemctl stop lazyedit.service
sudo systemctl status lazyedit.service
sudo journalctl -u lazyedit.service

⚙️ Configuration

Copy .env.example to .env and update paths/secrets:

cp .env.example .env

Configuration precedence note:

  • config.py loads .env values if present and only sets keys not already exported in the shell.
  • Runtime values can therefore come from: shell-exported env vars -> .env -> code defaults.
  • For tmux/service runs, lazyedit_config.sh controls startup/session parameters (LAZYEDIT_DIR, CONDA_ENV, APP_ARGS, ports via startup script env).

Key variables

Variable Purpose Default/Fallback
PORT, LAZYEDIT_PORT Backend port 8787
LAZYEDIT_UPLOAD_DIR Media root directory DATA/
LAZYEDIT_DATABASE_URL, DATABASE_URL PostgreSQL DSN Local DB fallback lazyedit_db
LAZYEDIT_AUTOPUBLISH_URL AutoPublish endpoint http://localhost:8081/publish
LAZYEDIT_AUTOPUBLISH_TIMEOUT AutoPublish request timeout (seconds) 60
LAZYEDIT_WHISPER_SCRIPT Whisper/VAD script path Environment-dependent
LAZYEDIT_WHISPER_MODEL, LAZYEDIT_WHISPER_FALLBACK_MODEL ASR model names large-v3 / large-v2 (example)
LAZYEDIT_CAPTION_PYTHON Python runtime for caption pipeline Environment-dependent
LAZYEDIT_CAPTION_PRIMARY_ROOT, LAZYEDIT_CAPTION_PRIMARY_SCRIPT Primary captioning path/script Environment-dependent
LAZYEDIT_CAPTION_FALLBACK_SCRIPT, LAZYEDIT_CAPTION_FALLBACK_CWD Fallback captioning path/script/cwd Environment-dependent
GRSAI_API_* Veo/GRSAI integration settings Environment-dependent
VENICE_*, A2E_* Venice/A2E integration settings Environment-dependent
OPENAI_API_KEY Required for OpenAI-backed features None

Machine-specific notes:

  • app.py may set CUDA behavior (CUDA_VISIBLE_DEVICES usage in codebase context).
  • Some paths in defaults are workstation-specific; use .env overrides for portable setups.
  • lazyedit_config.sh controls tmux/session startup variables for deployment scripts.

🧾 Configuration Files

File Purpose
.env.example Template for environment variables used by backend/services
.env Machine-local overrides; loaded by config.py/app.py if present
config.py Backend defaults and environment resolution
lazyedit_config.sh tmux/service runtime profile (deploy path, conda env, app args, session name)
start_lazyedit.sh Launches backend + Expo in tmux with selected ports
install_lazyedit.sh Creates lazyedit.service and validates existing scripts/config

Recommended update order for machine portability:

  1. Copy .env.example to .env.
  2. Set path- and API-related LAZYEDIT_* values in .env.
  3. Adjust lazyedit_config.sh only for tmux/service deployment behavior.

🔌 API Examples

Base URL examples assume http://localhost:8787.

API group Representative endpoints
Upload and media /upload, /upload-stream, /media/*
Video records /api/videos, /api/videos/{id}
Processing /api/videos/{id}/transcribe, /translate, /burn-subtitles, /caption, /metadata, /process
Publish /api/videos/{id}/publish, /api/autopublish/queue
Generation /api/videos/generate (+ provider routes in app.py)

Upload:

curl -F "video=@/path/to/video.mp4" \
     -F "title=my_video" \
     -F "filename=video.mp4" \
     -F "source=api" \
     http://localhost:8787/upload

End-to-end process:

curl -X POST \
  -d "file_path=/abs/path/to/DATA/my_video/video.mp4" \
  -d "use_translation_cache=true" \
  -d "use_metadata_cache=true" \
  http://localhost:8787/video-processing

List videos:

curl http://localhost:8787/api/videos

Publish package:

curl -X POST \
  -H "Content-Type: application/json" \
  -d '{"platforms":{"xiaohongshu":true,"douyin":true}}' \
  http://localhost:8787/api/videos/123/publish

More endpoints and payload details: references/API_GUIDE.md.

Related endpoint groups you will likely use:

  • Video lifecycle: /upload, /upload-stream, /api/videos, /api/videos/{id}, /media/*
  • Processing actions: /api/videos/{id}/transcribe, /api/videos/{id}/translate, /api/videos/{id}/burn-subtitles, /api/videos/{id}/metadata, /api/videos/{id}/caption, /api/videos/{id}/process
  • Generation/provider paths: /api/videos/generate plus Venice/A2E routes exposed in app.py
  • Distribution: /api/videos/{id}/publish, /api/autopublish/queue

🧪 Examples

Frontend local run (web)

cd app
npm install
EXPO_PUBLIC_API_URL="http://localhost:8787" npx expo start --web --port 8091

If backend is on 8887:

EXPO_PUBLIC_API_URL="http://localhost:8887" npx expo start --web --port 8091

Android emulator

EXPO_PUBLIC_API_URL="http://10.0.2.2:8787" npx expo start --android

iOS simulator (macOS)

EXPO_PUBLIC_API_URL="http://127.0.0.1:8787" npx expo start --ios

Optional Sora generation helper

python -m agi.demo_fantasy_woman --seconds 8 --size 1280x720 --output DATA/sora_oracle_valley.mp4

Supported seconds: 4, 8, 12. Supported sizes: 720x1280, 1280x720, 1024x1792, 1792x1024.

🧪 Development Notes

  • Use python from Conda env lazyedit (do not assume system python3).
  • Keep large media out of Git; store runtime media in DATA/ or external storage.
  • Initialize/update submodules whenever pipeline components fail to resolve.
  • Keep edits scoped; avoid unrelated large-formatting changes.
  • For frontend work, backend API URL is controlled by EXPO_PUBLIC_API_URL.
  • CORS is open on the backend for app development.

Submodule and external dependency policy:

  • Treat external dependencies as upstream-owned. In this repository workflow, avoid editing submodule internals unless intentionally working in those projects.
  • Operational guidance in this repo treats furigana (and sometimes echomind in local setups) as external dependency paths; if uncertain, preserve upstream and avoid in-place edits.

Helpful references:

  • references/QUICKSTART.md
  • references/API_GUIDE.md
  • references/APP_GUIDE.md
  • references/DEPLOYMENT_SYSTEMS.md
  • references/TMUX_SESSIONS.md
  • references/LAZYEDIT_DATABASE_SPLIT_FROM_ECHOMIND.md
  • references/LOCAL_DNS_HOST_CACHE.md

Security/config hygiene:

  • Keep API keys and secrets in environment variables; do not commit credentials.
  • Prefer .env for machine-local overrides and keep .env.example as the public template.
  • If CUDA/GPU behavior differs by host, override via environment instead of hardcoding machine-specific values.

✅ Testing

Current formal test surface is minimal and DB-oriented.

Validation layer Command or method
DB smoke python db_smoke_test.py
Pytest DB check pytest tests/test_db_smoke.py
Functional flow Web UI + API run using short sample in DATA/
python db_smoke_test.py
pytest tests/test_db_smoke.py

For functional validation, use the web UI and API flow with a short sample clip in DATA/.

Assumptions and portability notes:

  • Some default paths in code are workstation-specific fallbacks; this is expected in current repo state.
  • If a default path does not exist on your machine, set the corresponding LAZYEDIT_* variable in .env.
  • If uncertain about a machine-specific value, preserve existing settings and add explicit overrides rather than deleting defaults.

🧱 Assumptions & Known Limits

  • The backend dependency set is not pinned by a root lockfile; environment reproducibility currently depends on local setup discipline.
  • app.py is intentionally monolithic in current repo state and contains a large route surface.
  • Most pipeline validation is integration/manual (UI + API + sample media), with limited formal automated tests.
  • Runtime directories (DATA/, temp/, translation_logs/) are operational outputs and can grow significantly.
  • Submodules are required for full functionality; partial checkout often leads to missing-script errors.

🚢 Deployment & Sync Notes

Current known paths and sync flow (from repository operations docs):

  • Development workspace: /home/lachlan/ProjectsLFS/LazyEdit
  • Deployed LazyEdit backend + app: /home/lachlan/DiskMech/Projects/lazyedit
  • Deployed AutoPubMonitor: /home/lachlan/DiskMech/Projects/autopub-monitor
  • Publishing system host: /home/lachlan/Projects/auto-publish on lazyingart
Environment Path Notes
Dev workspace /home/lachlan/ProjectsLFS/LazyEdit Main source + submodules
Deployed LazyEdit /home/lachlan/DiskMech/Projects/lazyedit tmux la-lazyedit in ops docs
Deployed AutoPubMonitor /home/lachlan/DiskMech/Projects/autopub-monitor Monitor/sync/process sessions
Publishing host /home/lachlan/Projects/auto-publish (lazyingart) Pull after submodule updates

After pushing AutoPublish/ updates from this repo, pull on publishing host:

ssh lachlan@lazyingart
cd ~/Projects/auto-publish
git pull github main

🧯 Troubleshooting

Problem Check / Fix
Missing pipeline modules or scripts Run git submodule update --init --recursive
FFmpeg not found Install FFmpeg and confirm ffmpeg -version works
Port conflicts Backend defaults to 8787; start_lazyedit.sh defaults to 18787; set LAZYEDIT_PORT or PORT explicitly
Expo cannot reach backend Ensure EXPO_PUBLIC_API_URL points to active backend host/port
Database connection issues Verify PostgreSQL + DSN/env vars; optional smoke check: python db_smoke_test.py
GPU/CUDA issues Confirm driver/CUDA compatibility with installed Torch stack
Service script fails at install Ensure lazyedit_config.sh, start_lazyedit.sh, and stop_lazyedit.sh exist before running installer

🗺️ Roadmap

  • In-app subtitle/segment editing with A/B preview and per-line controls.
  • Stronger end-to-end test coverage for core API flows.
  • Documentation convergence across i18n README variants and deployment modes.
  • Additional workflow hardening for generation-provider retries and status visibility.

🤝 Contributing

Contributions are welcome.

  1. Fork and create a feature branch.
  2. Keep commits focused and scoped.
  3. Validate changes locally (python app.py, key API flow, and app integration if relevant).
  4. Open a PR with purpose, reproduction steps, and before/after notes (screenshots for UI changes).

Practical guidelines:

  • Follow Python style (PEP 8, 4 spaces, snake_case naming).
  • Avoid committing credentials or large binaries.
  • Update docs/config scripts when behavior changes.
  • Preferred commit style: short, imperative, scoped (for example: fix ffmpeg 7 compatibility).

❤️ Support

Donate PayPal Stripe
Donate PayPal Stripe

📄 License

Apache-2.0

🙏 Acknowledgements

LazyEdit builds on open-source libraries and services, including:

  • FFmpeg for media processing
  • Tornado for backend APIs
  • MoviePy for editing workflows
  • OpenAI models for AI-assisted pipeline tasks
  • CJKWrap and multilingual text tooling in subtitle workflows

About

LazyEdit is a tool to automatically edit videos with AI-assisted auto-caption, auto-transcription, auto-highlight, auto-metadata and auto-subtitles.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors