A high-performance microservice built in Rust that extracts duration information from video files, audio files, and SCORM e-learning packages. Designed for LMS platforms and e-learning tools that need fast, accurate content duration calculations.
- Media duration extraction β MP4, AVI, MOV, WEBM, MKV, MP3, WAV, FLAC, OGG, AAC, WMA, M4A
- SCORM package analysis β SCORM 1.1, 1.2, 2004 (2nd/3rd/4th Edition), and cmi5
- Content time estimation β Reading time from HTML word counts (200 wpm) + quiz time (30s per question)
- Manifest parsing β Extracts
typicalLearningTimeand SCORM 2004 duration limits fromimsmanifest.xml - Multiple file processing β Submit batches of files and get individual + total durations
- File upload support β Both URL-based and multipart upload endpoints
- Configurable output format β
HH:MM:SS,MM:SS, orHH:MM
- Rust 1.86+ (for building from source)
- FFmpeg (ffprobe must be on
PATH) - Docker (optional, for containerized deployment)
git clone https://github.com/joshghent/duration-api.git
cd duration-api
cargo build --releaseThe binary will be at target/release/durationapi.
# Start on default port 3000
./target/release/durationapi serve
# Custom port
./target/release/durationapi serve --port 8080A Docker image is published to GHCR on every merge to main:
docker run -d --name durationapi -p 3000:3000 ghcr.io/joshghent/duration-api:latestOr build it yourself:
docker build -t durationapi .
docker run -d --name durationapi -p 3000:3000 durationapiIt's a standard Docker image β run it however you like.
GET /health
{ "status": "ok" }POST /duration
Content-Type: application/json
Single file:
{
"fileUrl": "https://example.com/video.mp4",
"format": "HH:MM:SS"
}Response:
{
"duration": "00:03:24"
}Multiple files:
{
"files": [
"https://example.com/intro.mp3",
"https://example.com/lecture.mp4"
],
"format": "HH:MM:SS"
}Response:
{
"duration": "00:54:12",
"files": [
{ "file": "intro.mp3", "duration": "00:43:00" },
{ "file": "lecture.mp4", "duration": "00:11:12" }
],
"warnings": []
}SCORM package:
{
"fileUrl": "https://example.com/course.zip"
}Response:
{
"duration": "00:45:30",
"estimatedDuration": "00:52:15",
"scormAnalysis": {
"manifestDuration": "00:30:00",
"wordCount": 2500,
"quizQuestionCount": 10,
"estimatedReadingTime": "00:12:30",
"estimatedQuizTime": "00:05:00"
}
}POST /duration/upload
Content-Type: multipart/form-data
Fields:
filesβ One or more file uploadsformatβ (optional)HH:MM:SS,MM:SS, orHH:MM
Response format is the same as the JSON endpoint.
| Format | Example | Description |
|---|---|---|
HH:MM:SS |
01:30:45 |
Hours, minutes, seconds (default) |
MM:SS |
90:45 |
Total minutes and seconds |
HH:MM |
01:30 |
Hours and minutes (no seconds) |
| Status | Meaning |
|---|---|
| 400 | Bad request / unsupported file |
| 500 | Internal server error |
Errors return JSON:
{ "error": "Description of the problem" }When processing multiple files, unsupported files don't cause the request to fail β they appear in the warnings array with a null duration.
When a .zip file is submitted, the API treats it as a SCORM package:
- Extracts the archive and scans for media files (video/audio)
- Parses
imsmanifest.xmlfortypicalLearningTimeor SCORM 2004 duration limits - Counts words in all HTML/HTM files (used to estimate reading time at 200 words per minute)
- Detects quiz questions in JavaScript files (patterns like
AddQuestion(,new Question(, question object literals) - Returns both actual media duration and an estimated total duration that includes reading time and quiz time
Supported SCORM versions:
- SCORM 1.1
- SCORM 1.2
- SCORM 2004 2nd Edition
- SCORM 2004 3rd Edition
- SCORM 2004 4th Edition
- cmi5
# Install ffmpeg (required for media duration tests)
# macOS: brew install ffmpeg
# Ubuntu: sudo apt-get install ffmpeg
cargo testcargo fmt
cargo clippy -- -D warningssrc/
βββ main.rs # CLI and server setup
βββ lib.rs # Module exports
βββ routes.rs # HTTP endpoint handlers
βββ duration.rs # Core duration extraction and SCORM analysis
βββ models.rs # Request/response types
βββ error.rs # Error types and HTTP conversions
testfiles/ # Test media and SCORM packages
MIT