Skip to content
GanymedeNilPublic

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

video-encoder

English | 中文

A self-hosted video transcoding service with a built-in web console. Submit a video, pick a template, get transcoded outputs back in object storage — powered by FFmpeg, managed by Go, fronted by Astro.

Why

You have videos. You need them in the right format, the right resolution, with watermarks — at scale. video-encoder handles the pipeline: upload → queue → transcode → store → notify, with a web UI for self-service and a REST API for automation.

Features

  • Multi-codec transcoding — H.264 / H.265 / AV1 / VP9, MP4 / WebM containers, CRF or bitrate mode, per-rendition tuning.
  • ABR ladders — one template, multiple renditions (720p / 480p / …), each independently configured.
  • Watermarks — text and image overlays, 9-anchor positioning, opacity, time ranges, auto-scaling across renditions.
  • Thumbnail sprites — generate sprite sheets + WebVTT for player scrubber previews, with or without transcoding.
  • Templates — system presets + tenant custom templates, validated JSONB spec, reusable across jobs.
  • Web console — upload, submit, monitor, manage templates and watermarks, all from the browser.
  • Bilingual UI — English (default) and Chinese, switchable from the sidebar.
  • Webhooks — HMAC-signed callbacks on job completion, per-job or per-tenant.
  • Multi-tenant — API-key auth, isolated tenants, self-service sign-up.

Quick Start

docker compose up -d --build
docker compose run --rm api seed        # load system preset templates
docker compose run --rm api tenant acme # create a tenant → prints your API key

That's it. Three services come up:

Service URL What
Web console http://localhost:4321 Sign up, upload, transcode, manage
API http://localhost:8080 REST API for automation
MinIO http://localhost:9001 Object storage console (minioadmin/minioadmin)

Open the console, sign up, upload a video, pick a template, hit transcode. Done.

Prefer running from source? See Development Setup below.

Try the API

curl -X POST http://localhost:8080/v1/jobs \
  -H "Authorization: Bearer vek_xxxxx" \
  -H "Content-Type: application/json" \
  -d '{
    "template_id": "tpl_mp4_720p",
    "input":  {"storage": "s3://videos/in/src.mp4"},
    "output": {"prefix":  "s3://videos/out/job1"}
  }'
# → {"job_id":"...","status":"queued"}

curl http://localhost:8080/v1/jobs/<job_id> \
  -H "Authorization: Bearer vek_xxxxx"

Architecture

Client ──POST /v1/jobs──▶ API ──enqueue──▶ Worker
                          │                   │ download → FFmpeg → upload
                          ▼                   │
                    Postgres              Object Storage
Client ◀──GET /v1/jobs── API ◀── webhook ──┘

Single Go binary (videoenc) runs as api or worker. Postgres stores state, Redis queues jobs, S3/MinIO holds I/O. The web console is a separate Astro SSR app talking to the API.

Template Spec (Simplified)

{
  "output": { "container": "mp4" },
  "renditions": [
    { "name": "720p", "fit": "letterbox", "encoding": {
        "codec": "h264", "width": 1280, "height": 720, "crf": 23, "preset": "veryfast",
        "audio_bitrate": 128000, "channels": 2 } }
  ],
  "watermarks": [
    { "type": "text", "text": "© 2026", "anchor": "bottom_right",
      "font": "NotoSansSC", "font_size_pct": 4, "color": "white" }
  ],
  "thumbnails": { "columns": 4, "rows": 10 }  // optional sprite + WebVTT
}

Valid combos: MP4 → h264/h265/av1 · WebM → vp9. See the API docs in the console for the full spec.

Development Setup

# Prerequisites: Go 1.25+, Docker, FFmpeg (for local transcode tests)

# Start dependencies
docker compose up -d

# Migrate + seed + create tenant
go run ./cmd/videoenc migrate
go run ./cmd/videoenc seed
go run ./cmd/videoenc tenant acme

# Run api + worker (two terminals)
go run ./cmd/videoenc api
go run ./cmd/videoenc worker

# Frontend (another terminal)
cd web && npm install && npm run dev

# Tests
make test        # Go
cd web && npm test   # Frontend

Key env vars are in .env.example. The Docker image bundles FFmpeg (with drawtext + all encoders) and CJK fonts — no host-side FFmpeg needed.

Roadmap

  • GPU hardware encoding (NVENC / VAAPI)
  • MPEG-DASH output
  • Commercial DRM (Widevine / FairPlay)

License

MIT

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages