aeyvision
v0.2.10
Published
JavaScript SDK for Aey Vision API
Maintainers
Readme
AEY Vision JavaScript SDK
Official JavaScript/TypeScript SDK for the AEY Vision API - AI-powered video analytics for security and surveillance.
What's New in v0.2.0 🎉
- 🔧 Fluent Builder Pattern: Chainable, intuitive API for configuration
- 🔄 Automatic Retry Logic: Exponential backoff for network resilience
- 🎯 Custom Error Classes: Better error handling with specific exception types
- 📊 Typed Responses: Strongly typed response models with full TypeScript support
- ❌ Request Cancellation: AbortController support for canceling requests
- ⚡ Enhanced Configuration: Timeout, retry, and other advanced options
- 📦 Better Exports: All types and errors exported from main module
Installation
npm install aeyvisionOr install from source:
git clone https://github.com/yourusername/monorepo.git
cd monorepo/sdks/js
npm install
npm run buildQuick Start
Node.js - Traditional Approach
const { AeyVision } = require('aeyvision');
// Initialize the SDK
const sdk = new AeyVision('your-api-key');
// Configure analysis
const config = [
{
type: 'region_counter',
confidence: 0.5,
classes: ['person', 'car'],
zones: [
{
name: 'entrance',
points: [[0, 0], [100, 0], [100, 100], [0, 100]]
}
]
}
];
// Analyze video
const result = await sdk.analyze({
video: 'path/to/video.mp4',
config: config
});
console.log(result.analyzers);TypeScript - Builder Pattern (New! ⭐)
import { AeyVision } from 'aeyvision';
// Initialize SDK with advanced options
const sdk = new AeyVision('your-api-key', 'https://api.aeyvision.com', {
timeout: 300000,
maxRetries: 3,
retryDelay: 1000
});
// Use fluent builder pattern
const result = await sdk.movementInZone('path/to/video.mp4')
.withZones([{
name: 'entrance',
points: [[0, 0], [100, 0], [100, 100], [0, 100]]
}])
.withClasses(['person', 'car'])
.withConfidence(0.7)
.withAnnotatedVideo(true)
.execute();
console.log(`Detected ${result.analyzers.RegionCounterAnalyzer.total_tracks} objects`);With Request Cancellation
import { AeyVision } from 'aeyvision';
const sdk = new AeyVision('your-api-key');
const controller = new AbortController();
// Cancel after 30 seconds
setTimeout(() => controller.abort(), 30000);
try {
const result = await sdk.analyze({
video: 'video.mp4',
config: [{ type: 'region_counter', zones: [...] }]
}, undefined, controller);
} catch (error) {
if (error.name === 'TimeoutError') {
console.log('Request was cancelled');
}
}Browser
<script type="module">
import { AeyVision } from 'aeyvision';
const sdk = new AeyVision('your-api-key');
// Use with file input
const fileInput = document.querySelector('input[type="file"]');
fileInput.addEventListener('change', async (e) => {
const file = e.target.files[0];
const result = await sdk.analyze({
video: file,
config: [{ type: 'region_counter', zones: [...] }]
});
console.log(result);
});
</script>Features
- Movement in Zone Detection: Track objects entering/exiting defined zones
- PPE Detection: Verify personal protective equipment compliance
- Video Redaction: Automatically blur faces, persons, or license plates
- ALPR: Automatic license plate recognition
- Age & Gender Detection: Analyze demographics and emotional states
- Time in Region: Track how long objects spend in specific areas
- Entry/Exit Counting: Count objects crossing defined lines
- Fall Detection: Detect falls for safety monitoring
Error Handling
The SDK provides specific error classes for better error handling:
import {
AeyVision,
AuthenticationError,
RateLimitError,
ValidationError,
APIError,
NetworkError,
TimeoutError
} from 'aeyvision';
const sdk = new AeyVision('your-api-key');
try {
const result = await sdk.analyze({ video: 'video.mp4', config: [...] });
} catch (error) {
if (error instanceof AuthenticationError) {
console.error('Invalid API key');
} else if (error instanceof RateLimitError) {
console.error(`Rate limited. Retry after ${error.retryAfter} seconds`);
} else if (error instanceof ValidationError) {
console.error(`Invalid configuration: ${error.message}`);
} else if (error instanceof NetworkError) {
console.error(`Network error: ${error.message}`);
} else if (error instanceof TimeoutError) {
console.error(`Request timed out: ${error.message}`);
} else if (error instanceof APIError) {
console.error(`API error ${error.statusCode}: ${error.message}`);
}
}Builder Pattern Examples
PPE Detection
const result = await sdk.ppeDetection('construction-site.mp4')
.withRequiredPPE(['hardhat', 'safety_vest', 'gloves'])
.withConfidence(0.6)
.withAnnotatedVideo(true)
.execute();
if (result.analyzers.PPEAnalyzer.violations.length > 0) {
console.log('PPE violations detected!');
}Video Redaction
const { blob } = await sdk.videoRedaction('sensitive-footage.mp4')
.withClasses(['face', 'license_plate'])
.withBlurKernel(99, 99)
.withBackend('opencv')
.execute();
// Save redacted video in browser
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = 'redacted.mp4';
a.click();Time in Region
const result = await sdk.timeInRegion('store-footage.mp4')
.withZones([{
name: 'checkout_area',
points: [[0.2, 0.2], [0.8, 0.2], [0.8, 0.8], [0.2, 0.8]]
}])
.withFPS(10)
.execute();
for (const [trackId, duration] of Object.entries(result.analyzers.TimeInRegionAnalyzer.time_spent)) {
console.log(`Object ${trackId} spent ${duration}s in checkout area`);
}API Methods
Generic Analysis
await sdk.analyze({
video: VideoInput,
config: AnalyzerConfig[],
return_annotated?: boolean
});Movement in Zone
await sdk.movementInZone(
video: VideoInput,
zones: Zone[],
options?: MovementInZoneOptions,
returnAnnotated?: boolean
);Options:
model: Model to use (default: 'yolo11n.pt')classes: Array of class names to detectconfidence: Confidence threshold (0-1)
PPE Detection
await sdk.ppeDetection(
video: VideoInput,
options?: PPEOptions,
returnAnnotated?: boolean
);Options:
model_path: Custom model pathconfidence: Confidence thresholdrequired_ppe: Array of required PPE items
Video Redaction
await sdk.videoRedaction(
video: VideoInput,
options?: RedactionOptions,
returnAnnotated?: boolean
);Options:
classes: Items to redact (e.g., ['face', 'person', 'license_plate'])backend: Redaction backend ('opencv' or 'deepface')blur_kernel_size: Blur intensity [width, height]fps: Processing frame rate
ALPR (License Plate Recognition)
await sdk.alpr(
video: VideoInput,
options?: ALPROptions,
returnAnnotated?: boolean
);Age & Gender Detection
await sdk.ageEmotion(
video: VideoInput,
options?: AgeEmotionOptions,
returnAnnotated?: boolean
);Options:
backend: Detection backendperson_model: Person detection modelfps: Processing frame ratemin_face_size: Minimum face size to detect
Time in Region
await sdk.timeInRegion(
video: VideoInput,
zones: Zone[],
options?: TimeInRegionOptions,
returnAnnotated?: boolean
);Options:
model: Detection modelfps: Processing frame rate
Entry/Exit Counting
await sdk.entryExit(
video: VideoInput,
zones: Zone[],
options?: EntryExitOptions,
returnAnnotated?: boolean
);Options:
model: Detection modelclasses: Classes to tracklines: Alternative to zones for line-based counting
Fall Detection
await sdk.fallDetection(
video: VideoInput,
options?: FallDetectionOptions,
returnAnnotated?: boolean
);Options:
angle_threshold: Angle threshold for fall detectionaspect_ratio_threshold: Aspect ratio threshold
Types
VideoInput
type VideoInput = File | Blob | Buffer | string;- File/Blob: Browser file input
- Buffer: Node.js buffer
- string: File path (Node.js only)
Zone
interface Zone {
name: string;
points: [number, number][];
color?: [number, number, number];
classes?: string[] | number[];
}Advanced Usage
Get Annotated Video
// Returns a Blob containing the annotated video
const videoBlob = await sdk.analyze({
video: 'input.mp4',
config: [...],
return_annotated: true
});
// Save in Node.js
const buffer = Buffer.from(await videoBlob.arrayBuffer());
fs.writeFileSync('output.mp4', buffer);
// Download in browser
const url = URL.createObjectURL(videoBlob);
const a = document.createElement('a');
a.href = url;
a.download = 'output.mp4';
a.click();Multi-Feature Analysis
Run multiple analyzers on a single video for comprehensive insights. Save 25% on token costs when using 2 or more features together!
Using the Dedicated Method
const result = await sdk.multiFeatureAnalysis({
video: 'video.mp4',
config: [
{
type: 'region_counter',
zones: [{ name: 'entrance', points: [[0,0], [100,0], [100,100], [0,100]] }],
classes: ['person']
},
{
type: 'ppe',
required_ppe: ['hardhat', 'safety_vest']
},
{
type: 'fall_detection',
confidence: 0.6
}
]
});
// Access results for each analyzer
console.log(result.analyzers.RegionCounterAnalyzer);
console.log(result.analyzers.PPEAnalyzer);
console.log(result.analyzers.FallDetectionAnalyzer);Using the Generic Method
const result = await sdk.analyze({
video: 'video.mp4',
config: [
{
type: 'region_counter',
zones: [{ name: 'entrance', points: [[0,0], [100,0], [100,100], [0,100]] }]
},
{
type: 'ppe',
required_ppe: ['helmet', 'vest']
}
]
});Real-World Use Cases
Construction Site Safety
// Monitor PPE compliance, track movement, and detect falls
const result = await sdk.multiFeatureAnalysis({
video: 'construction-site.mp4',
config: [
{ type: 'ppe', required_ppe: ['hardhat', 'safety_vest'] },
{ type: 'region_counter', zones: [{ name: 'restricted_area', points: [[0.2,0.2], [0.8,0.2], [0.8,0.8], [0.2,0.8]] }] },
{ type: 'fall_detection' }
]
});Parking Lot Security
// Track vehicles, read license plates, and monitor entry/exit
const result = await sdk.multiFeatureAnalysis({
video: 'parking-lot.mp4',
config: [
{ type: 'alpr' },
{ type: 'entry_exit', lines: [{ name: 'gate', points: [[0.5,0], [0.5,1]] }] },
{ type: 'region_counter', zones: [{ name: 'parking_zone', points: [[0,0], [1,0], [1,1], [0,1]] }], classes: ['car', 'truck'] }
]
});Retail Analytics
// Analyze customer demographics and track time in regions
const result = await sdk.multiFeatureAnalysis({
video: 'retail-store.mp4',
config: [
{ type: 'age_emotion' },
{ type: 'time_in_region', zones: [{ name: 'product_display', points: [[0.3,0.3], [0.7,0.3], [0.7,0.7], [0.3,0.7]] }] }
]
});Response Structure
{
meta: {
total_frames: 309,
fps: 29.97,
duration: 10.31,
processing_time: 3.58
},
analyzers: {
RegionCounterAnalyzer: {
region_counts: { entrance: 5 },
total_tracks: 5
},
PPEAnalyzer: {
violations: [],
compliance_rate: 1.0
},
FallDetectionAnalyzer: {
falls_detected: 0
}
},
timing: {
processing_time: 3.67,
gpu_seconds: 3.67
},
billing: {
tokens_used: 225, // 25% discount applied (300 → 225)
gpu_seconds: 3.67,
tokens_per_gpu_second: 10
}
}Custom Base URL
const sdk = new AeyVision(
'your-api-key',
'https://custom.api.endpoint.com'
);API Response
{
meta: {
total_frames: number;
fps: number;
duration: number;
processing_time: number;
};
analyzers: {
[analyzerName: string]: {
// Analyzer-specific results
};
};
timing: {
processing_time: number;
gpu_seconds: number;
};
billing: {
tokens_used: number;
gpu_seconds: number;
tokens_per_gpu_second: number;
};
}Error Handling
try {
const result = await sdk.analyze({ video: 'video.mp4', config: [...] });
} catch (error) {
console.error('Analysis failed:', error.message);
}Requirements
- Node.js 14+ or modern browser
- form-data (for Node.js)
TypeScript Support
This SDK is written in TypeScript and includes full type definitions.
License
MIT License - see LICENSE file for details
Support
- Documentation: https://docs.aeyvision.com
- Email: [email protected]
- Issues: https://github.com/yourusername/monorepo/issues
