{"openapi":"3.0.0","info":{"version":"1.0.0","title":"FFmpeg REST API","description":"A REST API wrapper for FFmpeg media processing operations"},"servers":[{"url":"http://localhost:3000","description":"Development server"}],"components":{"schemas":{"EndpointsResponse":{"type":"object","properties":{"endpoints":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"method":{"type":"string"},"description":{"type":"string"}},"required":["path","method","description"]}}},"required":["endpoints"]},"Error":{"type":"object","properties":{"error":{"type":"string","example":"Invalid file format"},"message":{"type":"string","example":"The uploaded file is not a valid audio format"}},"required":["error"]},"UrlResponse":{"type":"object","properties":{"url":{"type":"string","format":"uri","example":"https://pub-xxx.r2.dev/ffmpeg-rest/2025-01-05-abc123/output.mp3"}},"required":["url"]},"ProbeResponse":{"type":"object","properties":{"format":{"type":"object","properties":{"filename":{"type":"string"},"nb_streams":{"type":"number"},"format_name":{"type":"string"},"format_long_name":{"type":"string"},"duration":{"type":"string"},"size":{"type":"string"},"bit_rate":{"type":"string"}},"required":["filename","nb_streams","format_name","format_long_name","duration","size","bit_rate"]},"streams":{"type":"array","items":{"type":"object","properties":{"index":{"type":"number"},"codec_name":{"type":"string"},"codec_type":{"type":"string"},"codec_long_name":{"type":"string"},"width":{"type":"number"},"height":{"type":"number"},"sample_rate":{"type":"string"},"channels":{"type":"number"}},"required":["index","codec_name","codec_type"]}}},"required":["format","streams"]}},"parameters":{}},"paths":{"/":{"get":{"tags":["General"],"responses":{"200":{"description":"API documentation and readme","content":{"text/html":{"schema":{"type":"string","example":"<h1>FFmpeg REST API</h1>"}}}}}}},"/endpoints":{"get":{"tags":["General"],"responses":{"200":{"description":"List of all available endpoints","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EndpointsResponse"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/health":{"get":{"tags":["General"],"responses":{"200":{"description":"System is active and running","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","example":"ok"},"uptime":{"type":"number","example":120.5},"timestamp":{"type":"string","example":"2024-01-01T12:00:00Z"},"version":{"type":"string","example":"1.0.0"}},"required":["status","uptime","timestamp","version"]}}}}}}},"/audio/mp3":{"post":{"tags":["Audio"],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"type":"object","properties":{"file":{"type":"string","format":"binary","description":"Media file to process"}},"required":["file"]}}}},"responses":{"200":{"description":"Audio converted to MP3 format","content":{"audio/mpeg":{"schema":{"type":"string","format":"binary","description":"Media file to process"}}}},"400":{"description":"Invalid audio file or unsupported format","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Conversion failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"501":{"description":"Not implemented","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/audio/wav":{"post":{"tags":["Audio"],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"type":"object","properties":{"file":{"type":"string","format":"binary","description":"Media file to process"}},"required":["file"]}}}},"responses":{"200":{"description":"Audio converted to WAV format","content":{"audio/wav":{"schema":{"type":"string","format":"binary","description":"Media file to process"}}}},"400":{"description":"Invalid audio file or unsupported format","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Conversion failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"501":{"description":"Not implemented","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/audio/mp3/url":{"post":{"tags":["Audio"],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"type":"object","properties":{"file":{"type":"string","format":"binary","description":"Media file to process"}},"required":["file"]}}}},"responses":{"200":{"description":"Audio converted to MP3 and uploaded to S3","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UrlResponse"}}}},"400":{"description":"Invalid audio file or S3 mode not enabled","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Conversion failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"501":{"description":"Not implemented","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/audio/wav/url":{"post":{"tags":["Audio"],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"type":"object","properties":{"file":{"type":"string","format":"binary","description":"Media file to process"}},"required":["file"]}}}},"responses":{"200":{"description":"Audio converted to WAV and uploaded to S3","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UrlResponse"}}}},"400":{"description":"Invalid audio file or S3 mode not enabled","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Conversion failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"501":{"description":"Not implemented","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/video/mp4":{"post":{"tags":["Video"],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"type":"object","properties":{"file":{"type":"string","format":"binary","description":"Media file to process"}},"required":["file"]}}}},"responses":{"200":{"description":"Video converted to MP4 format","content":{"video/mp4":{"schema":{"type":"string","format":"binary","description":"Media file to process"}}}},"400":{"description":"Invalid video file or unsupported format","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Conversion failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"501":{"description":"Not implemented","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/video/audio":{"post":{"tags":["Video"],"parameters":[{"schema":{"type":"string","enum":["yes","no"],"default":"yes","example":"yes","description":"Extract mono audio (yes) or all channels (no)"},"required":false,"description":"Extract mono audio (yes) or all channels (no)","name":"mono","in":"query"}],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"type":"object","properties":{"file":{"type":"string","format":"binary","description":"Media file to process"}},"required":["file"]}}}},"responses":{"200":{"description":"Extracted audio track as WAV file","content":{"audio/wav":{"schema":{"type":"string","format":"binary","description":"Media file to process"}}}},"400":{"description":"Invalid video file or no audio track found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Extraction failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"501":{"description":"Not implemented","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/video/frames":{"post":{"tags":["Video"],"parameters":[{"schema":{"type":"string","pattern":"^\\d+$","default":1,"example":"1","description":"Frames per second for image extraction"},"required":false,"description":"Frames per second for image extraction","name":"fps","in":"query"},{"schema":{"type":"string","enum":["zip","gzip"],"example":"zip","description":"Compression format for extracted images"},"required":false,"description":"Compression format for extracted images","name":"compress","in":"query"}],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"type":"object","properties":{"file":{"type":"string","format":"binary","description":"Media file to process"}},"required":["file"]}}}},"responses":{"200":{"description":"Extracted frames as compressed archive","content":{"application/zip":{"schema":{"type":"string","format":"binary","description":"Media file to process"}},"application/gzip":{"schema":{"type":"string","format":"binary","description":"Media file to process"}}}},"400":{"description":"Invalid video file or parameters","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Frame extraction failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"501":{"description":"Not implemented","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/video/mp4/url":{"post":{"tags":["Video"],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"type":"object","properties":{"file":{"type":"string","format":"binary","description":"Media file to process"}},"required":["file"]}}}},"responses":{"200":{"description":"Video converted to MP4 and uploaded to S3","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UrlResponse"}}}},"400":{"description":"Invalid video file or S3 mode not enabled","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Conversion failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"501":{"description":"Not implemented","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/video/audio/url":{"post":{"tags":["Video"],"parameters":[{"schema":{"type":"string","enum":["yes","no"],"default":"yes","example":"yes","description":"Extract mono audio (yes) or all channels (no)"},"required":false,"description":"Extract mono audio (yes) or all channels (no)","name":"mono","in":"query"}],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"type":"object","properties":{"file":{"type":"string","format":"binary","description":"Media file to process"}},"required":["file"]}}}},"responses":{"200":{"description":"Extracted audio track uploaded to S3","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UrlResponse"}}}},"400":{"description":"Invalid video file or S3 mode not enabled","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Extraction failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"501":{"description":"Not implemented","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/video/frames/url":{"post":{"tags":["Video"],"parameters":[{"schema":{"type":"string","pattern":"^\\d+$","default":1,"example":"1","description":"Frames per second for image extraction"},"required":false,"description":"Frames per second for image extraction","name":"fps","in":"query"},{"schema":{"type":"string","enum":["zip","gzip"],"example":"zip","description":"Compression format for extracted images"},"required":false,"description":"Compression format for extracted images","name":"compress","in":"query"}],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"type":"object","properties":{"file":{"type":"string","format":"binary","description":"Media file to process"}},"required":["file"]}}}},"responses":{"200":{"description":"Extracted frames archive uploaded to S3","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UrlResponse"}}}},"400":{"description":"Invalid video file or S3 mode not enabled","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Frame extraction failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"501":{"description":"Not implemented","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/video/frames/{filename}":{"get":{"tags":["Video"],"parameters":[{"schema":{"type":"string","example":"image_001.png","description":"Name of the file to download"},"required":true,"description":"Name of the file to download","name":"filename","in":"path"},{"schema":{"type":"string","enum":["yes","no"],"default":"yes","example":"yes","description":"Delete file after download (yes) or keep it (no)"},"required":false,"description":"Delete file after download (yes) or keep it (no)","name":"delete","in":"query"}],"responses":{"200":{"description":"Downloaded frame image","content":{"image/png":{"schema":{"type":"string","format":"binary","description":"Media file to process"}}}},"404":{"description":"Frame not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Download failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"501":{"description":"Not implemented","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/image/jpg":{"post":{"tags":["Image"],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"type":"object","properties":{"file":{"type":"string","format":"binary","description":"Media file to process"}},"required":["file"]}}}},"responses":{"200":{"description":"Image converted to JPG format","content":{"image/jpeg":{"schema":{"type":"string","format":"binary","description":"Media file to process"}}}},"400":{"description":"Invalid image file or unsupported format","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Conversion failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"501":{"description":"Not implemented","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/image/jpg/url":{"post":{"tags":["Image"],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"type":"object","properties":{"file":{"type":"string","format":"binary","description":"Media file to process"}},"required":["file"]}}}},"responses":{"200":{"description":"Image converted to JPG and uploaded to S3","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UrlResponse"}}}},"400":{"description":"Invalid image file or S3 mode not enabled","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Conversion failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"501":{"description":"Not implemented","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/image/resize":{"post":{"tags":["Image"],"parameters":[{"schema":{"type":"string","pattern":"^\\d+$","example":"1920","description":"Target width in pixels (max 8192)"},"required":false,"description":"Target width in pixels (max 8192)","name":"width","in":"query"},{"schema":{"type":"string","pattern":"^\\d+$","example":"1080","description":"Target height in pixels (max 8192)"},"required":false,"description":"Target height in pixels (max 8192)","name":"height","in":"query"},{"schema":{"type":"string","enum":["fit","fill","force"],"default":"fit","example":"fit","description":"Resize mode: fit (preserve aspect ratio, no crop), fill (preserve aspect ratio, crop overflow), force (ignore aspect ratio)"},"required":false,"description":"Resize mode: fit (preserve aspect ratio, no crop), fill (preserve aspect ratio, crop overflow), force (ignore aspect ratio)","name":"mode","in":"query"}],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"type":"object","properties":{"file":{"type":"string","format":"binary","description":"Media file to process"}},"required":["file"]}}}},"responses":{"200":{"description":"Image resized (preserves original format)","content":{"application/octet-stream":{"schema":{"type":"string","format":"binary","description":"Media file to process"}}}},"400":{"description":"Invalid parameters or image file","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Resize failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/image/resize/url":{"post":{"tags":["Image"],"parameters":[{"schema":{"type":"string","pattern":"^\\d+$","example":"1920","description":"Target width in pixels (max 8192)"},"required":false,"description":"Target width in pixels (max 8192)","name":"width","in":"query"},{"schema":{"type":"string","pattern":"^\\d+$","example":"1080","description":"Target height in pixels (max 8192)"},"required":false,"description":"Target height in pixels (max 8192)","name":"height","in":"query"},{"schema":{"type":"string","enum":["fit","fill","force"],"default":"fit","example":"fit","description":"Resize mode: fit (preserve aspect ratio, no crop), fill (preserve aspect ratio, crop overflow), force (ignore aspect ratio)"},"required":false,"description":"Resize mode: fit (preserve aspect ratio, no crop), fill (preserve aspect ratio, crop overflow), force (ignore aspect ratio)","name":"mode","in":"query"}],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"type":"object","properties":{"file":{"type":"string","format":"binary","description":"Media file to process"}},"required":["file"]}}}},"responses":{"200":{"description":"Image resized and uploaded to S3","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UrlResponse"}}}},"400":{"description":"Invalid parameters, image file, or S3 mode not enabled","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Resize failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/media/info":{"post":{"tags":["Media"],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"type":"object","properties":{"file":{"type":"string","format":"binary","description":"Media file to process"}},"required":["file"]}}}},"responses":{"200":{"description":"Media file metadata and stream information","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProbeResponse"}}}},"400":{"description":"Invalid media file","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Probe failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"501":{"description":"Not implemented","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}}}