A Docker-based microservice API for processing media files using FFmpeg commands.
- RESTful API: FastAPI-based service with automatic documentation
- Single & Multi-File Processing: Handle single files or combine multiple videos and audios
- Custom FFmpeg Commands: Execute any FFmpeg command on uploaded files
- Complex Operations: Concatenation, audio mixing, video overlay, and more
- File Download: Return processed files directly through the API
- Health Monitoring: Built-in health check endpoint
- Automatic Cleanup: Temporary files are automatically cleaned up after processing
- Clone or download this repository
- Build and start the service:
docker-compose up --build
-
Build the image:
docker build -t ffmpeg-service . -
Run the container:
docker run -p 8000:8000 ffmpeg-service
- GET
/health- Check service health and FFmpeg availability
- POST
/process- Process single or multiple media files with FFmpeg
files(required): Single media filecommand(required): FFmpeg command (without input/output paths)output_format(optional): Output file extension (e.g., 'mp4', 'avi', 'wav')
files(required): List of media files (2 or more)operation(required): Type of operation ('concat', 'mix_audio', 'overlay', 'merge_av', 'custom')command(optional): Custom FFmpeg command (required for 'custom' operation)output_format(optional): Output file extension (default: 'mp4')options(optional): JSON string with operation-specific options
- concat: Concatenate videos or audios sequentially
- mix_audio: Mix multiple audio tracks together
- overlay: Overlay videos (picture-in-picture effect)
- merge_av: Merge separate audio and video files
- custom: Use custom FFmpeg command with multiple inputs
curl -X POST "http://localhost:8000/process" \
-F "files=@input.mov" \
-F "command=-c:v libx264 -preset fast -crf 23" \
-F "output_format=mp4" \
--output converted.mp4curl -X POST "http://localhost:8000/process" \
-F "files=@large_video.mp4" \
-F "command=-vf scale=640:480 -c:v libx264 -preset fast" \
--output resized_video.mp4curl -X POST "http://localhost:8000/process" \
-F "files=@video.mp4" \
-F "command=-vn -acodec copy" \
-F "output_format=aac" \
--output audio.aaccurl -X POST "http://localhost:8000/process" \
-F "files=@audio.wav" \
-F "command=-acodec mp3 -ab 192k" \
-F "output_format=mp3" \
--output converted_audio.mp3curl -X POST "http://localhost:8000/process" \
-F "files=@video.mp4" \
-F "command=-ss 00:00:01 -vframes 1" \
-F "output_format=jpg" \
--output thumbnail.jpgcurl -X POST "http://localhost:8000/process" \
-F "files=@video1.mp4" \
-F "files=@video2.mp4" \
-F "files=@video3.mp4" \
-F "operation=concat" \
-F "output_format=mp4" \
--output concatenated.mp4curl -X POST "http://localhost:8000/process" \
-F "files=@video1.mp4" \
-F "files=@video2.mp4" \
-F "operation=concat" \
-F 'options={"transition": "fade", "duration": 1.5}' \
-F "output_format=mp4" \
--output faded_concat.mp4curl -X POST "http://localhost:8000/process" \
-F "files=@music.mp3" \
-F "files=@vocals.wav" \
-F "files=@drums.aac" \
-F "operation=mix_audio" \
-F 'options={"volumes": [1.0, 0.8, 0.6], "normalize": true}' \
-F "output_format=mp3" \
--output mixed_audio.mp3curl -X POST "http://localhost:8000/process" \
-F "files=@main_video.mp4" \
-F "files=@overlay_video.mp4" \
-F "operation=overlay" \
-F 'options={"positions": [{"x": 10, "y": 10}]}' \
-F "output_format=mp4" \
--output pip_video.mp4curl -X POST "http://localhost:8000/process" \
-F "files=@video_only.mp4" \
-F "files=@audio_only.mp3" \
-F "operation=merge_av" \
-F 'options={"video_index": 0, "audio_index": 1}' \
-F "output_format=mp4" \
--output merged.mp4curl -X POST "http://localhost:8000/process" \
-F "files=@input1.mp4" \
-F "files=@input2.mp4" \
-F "operation=custom" \
-F "command=-filter_complex [0:v][1:v]hstack=inputs=2" \
-F "output_format=mp4" \
--output side_by_side.mp4{
"transition": "fade", // Add fade transitions between clips
"duration": 1.5 // Transition duration in seconds
}{
"volumes": [1.0, 0.8, 0.6], // Volume levels for each input (0.0-1.0+)
"normalize": true // Apply audio normalization
}{
"positions": [
{"x": 10, "y": 10}, // Position for first overlay
{"x": 100, "y": 50} // Position for second overlay
]
}{
"video_index": 0, // Index of file to use for video
"audio_index": 1 // Index of file to use for audio
}Once the service is running, you can access the interactive API documentation at:
- Swagger UI: http://localhost:8000/docs
- ReDoc: http://localhost:8000/redoc
Here are some common FFmpeg command patterns you can use:
- Scale video:
-vf scale=640:480 - Change quality:
-crf 23(lower = better quality) - Change codec:
-c:v libx264or-c:v libx265 - Set preset:
-preset fast(ultrafast, fast, medium, slow, veryslow)
- Extract audio:
-vn -acodec copy - Change audio codec:
-acodec mp3or-acodec aac - Set audio bitrate:
-ab 192k - Remove audio:
-an
- MP4 to AVI:
-c:v libx264 -c:a mp3 - WAV to MP3:
-acodec mp3 -ab 192k
The API provides detailed error messages for common issues:
- Invalid FFmpeg commands
- Unsupported file formats
- Processing timeouts (5-minute limit)
- File size limitations
- The service runs FFmpeg commands in a containerized environment
- Temporary files are automatically cleaned up
- Processing has a 5-minute timeout to prevent resource exhaustion
- Consider implementing authentication for production use
- Install FFmpeg on your system
- Install Python dependencies:
pip install -r requirements.txt
- Run the application:
python main.py
You can modify the following in main.py:
- Processing timeout (currently 5 minutes)
- Temporary file locations
- API endpoints and parameters
- Error handling behavior