Skip to main content
The Client SDK has two separate event categories that serve different purposes and are subscribed to differently.
CategorySourcePurpose
Connection eventsmanager.on()Camera discovery and connection state
Property & action eventsEventStreamCamera settings changes, warnings, transfers

Connection Events

Emitted by CameraManager (both server and browser variants). Use these to monitor camera discovery, connection state, and errors.

Events table

EventPayloadWhen
camera-found{ camera }New camera detected by polling
camera-lost{ camera }Camera no longer detected (unplugged/offline)
camera-connecting{ cameraId }Connection attempt started
camera-ready{ cameraId, camera }Connected and ready for commands
camera-disconnected{ cameraId, error? }Disconnected (explicit or unexpected)
connection-failed{ cameraId, error, attempt }Connection attempt failed
error{ message }Manager-level error (poll failure, SSE error)

Subscribing

manager.on('camera-found', ({ camera }) => {
  console.log(`Discovered ${camera.model} (${camera.id})`);
});

manager.on('camera-ready', ({ cameraId, camera }) => {
  console.log(`${camera.model} ready for commands`);
});

manager.on('camera-disconnected', ({ cameraId, error }) => {
  if (error) {
    console.log(`Unexpected disconnect: ${error}`);
  } else {
    console.log('Clean disconnect');
  }
});

manager.on('connection-failed', ({ cameraId, error, attempt }) => {
  console.log(`Attempt ${attempt} failed: ${error}`);
});

manager.on('error', ({ message }) => {
  console.error('Manager error:', message);
});

Unsubscribing

// Remove a specific listener
const handler = ({ cameraId }) => console.log('ready', cameraId);
manager.on('camera-ready', handler);
manager.off('camera-ready', handler);

// Remove all listeners for an event
manager.off('camera-ready');

Property & Action Events

Real-time notifications from the camera via SSE. Use EventStream to subscribe to property changes, warnings, autofocus status, file transfers, and errors.

Events table

EventPayloadWhen
connected{ cameraId }Camera connection established (SSE callback from server)
disconnected{ error }Camera disconnected (SSE callback from server)
propertyChanged{ codes }Camera settings changed (ISO, aperture, etc.)
warning{ code }Camera warning (code 0x20011 = photo captured)
afStatus{ state }Autofocus state changed ('focused' | 'unlocked' | 'tracking')
downloadComplete{ filename }File saved to host PC
transferProgress{ percent, filename }File transfer progress
error{ code }SSE connection error

Subscribe to all camera events

import { EventStream } from 'camera-remote-web-api';

const events = new EventStream('http://localhost:8080');

events.on('propertyChanged', (data) => {
  console.log('Properties changed:', data.codes);
});

events.on('warning', (data) => {
  if (data.code === '0x20011') {
    console.log('Photo captured!');
  }
});

events.on('downloadComplete', (data) => {
  console.log('File saved:', data.filename);
});

events.on('afStatus', (data) => {
  console.log('AF state:', data.state);
});

events.on('transferProgress', (data) => {
  console.log(`Transfer: ${data.percent}%`, data.filename);
});

events.on('error', (data) => {
  console.error('SSE error:', data.code);
});

Subscribe to select camera events

Filter events to a single camera by passing a camera ID:
const camEvents = new EventStream('http://localhost:8080', 'D10F60149B0C');

camEvents.on('propertyChanged', (data) => {
  console.log('Camera D10F60149B0C properties changed:', data.codes);
});

Cleanup

// Remove specific callback
const handler = (data) => console.log(data);
events.on('downloadComplete', handler);
events.off('downloadComplete', handler);

// Close SSE connection
events.close();

Using Both Together

Connection events tell you when a camera is ready. Property & action events tell you what’s happening on the camera.
import { CameraManager } from 'camera-remote-web-api/server';
import { EventStream } from 'camera-remote-web-api';

const manager = new CameraManager({ port: 8080, connectionMode: 'remote-transfer' });

// Connection events — monitor lifecycle
manager.on('camera-ready', async ({ cameraId, camera }) => {
  console.log(`${camera.model} connected`);

  // Property events — monitor camera activity
  const events = new EventStream(`http://localhost:${manager.getPort()}`, cameraId);

  events.on('downloadComplete', (data) => {
    console.log(`${camera.model}: file saved — ${data.filename}`);
  });

  events.on('propertyChanged', (data) => {
    console.log(`${camera.model}: settings changed — ${data.codes}`);
  });
});

await manager.start();