Skip to content

Repository files navigation

Chunked Audio Upload API

Backend API for handling chunked audio uploads from browsers and mobile devices.

Stack

  • TypeScript
  • Express
  • In-memory storage

Quick Start

# 1. Install dependencies
npm install

# 2. Start the server (in a separate terminal)
npm run dev

# 3. Run the test script
./test_all.sh

The test script will automatically split the sample audio file, upload it in chunks, and verify the complete flow works correctly.

Installation

npm install

Running the Server

Development mode (with auto-reload)

npm run dev

Production mode

npm run build
npm start

The server will run on http://localhost:3000 by default.

API Endpoints

1. Create Upload Session

Endpoint: POST /start

Request Body:

{
  "fileName": "audio.mp3",
  "fileType": "mp3",
  "fileSize": 1048576,
  "chunkCount": 10
}

Response:

{
  "uploadId": "550e8400-e29b-41d4-a716-446655440000"
}

2. Upload Chunk

Endpoint: POST /part

Content-Type: multipart/form-data

Form Fields:

  • uploadId: string (the uploadId from /start)
  • chunkNumber: number (0-based index)
  • chunk: file (binary chunk data)

Response:

{
  "uploadId": "550e8400-e29b-41d4-a716-446655440000",
  "chunkNumber": 0,
  "status": "Uploaded"
}

3. Get Upload Status

Endpoint: GET /status/:uploadId

Response:

{
  "uploadId": "550e8400-e29b-41d4-a716-446655440000",
  "status": "InProgress",
  "chunkCount": 10,
  "chunks": [
    { "chunkNumber": 0, "status": "Uploaded" },
    { "chunkNumber": 1, "status": "Uploaded" },
    { "chunkNumber": 2, "status": "Pending" },
    ...
  ]
}

Status Values:

  • InProgress: Upload session is active, chunks are being uploaded
  • Complete: All chunks uploaded and file has been assembled

4. Complete Upload

Endpoint: POST /complete

Request Body:

{
  "uploadId": "550e8400-e29b-41d4-a716-446655440000"
}

Success Response:

{
  "uploadId": "550e8400-e29b-41d4-a716-446655440000",
  "finalFileSize": 1048576,
  "filePath": "/Users/murali/Code/LivaAI/uploads/sample.mp3"
}

Notes:

  • The assembled file is automatically saved to the uploads/ directory
  • /complete is idempotent: calling it multiple times returns the cached result without re-stitching
  • After successful completion, the upload status changes from InProgress to Complete

Error Response (if incomplete):

{
  "error": "Upload incomplete. Missing chunks: 2, 5, 7"
}

Key Features

Out-of-order chunks: Chunks can arrive in any order ✅ Retry handling: Same chunk can be sent multiple times (overwrites previous) ✅ Validation: /complete validates all chunks are present ✅ No corruption: Chunks are reassembled in correct order ✅ Idempotent completion: Calling /complete multiple times is safe - returns cached result without re-stitching ✅ Upload status tracking: Track overall upload state (InProgressComplete)

Automated Testing

Quick Test with Sample Audio

Run the comprehensive test script that automatically tests all API endpoints:

./test_all.sh

What it does:

  1. Splits media/sample.mp3 into 5 chunks
  2. Creates an upload session via POST /start
  3. Uploads chunks out-of-order (2, 0, 4, 1, 3) to test ordering
  4. Re-uploads chunk 2 to test retry/overwrite functionality
  5. Checks status via GET /status/:uploadId
  6. Completes the upload via POST /complete
  7. Verifies final file size matches original
  8. Performs binary comparison to ensure uploaded file is byte-for-byte identical to original
  9. Tests idempotency by calling /complete again (should return cached result)
  10. Cleans up temporary files

Sample output:

========================================
  Chunked Audio Upload API Test
========================================

File Information:
  - Name: sample.mp3
  - Size: 307200 bytes
  - Type: mp3
  - Chunks: 5

✓ File split complete
✓ Upload session created: 550e8400-e29b-41d4-a716-446655440000
✓ All chunks uploaded
✓ Status retrieved
✓ Retry test complete
✓ Upload completed

Step 6: Verifying uploaded file
✓ File size verification: PASSED
  Original: 307453 bytes
  Final:    307453 bytes

Uploaded file location: /Users/murali/Code/LivaAI/uploads/sample.mp3
✓ Binary verification: PASSED
  Files are identical (byte-for-byte match)

Test Incomplete Upload Scenario

Test that the API correctly rejects incomplete uploads:

./test_incomplete.sh

What it does:

  1. Creates an upload session
  2. Attempts to call /complete without uploading any chunks
  3. Verifies the API returns an error message

Example Usage with cURL

1. Start upload

curl -X POST http://localhost:3000/start \
  -H "Content-Type: application/json" \
  -d '{
    "fileName": "test.mp3",
    "fileType": "mp3",
    "fileSize": 1024,
    "chunkCount": 3
  }'

2. Upload chunks

# Chunk 0
curl -X POST http://localhost:3000/part \
  -F "uploadId=YOUR_UPLOAD_ID" \
  -F "chunkNumber=0" \
  -F "chunk=@chunk0.bin"

# Chunk 1
curl -X POST http://localhost:3000/part \
  -F "uploadId=YOUR_UPLOAD_ID" \
  -F "chunkNumber=1" \
  -F "chunk=@chunk1.bin"

# Chunk 2
curl -X POST http://localhost:3000/part \
  -F "uploadId=YOUR_UPLOAD_ID" \
  -F "chunkNumber=2" \
  -F "chunk=@chunk2.bin"

3. Check status

curl http://localhost:3000/status/YOUR_UPLOAD_ID

4. Complete upload

curl -X POST http://localhost:3000/complete \
  -H "Content-Type: application/json" \
  -d '{"uploadId": "YOUR_UPLOAD_ID"}'

Project Structure

/Users/murali/Code/LivaAI/
├── src/
│   ├── index.ts                   # Server entry point
│   ├── app.ts                     # Express app configuration
│   ├── types/
│   │   └── upload.types.ts        # TypeScript interfaces
│   ├── validators/
│   │   └── upload.validators.ts   # Request validation functions
│   ├── services/
│   │   └── upload.service.ts      # Business logic & in-memory storage
│   └── routes/
│       └── upload.routes.ts       # API endpoints
├── media/
│   └── sample.mp3                 # Sample audio file for testing
├── test_all.sh                    # Comprehensive API test script
├── test_incomplete.sh             # Incomplete upload test script
├── package.json
├── tsconfig.json
└── README.md

About

Liva AI Coding Assignment

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages