Skip to content

crisog/ffmpeg-rest

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

110 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

FFmpeg REST API

A REST API that wraps FFmpeg for media processing operations. Built with Node.js, Hono, and BullMQ for reliable async job processing.

API Documentation Preview

Deploy on Railway

Features

Convert and process media files through simple HTTP endpoints:

  • Video: Convert any video to MP4, convert to animated GIF, extract audio tracks (mono/stereo), extract frames at custom FPS (compressed as ZIP/GZIP)
  • Audio: Convert any audio to MP3 or WAV
  • Image: Convert any image format to JPG, resize images while preserving format
  • Media Info: Probe any media file for metadata and stream information

Storage Modes

The API supports two storage modes configured via the STORAGE_MODE environment variable:

  • stateless (default) - Files returned directly in HTTP responses
  • s3 - Files uploaded to S3-compatible storage, URLs returned

Stateless Mode (Default)

Files are processed and returned directly in the HTTP response. Simple and straightforward for immediate consumption.

Cost Consideration: On Railway, stateless mode is cheaper than running S3 Mode unless you have free egress at your S3-storage provider (like Cloudflare R2). Railway charges $0.05 per GB egress vs S3's typical $0.09 per GB, but you trade off file persistence - processed files aren't stored for later retrieval.

Stateless Binary Cache

Stateless mode can optionally cache binary conversion outputs using cacache to avoid rerunning FFmpeg on identical inputs + params.

  • Cache scope: binary conversion endpoints only (not /.../url S3 responses, not /media/info)
  • Cache key: SHA-256 of input bytes + job type + normalized processing params
  • Retention: TTL + size cap (enforced on reads/writes and startup)
  • Storage: local filesystem (ephemeral by default)

Configuration:

CACHE_ENABLED=false             # Enable/disable stateless binary cache
CACHE_DIR=/tmp/ffmpeg-rest/cache # Cache directory (defaults to <TEMP_DIR>/cache)
CACHE_TTL_HOURS=2160            # Entry TTL in hours (90 days)
CACHE_MAX_SIZE_MB=1024          # Max cache size on disk in MiB (1 GiB)

S3 Mode

Processed files are uploaded to S3-compatible storage and a URL is returned. This mode significantly reduces egress bandwidth costs since users download the processed files directly from S3 rather than through your API server. Ideal for production deployments where bandwidth costs matter.

Why Cloudflare R2? R2 is S3-compatible and offers no egress fees, which dramatically lowers costs when serving processed media from your bucket via Cloudflare's global network. While any S3-compatible storage works, R2 is the only major provider with zero egress charges—making it the optimal choice for media delivery.

Configure S3 mode by setting STORAGE_MODE=s3 and providing S3 credentials in your environment variables.

Content Deduplication

S3 Mode includes intelligent content-based deduplication to optimize storage costs and upload performance:

  • SHA-256 File Hashing: Each processed file is hashed using SHA-256 before upload
  • Redis Cache: File hashes are mapped to S3 URLs with a 90-day TTL (configurable)
  • Automatic Deduplication: Identical files are only uploaded once - subsequent requests return the cached S3 URL
  • Zero-Cost Cache Hits: When a duplicate file is processed, the upload to S3 is skipped entirely
  • Graceful Degradation: Cache failures don't block uploads - the system falls back to normal upload behavior

Configuration:

S3_DEDUP_ENABLED=1           # Enable/disable deduplication (default: true)
S3_DEDUP_TTL_DAYS=90         # Cache TTL in days (default: 90)

This feature dramatically reduces S3 storage costs and upload bandwidth for workloads with duplicate media content, while improving response times through cache hits.

Documentation

This API is built with documentation-first approach using Hono Zod OpenAPI and Scalar:

  • Type-Safe Schemas: All endpoints use Zod schemas for validation, ensuring type safety and automatic OpenAPI spec generation
  • Interactive API Reference: Beautiful, interactive documentation powered by Scalar at /reference
  • OpenAPI Spec (/doc): Complete machine-readable API specification (served as OpenAPI 3.0)
  • LLM-Friendly Docs (/llms.txt): Markdown documentation optimized for AI assistants (generated from OpenAPI 3.1, following llmstxt.org standard)

Every endpoint is fully documented with request/response schemas, validation rules, and example payloads. No manual documentation maintenance required.

Quick Start

Prerequisites

  • Node.js 22+ and npm
  • FFmpeg and FFprobe installed and available in PATH
  • Redis server running

Setup

  1. Clone the repository

    git clone https://github.com/crisog/ffmpeg-rest
    cd ffmpeg-rest
  2. Install dependencies

    npm ci
  3. Start Redis (using Docker)

    docker-compose up -d
  4. Configure environment

    cp .env.example .env
    cp apps/web/.env.example apps/web/.env
    # Edit both files with your settings
  5. Run the API

    Development mode (with auto-reload):

    # Starts web + server + worker
    npm run dev

    Or run processes individually:

    npm run dev:server
    npm run dev:worker
    npm run dev:web

    Production mode:

    npm run build
    npm start

Web App + Nitro Proxy

The apps/web workspace is a Vite + TanStack Router frontend with a Nitro catch-all proxy for /api/**.

  • Dev server: npm run dev:web
  • Proxy route: apps/web/routes/api/[...path].ts
  • Frontend API client uses Hono RPC (hc) with shared AppType from the server

Proxy behavior:

  • Requests to /api/** are forwarded to BACKEND_URL (required)
  • Authorization: Bearer ${AUTH_TOKEN} is injected server-side when AUTH_TOKEN is set
  • Browser clients do not need to store or submit AUTH_TOKEN
  • Web dev server runs on http://localhost:5173 (fixed), API server defaults to http://localhost:3000

Environment variables:

BACKEND_URL=http://localhost:3000
AUTH_TOKEN=your-api-token
WEB_PASSWORD=

Contribution Policy

FFmpeg REST is open source but only accepting contributions for bug fixes.

About

FFmpeg REST API with S3-compatible Storage Support

Topics

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages