CLI and library for checking EBU R128 compliance of audio files with S3 upload support
npm install @eyevinn/audio-qcCLI and library for checking EBU R128 compliance of audio files with S3 upload support.
Get started instantly without any setup! This service is available in Open Source Cloud - no need to install dependencies, configure Docker, or manage infrastructure.
``bashSet your OSC access token
export OSC_ACCESS_TOKEN="your-osc-token"
⨠Benefits of Open Source Cloud:
- No local setup required - ready to use immediately
- Pre-configured with FFmpeg and all dependencies
- Scalable cloud infrastructure
- Pay-per-use pricing
- Perfect for testing, prototyping, or production workloads
š Try it now at app.osaas.io
Features
- EBU R128 Compliance Checking: Analyze audio files for loudness, dynamic range, and true peak compliance
- Video Container Support: Extract and analyze audio from MP4, MOV, MXF, AVI, MKV and other video formats
- HTTP(S) Streaming: Stream analysis directly from URLs without downloading (MP4, MXF, MOV, TS)
- Multiple Audio Streams: Detect and select specific audio streams in multi-stream containers
- Multiple Standards: Support for both broadcast and music content standards
- S3 Integration: Upload compliance reports directly to Amazon S3 or MinIO
- CLI and Library: Use as a command-line tool or integrate into your applications
- JSON Reports: Detailed compliance reports in JSON format
- TypeScript Support: Full TypeScript definitions included
Installation
$3
`bash
npm install -g @eyevinn/audio-qc
`$3
`bash
npm install @eyevinn/audio-qc
`Requirements
- Node.js 16 or higher
- FFmpeg and FFprobe installed and available in PATH
CLI Usage
$3
`bash
Analyze local audio file
audio-qc analyze input.wavAnalyze with verbose output
audio-qc analyze input.wav --verboseSave report to file
audio-qc analyze input.wav --output report.jsonOutput as JSON
audio-qc analyze input.wav --jsonAnalyze file from S3 URL
audio-qc analyze s3://my-bucket/audio.wav --verboseAnalyze file from presigned S3 URL
audio-qc analyze "https://mybucket.s3.amazonaws.com/audio.wav?X-Amz-..." --verbose
`$3
`bash
Upload report to S3 (uses AWS CLI credentials)
audio-qc analyze input.wav --s3-bucket my-reports-bucketUpload with custom key
audio-qc analyze input.wav --s3-bucket my-reports-bucket --s3-key my-report.jsonUpload with explicit credentials
audio-qc analyze input.wav \\
--s3-bucket my-reports-bucket \\
--s3-access-key YOUR_ACCESS_KEY \\
--s3-secret-key YOUR_SECRET_KEY \\
--s3-region us-west-2Upload to MinIO or custom S3-compatible service
audio-qc analyze input.wav \\
--s3-bucket my-reports-bucket \\
--s3-endpoint http://localhost:9000 \\
--s3-force-path-style
`$3
`bash
Analyze for broadcast content (default)
audio-qc analyze input.wav --type broadcastAnalyze for music content
audio-qc analyze input.wav --type musicShow standards information
audio-qc standards
audio-qc standards --type broadcast
audio-qc standards --type music
`$3
`bash
Analyze audio from local video files
audio-qc analyze video.mp4 --verbose
audio-qc analyze movie.mov --type broadcast
audio-qc analyze broadcast.mxf --verboseAnalyze video files from S3
audio-qc analyze s3://my-bucket/video.mp4 --verbose
audio-qc analyze "https://bucket.s3.amazonaws.com/video.mxf?X-Amz-..." --verboseList available audio streams in a video file
audio-qc analyze multi-audio.mp4 --list-streams
audio-qc analyze s3://my-bucket/multi-audio.mp4 --list-streamsSelect specific audio stream for analysis
audio-qc analyze multi-audio.mp4 --audio-stream 1 --verbose
audio-qc analyze s3://my-bucket/video.mxf --audio-stream 0 --verboseAnalyze XDCAM HD MXF files from S3
audio-qc analyze "https://bucket.s3.amazonaws.com/XDCAM_file.mxf?X-Amz-..." --audio-stream 0
`Library Usage
$3
`typescript
import { AudioQC } from '@eyevinn/audio-qc';const audioQC = new AudioQC();
const result = await audioQC.analyze({
inputFile: 'path/to/audio.wav'
});
console.log(
File is ${result.isCompliant ? 'compliant' : 'non-compliant'});
console.log(Integrated Loudness: ${result.metrics.integratedLoudness} LUFS);
`$3
`typescript
import { AudioQC } from '@eyevinn/audio-qc';const result = await AudioQC.analyzeFile('audio.wav');
const audioQC = new AudioQC();
await audioQC.analyze({
inputFile: 'path/to/audio.wav',
s3Upload: {
bucket: 'my-reports-bucket',
region: 'us-east-1'
},
outputFile: 'local-report.json',
verbose: true
});
// With MinIO or custom S3-compatible service
await audioQC.analyze({
inputFile: 'path/to/audio.wav',
s3Upload: {
bucket: 'my-reports-bucket',
endpoint: 'http://localhost:9000',
forcePathStyle: true,
accessKeyId: 'minio-access-key',
secretAccessKey: 'minio-secret-key'
}
});
`$3
`typescript
import { AudioQC, EBU_R128_MUSIC_STANDARDS } from '@eyevinn/audio-qc';const audioQC = new AudioQC(EBU_R128_MUSIC_STANDARDS);
const result = await audioQC.analyze({
inputFile: 'music.wav'
});
`$3
`typescript
import { AudioQC, ContainerDetector } from '@eyevinn/audio-qc';// Check if file is a video container
const isVideo = ContainerDetector.isVideoContainer('video.mp4');
// Get container information
const containerInfo = await ContainerDetector.getContainerInfo('video.mp4');
console.log(
Format: ${containerInfo.format}, Audio streams: ${containerInfo.audioStreamCount});// List available audio streams
const audioStreams = await AudioQC.getAudioStreams('multi-audio.mov');
console.log(
Found ${audioStreams.length} audio streams);// Analyze specific audio stream from video
const result = await AudioQC.analyzeFile('video.mp4', undefined, 1); // Use audio stream 1
`$3
`typescript
import { AudioQC, S3Downloader, StreamingAnalyzer } from '@eyevinn/audio-qc';// Check if input is an S3 URL
const isS3 = S3Downloader.isS3Url('s3://bucket/file.wav');
// Check streaming capability for a format
const capability = StreamingAnalyzer.getStreamingCapability('https://bucket.s3.amazonaws.com/video.mp4');
console.log(
Can stream: ${capability.canStream}, Format: ${capability.format});// Analyze file from S3 URL (automatically streams if possible, falls back to download)
const result = await AudioQC.analyzeFile('s3://my-bucket/audio.wav');
// Analyze video from presigned S3 URL (will stream MP4/MXF/MOV automatically)
const videoResult = await AudioQC.analyzeFile(
'https://bucket.s3.amazonaws.com/video.mp4?X-Amz-Signature=...',
undefined, // use default standards
1 // audio stream index
);
// Manual streaming analysis
const streamingResult = await StreamingAnalyzer.analyzeFileFromUrl('https://example.com/video.mp4');
// Manual download (if needed for custom processing)
const localPath = await S3Downloader.downloadFileStatic('s3://bucket/file.wav');
// ... do something with localPath
// Remember to clean up: fs.unlinkSync(localPath);
`$3
`typescript
import { ComplianceChecker } from '@eyevinn/audio-qc';const report = ComplianceChecker.formatReport(result);
console.log(report);
`Streaming vs Download
The tool automatically determines whether to stream or download based on:
$3
- MP4, MOV, M4V - Excellent streaming support
- TS, M2TS - Designed for streaming
- WebM - Good streaming support
- MXF - Good streaming for most variants$3
- AVI - Index usually at end of file
- FLV - Metadata at end
- WMV, RM, RMVB - Poor streaming support$3
- Streaming: Faster analysis, no temporary files, lower bandwidth
- Automatic Fallback: Downloads if streaming fails
- Smart Detection: Tests streaming capability before attemptingEBU R128 Standards
$3
- Integrated Loudness: -24 to -22 LUFS (target: -23 LUFS)
- Loudness Range: max 7 LU
- True Peak: max -1 dBTP$3
- Integrated Loudness: -18 to -14 LUFS (target: -16 LUFS)
- Loudness Range: max 20 LU
- True Peak: max -1 dBTPCompliance Report Format
`json
{
"file": "/path/to/audio.wav",
"isCompliant": false,
"metrics": {
"integratedLoudness": -25.2,
"loudnessRange": 8.1,
"truePeakMax": -0.5,
"momentaryMax": -18.7,
"shortTermMax": -20.1
},
"violations": [
"Integrated loudness -25.2 LUFS is outside acceptable range (-24 to -22 LUFS)",
"Loudness range 8.1 LU exceeds maximum of 7 LU"
],
"timestamp": "2024-01-15T10:30:00.000Z"
}
`S3 Configuration
The tool supports multiple S3-compatible services and authentication methods:
$3
1. AWS CLI credentials (recommended)
2. Environment variables: AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, AWS_REGION
3. EC2/ECS roles (when running on AWS)
4. Explicit credentials via CLI options or library parameters$3
Use custom endpoints with these environment variables:
- S3_ENDPOINT - Custom S3 endpoint URL
- S3_ACCESS_KEY_ID - Access key for the service
- S3_SECRET_ACCESS_KEY - Secret key for the service
- S3_REGION - Region (if required)
- S3_FORCE_PATH_STYLE=true - Use path-style addressing
- S3_SESSION_TOKEN - Session token (if using temporary credentials)$3
The tool checks environment variables in this order:
1. S3-specific: S3_ACCESS_KEY_ID, S3_SECRET_ACCESS_KEY, S3_REGION, S3_ENDPOINT
2. AWS standard: AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, AWS_REGION
3. CLI parameters override environment variables
Docker Usage
$3
`bash
Build the Docker image
./docker-build.shBuild with specific tag
./docker-build.sh -t v1.0.0Build for multiple platforms
./docker-build.sh -p linux/amd64,linux/arm64 --push
`$3
`bash
Basic usage - analyze local audio file
docker run --rm -v $(pwd):/usercontent eyevinntechnology/audio-qc analyze /usercontent/audio.wav --verboseAnalyze video file and save report
docker run --rm -v $(pwd):/usercontent eyevinntechnology/audio-qc \
analyze /usercontent/video.mp4 --output /usercontent/report.jsonAnalyze file from S3 URL
docker run --rm -v $(pwd):/usercontent \
-e S3_ACCESS_KEY_ID=your-key -e S3_SECRET_ACCESS_KEY=your-secret \
eyevinntechnology/audio-qc analyze s3://bucket/audio.wav --verboseAnalyze presigned S3 URL (no credentials needed)
docker run --rm -v $(pwd):/usercontent eyevinntechnology/audio-qc \
analyze "https://bucket.s3.amazonaws.com/video.mxf?X-Amz-Signature=..." --verboseList audio streams in video
docker run --rm -v $(pwd):/usercontent eyevinntechnology/audio-qc \
analyze /usercontent/video.mp4 --list-streamsUpload results to S3
docker run --rm -v $(pwd):/usercontent \
-e S3_ACCESS_KEY_ID=your-key \
-e S3_SECRET_ACCESS_KEY=your-secret \
-e S3_BUCKET=reports-bucket \
eyevinntechnology/audio-qc analyze /usercontent/audio.wav --s3-bucket reports-bucketUse with MinIO
docker run --rm -v $(pwd):/usercontent \
-e S3_ENDPOINT=http://minio:9000 \
-e S3_ACCESS_KEY_ID=minio-key \
-e S3_SECRET_ACCESS_KEY=minio-secret \
-e S3_FORCE_PATH_STYLE=true \
eyevinntechnology/audio-qc analyze /usercontent/audio.wav --s3-bucket my-bucket
`$3
Use the included
docker-compose.yml for local development with MinIO:`bash
Start services with MinIO
docker-compose up minioRun audio analysis with MinIO integration
docker-compose run audio-qc-minioCustom analysis
docker-compose run audio-qc analyze /usercontent/your-file.wav --verbose
`Development
`bash
Install dependencies
npm installBuild the project
npm run buildRun in development mode
npm run devLint and format
npm run lint
npm run formatRun tests
npm test
``MIT