SoloTech.Get in touch
← Back to the project
GOVIRALDEV SOURCE CODE

Setup guide.

A self-hostable AI faceless-video auto-poster. You bring API keys; it generates a daily AI video per account and posts it on schedule.

Overview

Each scheduled post runs one resumable pipeline:

AI character → AI video (Kling) → AI music (Stable Audio) → viral text overlay → + your app demo → caption → publish (Zernio).

You describe your app once; a minute-by-minute cron fires due slots; a detached worker runs each job and is crash-resumable. Provider usage is billed to your own accounts. Configure a daily generation budget before running real jobs.

Requirements

Quick start

php bin/setup.php                 # checks deps, creates .env, inits the SQLite DB
$EDITOR .env                      # fill in FAL_KEY, OPENAI_API_KEY, R2_*, GOOGLE_CLIENT_ID, secrets
php -S 127.0.0.1:8090 public/index.php
# open http://127.0.0.1:8090 → sign in

Then in the app: connect your Zernio key → create a workspace → add accounts → set up an AI character per account → upload your app-demo clips → set a schedule.

Keep DRY_RUN=1 until you've watched a video generate end-to-end. Flip to 0 to post for real.

Environment

Everything is in .env (gitignored, chmod 600). See .env.example for every key with notes. Generate secrets with php -r "echo bin2hex(random_bytes(32)).PHP_EOL;".

KeyWhat
FAL_KEYfal.ai — AI image / video / music
FAL_DAILY_BUDGET_USDkill-switch: stop generating past this daily spend
OPENAI_API_KEY / OPENAI_MODELcaption + on-video hook text
R2_*Cloudflare R2 (S3-compatible) storage
GOOGLE_CLIENT_IDsign-in (Authorized JS origin = APP_URL)
APP_NAMEyour brand (navbar + titles)
DRY_RUN1 = generate but don't post

Operator access

Single-operator by design. ENTITLEMENT_ALLOWLIST empty = open (anyone who signs in); set it to your email to lock the instance to yourself. ADMIN_EMAILS controls admin-only features.

The pipeline

Per post: a fresh variation of the account's locked character image → a 5s Kling reaction clip → a Stable Audio bed (vibe per character) → the OpenAI hook is burned on TikTok-style (white + black stroke, centered) → your app-demo clip is appended → muxed with the music → an OpenAI caption → published via Zernio. State persists per stage so a crashed worker resumes.

First real post

  1. Set up an AI character on an account (Schedule tab → describe → save).
  2. Upload at least one app-demo clip (Library tab).
  3. Enable a schedule hour, or watch the cron fire the due slot.
  4. Watch the Overview dashboard light up IMAGE → VIDEO → MUSIC → OVERLAY → PUBLISH.

Deploy

Serve public/ with PHP-FPM behind Caddy/nginx. Add the cron (every minute):

* * * * * php /path/to/app/bin/cron.php >> /path/to/app/logs/cron.log 2>&1

Set APP_ENV=production, DEV_LOGIN=0, and a real SESSION_COOKIE_DOMAIN.

Customize

Code layout

public/        index.php (front controller) + views + assets
src/           gen_pipeline, fal_client, openai_caption, ffmpeg_mux,
               zernio_client, r2_client, media_select, auth, gate, db, crypto
bin/           cron.php (scheduler), gen_worker.php (one job), setup.php
db/schema.sql  SQLite schema (IF NOT EXISTS; safe to re-apply)

Support

Questions? Email [email protected]. License terms are in LICENSE.