The Media Proxy is Fluxer’s specialized service for processing, transforming, and serving media content. It handles image resizing, video thumbnails, format conversion, and content moderation.
Service Overview
The media proxy provides:
Image Processing Resize, crop, and convert images to optimal formats
Video Thumbnails Extract frames from videos for previews
Format Conversion Convert between WebP, PNG, JPEG, and GIF
NSFW Detection Detect and flag explicit content
Architecture
The media proxy is built with:
Hono - High-performance web framework
Sharp - Fast image processing
FFmpeg - Video thumbnail extraction
S3 - Media storage backend
Cloudflare - Edge caching and firewall
Image Processing
GET /proxy/image/{hash}?width=800&height=600&format=webp&quality=80
Path Parameters:
SHA-256 hash of the image
Query Parameters:
Target width in pixels (max: 4096)
Target height in pixels (max: 4096)
Output format: webp, png, jpeg, gif
Quality level: low, medium, high, lossless
Preserve animation (for GIF/WebP)
Quality Settings
Quality WebP JPEG PNG low60 60 Compression 8 medium75 75 Compression 6 high90 90 Compression 4 lossless100 100 Compression 0
Example Requests
Resize Image
Convert to WebP
Thumbnail
curl "https://cdn.fluxer.app/proxy/image/abc123?width=800&height=600"
Video Thumbnails
GET /proxy/thumbnail/{hash}?width=1280&height=720&format=jpeg
Path Parameters:
SHA-256 hash of the video
Query Parameters:
Thumbnail width (max: 1920)
Thumbnail height (max: 1080)
Output format: jpeg, png, webp
Quality level (default: medium)
Timestamp in seconds to extract frame from
Example
curl "https://cdn.fluxer.app/proxy/thumbnail/def456?width=640&height=360×tamp=5"
Proxy external URLs through Fluxer:
GET /proxy/external?url={encoded_url}&width=800
URL-encoded external image URL
Example:
const url = encodeURIComponent ( 'https://example.com/image.png' );
const proxied = `https://cdn.fluxer.app/proxy/external?url= ${ url } &width=800` ;
External media is cached for 24 hours. Excessive requests may be rate limited.
NSFW Detection
Detection Service
The media proxy includes optional NSFW detection:
interface NSFWDetectionResult {
isNSFW : boolean ;
confidence : number ;
labels : Array <{
name : string ;
confidence : number ;
}>;
}
Configuration
export interface MediaProxyConfig {
nsfwModelPath ?: string ; // Path to NSFW detection model
// ...
}
NSFW detection requires a trained model file. This feature is optional and disabled by default.
GET /proxy/metadata/{hash}
Response:
{
"width" : 1920 ,
"height" : 1080 ,
"format" : "png" ,
"size" : 245678 ,
"has_alpha" : true ,
"is_animated" : false ,
"frame_count" : 1 ,
"mime_type" : "image/png"
}
Images: JPEG, PNG, WebP, GIF, BMP, TIFF, SVG
Videos: MP4, WebM, MOV, AVI (for thumbnails)
WebP - Best compression and quality
PNG - Lossless with transparency
JPEG - Wide compatibility
GIF - Animation support
Authentication
Media proxy endpoints require authentication:
GET /proxy/image/abc123
Authorization : Bearer {token}
Or via signed URLs:
GET /proxy/image/abc123?signature={hmac_signature}&expires={timestamp}
Generating Signed URLs
import crypto from 'crypto' ;
function generateSignedUrl (
path : string ,
secretKey : string ,
expiresIn : number = 3600
) : string {
const expires = Math . floor ( Date . now () / 1000 ) + expiresIn ;
const message = ` ${ path }${ expires } ` ;
const signature = crypto
. createHmac ( 'sha256' , secretKey )
. update ( message )
. digest ( 'base64url' );
return ` ${ path } ?signature= ${ signature } &expires= ${ expires } ` ;
}
const url = generateSignedUrl (
'/proxy/image/abc123?width=800' ,
process . env . MEDIA_PROXY_SECRET
);
Caching
The media proxy implements multi-layer caching:
Cloudflare Edge Cache
Cached at edge locations (TTL: 7 days)
In-Memory Cache
Recent transformations cached in memory
S3 Storage
Original media stored in S3
HTTP / 1.1 200 OK
Cache-Control : public, max-age=604800
ETag : "abc123def456"
Last-Modified : Mon, 15 Jan 2024 10:00:00 GMT
Rate Limiting
Media proxy has specific rate limits:
Operation Limit Window Image Processing 100 1 minute Video Thumbnails 20 1 minute External Media 30 1 minute Metadata 200 1 minute
Error Handling
Common Errors
{
"code" : "NOT_FOUND" ,
"message" : "Media not found"
}
HTTP Status: 404
{
"code" : "BAD_REQUEST" ,
"message" : "Invalid width parameter"
}
HTTP Status: 400
{
"code" : "PROCESSING_FAILED" ,
"message" : "Failed to process image"
}
HTTP Status: 500
{
"code" : "RATE_LIMITED" ,
"message" : "Too many requests" ,
"retry_after" : 30
}
HTTP Status: 429
Configuration
export interface MediaProxyConfig {
nodeEnv : 'development' | 'production' ;
secretKey : string ; // HMAC secret for signed URLs
requireCloudflareEdge : boolean ; // Require Cloudflare edge
staticMode : boolean ; // Serve static files only
s3 : S3Config ; // S3 configuration
nsfwModelPath ?: string ; // NSFW model path
}
export interface S3Config {
endpoint : string ; // S3 endpoint URL
region : string ; // S3 region
accessKeyId : string ; // S3 access key
secretAccessKey : string ; // S3 secret key
bucketCdn : string ; // CDN bucket name
bucketUploads : string ; // Uploads bucket name
bucketStatic ?: string ; // Static assets bucket
}
Cloudflare Integration
Edge Firewall
The media proxy includes Cloudflare edge detection:
import { CloudflareFirewall } from '@fluxer/media_proxy' ;
app . use ( '*' , CloudflareFirewall ( config ));
This middleware:
Validates requests come from Cloudflare edge
Blocks direct access when requireCloudflareEdge is enabled
Extracts real client IP from CF-Connecting-IP
Edge Caching
Configure Cloudflare caching:
// Cloudflare Page Rule
Cache Level : Cache Everything
Edge Cache TTL : 7 days
Browser Cache TTL : 1 day
Image Processing
const sharpOptions = {
limitInputPixels: 268402689 , // ~16k x 16k max
sequentialRead: true ,
density: 72
};
Concurrency Control
The media proxy uses a coalescer to prevent duplicate processing:
import { InMemoryCoalescer } from '@fluxer/media_proxy' ;
const coalescer = new InMemoryCoalescer ();
// Only process once for concurrent requests
const result = await coalescer . coalesce ( key , async () => {
return await processImage ( buffer , options );
});
Monitoring
Metrics
The media proxy tracks:
Request count by endpoint and status
Processing time for transformations
Cache hit ratio
Error rate by type
Bandwidth usage
Health Check
Response:
{
"status" : "healthy" ,
"uptime" : 86400 ,
"version" : "1.0.0"
}
Best Practices
Use WebP Request WebP format for best compression and quality. It’s supported by all modern browsers.
Specify Dimensions Always specify width/height to allow the proxy to optimize processing and caching.
Leverage Caching Use consistent URLs for the same transformations to maximize cache hits.
Quality vs Size Use medium quality for most images. Use high only for important images where quality matters.
Client Integration
function getOptimizedImageUrl (
hash : string ,
options : {
width ?: number ;
height ?: number ;
quality ?: 'low' | 'medium' | 'high' ;
format ?: 'webp' | 'png' | 'jpeg' ;
} = {}
) : string {
const params = new URLSearchParams ();
if ( options . width ) params . set ( 'width' , String ( options . width ));
if ( options . height ) params . set ( 'height' , String ( options . height ));
if ( options . quality ) params . set ( 'quality' , options . quality );
if ( options . format ) params . set ( 'format' , options . format );
return `https://cdn.fluxer.app/proxy/image/ ${ hash } ? ${ params } ` ;
}
// Usage
const avatarUrl = getOptimizedImageUrl ( 'abc123' , {
width: 128 ,
height: 128 ,
format: 'webp' ,
quality: 'medium'
});