{"id":31642383,"url":"https://github.com/crisog/ffmpeg-rest","last_synced_at":"2026-02-16T07:17:29.795Z","repository":{"id":318333416,"uuid":"1069703055","full_name":"crisog/ffmpeg-rest","owner":"crisog","description":"FFmpeg REST API with S3-compatible Storage Support","archived":false,"fork":false,"pushed_at":"2026-02-16T05:16:19.000Z","size":3332,"stargazers_count":9,"open_issues_count":0,"forks_count":9,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-02-16T06:51:04.032Z","etag":null,"topics":["ffmpeg","ffmpeg-wrapper","queues"],"latest_commit_sha":null,"homepage":"https://railway.com/deploy/ffmpeg-rest-api?referralCode=crisog","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/crisog.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-10-04T13:05:03.000Z","updated_at":"2026-02-16T05:15:16.000Z","dependencies_parsed_at":"2025-10-06T16:36:27.384Z","dependency_job_id":null,"html_url":"https://github.com/crisog/ffmpeg-rest","commit_stats":null,"previous_names":["crisog/ffmpeg-rest"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/crisog/ffmpeg-rest","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/crisog%2Fffmpeg-rest","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/crisog%2Fffmpeg-rest/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/crisog%2Fffmpeg-rest/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/crisog%2Fffmpeg-rest/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/crisog","download_url":"https://codeload.github.com/crisog/ffmpeg-rest/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/crisog%2Fffmpeg-rest/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29502933,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-16T05:57:17.024Z","status":"ssl_error","status_checked_at":"2026-02-16T05:56:49.929Z","response_time":115,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ffmpeg","ffmpeg-wrapper","queues"],"created_at":"2025-10-07T03:58:52.027Z","updated_at":"2026-02-16T07:17:29.790Z","avatar_url":"https://github.com/crisog.png","language":"TypeScript","readme":"# FFmpeg REST API\n\nA REST API that wraps FFmpeg for media processing operations. Built with Node.js, Hono, and BullMQ for reliable async job processing.\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"docs-preview.png\" alt=\"API Documentation Preview\" width=\"800\"\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://railway.com/deploy/ffmpeg-rest-api?referralCode=crisog\"\u003e\n    \u003cimg src=\"https://railway.app/button.svg\" alt=\"Deploy on Railway\"\u003e\n  \u003c/a\u003e\n\u003c/p\u003e\n\n## Features\n\nConvert and process media files through simple HTTP endpoints:\n\n- **Video**: Convert any video to MP4, convert to animated GIF, extract audio tracks (mono/stereo), extract frames at custom FPS (compressed as ZIP/GZIP)\n- **Audio**: Convert any audio to MP3 or WAV\n- **Image**: Convert any image format to JPG\n- **Media Info**: Probe any media file for metadata and stream information\n\n## Storage Modes\n\nThe API supports two storage modes configured via the `STORAGE_MODE` environment variable:\n\n- **`stateless`** (default) - Files returned directly in HTTP responses\n- **`s3`** - Files uploaded to S3-compatible storage, URLs returned\n\n### Stateless Mode (Default)\n\nFiles are processed and returned directly in the HTTP response. Simple and straightforward for immediate consumption.\n\n**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.\n\n### S3 Mode\n\nProcessed 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.\n\n**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.\n\nConfigure S3 mode by setting `STORAGE_MODE=s3` and providing S3 credentials in your environment variables.\n\n#### Content Deduplication\n\nS3 Mode includes intelligent content-based deduplication to optimize storage costs and upload performance:\n\n- **SHA-256 File Hashing**: Each processed file is hashed using SHA-256 before upload\n- **Redis Cache**: File hashes are mapped to S3 URLs with a 90-day TTL (configurable)\n- **Automatic Deduplication**: Identical files are only uploaded once - subsequent requests return the cached S3 URL\n- **Zero-Cost Cache Hits**: When a duplicate file is processed, the upload to S3 is skipped entirely\n- **Graceful Degradation**: Cache failures don't block uploads - the system falls back to normal upload behavior\n\n**Configuration**:\n\n```bash\nS3_DEDUP_ENABLED=1           # Enable/disable deduplication (default: true)\nS3_DEDUP_TTL_DAYS=90         # Cache TTL in days (default: 90)\n```\n\nThis feature dramatically reduces S3 storage costs and upload bandwidth for workloads with duplicate media content, while improving response times through cache hits.\n\n## Documentation\n\nThis API is built with documentation-first approach using **Hono Zod OpenAPI** and **Scalar**:\n\n- **Type-Safe Schemas**: All endpoints use Zod schemas for validation, ensuring type safety and automatic OpenAPI spec generation\n- **Interactive API Reference**: Beautiful, interactive documentation powered by Scalar at `/reference`\n- **OpenAPI 3.1 Spec**: Complete machine-readable API specification at `/doc`\n- **LLM-Friendly Docs**: Markdown documentation optimized for AI assistants at `/llms.txt` (following [llmstxt.org](https://llmstxt.org/) standard)\n\nEvery endpoint is fully documented with request/response schemas, validation rules, and example payloads. No manual documentation maintenance required.\n\n## Quick Start\n\n### Prerequisites\n\n- **Node.js** 20+ and npm\n- **FFmpeg** installed and available in PATH\n- **Redis** server running\n\n### Setup\n\n1. **Clone the repository**\n\n   ```bash\n   git clone https://github.com/crisog/ffmpeg-rest\n   cd ffmpeg-rest\n   ```\n\n2. **Install dependencies**\n\n   ```bash\n   npm install\n   ```\n\n3. **Start Redis** (using Docker)\n\n   ```bash\n   docker-compose up -d\n   ```\n\n4. **Configure environment**\n\n   ```bash\n   cp .env.example .env\n   # Edit .env with your settings\n   ```\n\n5. **Run the API**\n\n   Development mode (with auto-reload):\n\n   ```bash\n   # Terminal 1 - Start the API server\n   npm run dev\n\n   # Terminal 2 - Start the worker\n   npm run dev:worker\n   ```\n\n   Production mode:\n\n   ```bash\n   npm run build\n   npm start\n   ```\n\n## Contribution Policy\n\nFFmpeg REST is open source but only accepting contributions for bug fixes.\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcrisog%2Fffmpeg-rest","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcrisog%2Fffmpeg-rest","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcrisog%2Fffmpeg-rest/lists"}