A high-performance, GPU-accelerated video transcoding service built with Elixir that supports NVIDIA, AMD, and Intel GPU acceleration with automatic fallback to CPU encoding.
# Pull the image
docker pull moootid/video_transcoder:latest
# Run with environment variables
docker run -p 4000:4000 \
-e AWS_ACCESS_KEY_ID=your_key \
-e AWS_SECRET_ACCESS_KEY=your_secret \
-e AWS_REGION=us-east-1 \
-e S3_BUCKET=your-bucket \
-e DATABASE_HOST=your-db-host \
-e DATABASE_NAME=video_transcoding \
-e DATABASE_USER=postgres \
-e DATABASE_PASSWORD=your-password \
--gpus all \
moootid/video_transcoder:latest
git clone https://github.com/moootid/video_transcoder.git
cd video_transcoder
cp .env.example .env
# Edit .env with your configuration
docker-compose up -d
POST /transcode
Content-Type: application/json
{
"source_path": "s3://your-bucket/input/video.mp4",
"target_codec": "h264",
"target_container": "mp4",
"quality": "medium",
"bitrate": 2000,
"gpu_preference": "auto",
"created_by": 1
}
Response:
{
"job_id": "550e8400-e29b-41d4-a716-446655440000",
"status": "accepted"
}
GET /status/{job_id}
Response:
{
"job_id": "550e8400-e29b-41d4-a716-446655440000",
"status": "completed",
"source_path": "s3://bucket/input.mp4",
"target_codec": "h264",
"target_container": "mp4",
"output_url": "s3://bucket/transcoded/output.mp4",
"duration_seconds": 45,
"gpu_used": "nvidia",
"created_at": "2025-01-15T10:30:00Z",
"updated_at": "2025-01-15T10:30:45Z"
}
GET /gpu-status
Response:
{
"nvidia": {
"available": true,
"count": 2,
"type": "nvidia"
},
"amd": {
"available": false,
"count": 0,
"type": "amd"
},
"intel": {
"available": true,
"count": 1,
"type": "intel"
}
}
GET /health
| Variable | Description | Default | Required |
|---|---|---|---|
PORT | HTTP server port | 4000 | No |
AWS_ACCESS_KEY_ID | AWS access key | - | Yes |
AWS_SECRET_ACCESS_KEY | AWS secret key | - | Yes |
AWS_REGION | AWS region | - | Yes |
S3_BUCKET | S3 bucket for files | - | Yes |
DATABASE_HOST | Database hostname | - | Yes |
DATABASE_PORT | Database port | 5432 | No |
DATABASE_NAME | Database name | - | Yes |
DATABASE_USER | Database username | - | Yes |
DATABASE_PASSWORD | Database password | - | Yes |
TEMP_DIR | Temporary directory | /tmp/video_transcoding_<user> | No |
| Preset | CRF (CPU) | QP (GPU) | Description |
|---|---|---|---|
low | 28 | 28 | Smaller file size, lower quality |
medium | 23 | 23 | Balanced quality and size |
high | 18 | 18 | Higher quality, larger file size |
| Preference | Description |
|---|---|
auto | Automatically select best available GPU (NVIDIA > AMD > Intel > CPU) |
nvidia | Force NVIDIA GPU, fallback to CPU if unavailable |
amd | Force AMD GPU, fallback to CPU if unavailable |
intel | Force Intel GPU, fallback to CPU if unavailable |
cpu | Force CPU encoding |
mix deps.get
mix ecto.setup
mix run --no-halt
Run the test suite:
mix test
Test GPU detection:
./test_gpu_fallback.exs
Test encoder availability:
./test_encoder_fallback.exs
Test database connection:
./test_db_connection.exs
The service includes built-in Prometheus metrics available at /metrics:
transcoding_jobs_total - Total transcoding jobs by codec, container, GPU, and statustranscoding_duration_seconds - Job duration histogramsactive_transcoding_jobs - Current active jobs gaugegpu_usage_total - GPU usage counters by typehttp_requests_total - HTTP request counters# Average transcoding time by GPU type
rate(transcoding_duration_seconds_sum[5m]) / rate(transcoding_duration_seconds_count[5m])
# Job success rate
rate(transcoding_jobs_total{status="success"}[5m]) / rate(transcoding_jobs_total[5m])
# Current queue depth
active_transcoding_jobs
βββββββββββββββββββ βββββββββββββββββββ βββββββββββββββββββ
β HTTP Client βββββΆβ Video Transcoder βββββΆβ S3 Storage β
βββββββββββββββββββ β Service β βββββββββββββββββββ
βββββββββββββββββββ
β
βΌ
βββββββββββββββββββ βββββββββββββββββββ
β PostgreSQL β β Prometheus β
β Database β β Metrics β
βββββββββββββββββββ βββββββββββββββββββ
VideoTranscoder.Router) - HTTP request handlingExample deployment with GPU support:
apiVersion: apps/v1
kind: Deployment
metadata:
name: video-transcoder
spec:
replicas: 3
selector:
matchLabels:
app: video-transcoder
template:
metadata:
labels:
app: video-transcoder
spec:
containers:
- name: video-transcoder
image: moootid/video_transcoder:latest
ports:
- containerPort: 4000
env:
- name: AWS_ACCESS_KEY_ID
valueFrom:
secretKeyRef:
name: aws-secrets
key: access-key-id
# ... other environment variables
resources:
limits:
nvidia.com/gpu: 1
volumeMounts:
- name: tmp-storage
mountPath: /tmp/transcoding
volumes:
- name: tmp-storage
emptyDir: {}
Enable debug logging by setting the log level:
export ELIXIR_LOG_LEVEL=debug
The service includes comprehensive fallback logic. Test with:
# Test GPU detection in simulated Kubernetes environment
./test_gpu_fallback.exs
# Test encoder availability
./test_encoder_fallback.exs
This project is licensed under the MIT License - see the LICENSEβ file for details.
Content type
Image
Digest
sha256:bba7ef3c0β¦
Size
667.3 MB
Last updated
about 1 year ago
docker pull moootid/video_transcoder