ExOxvif (ex_oxvif v0.1.0)

Copy Markdown View Source

ONVIF IP camera control for Elixir, backed by the Rust oxvif client.

Find cameras with discover/1, open a session with connect/2, then use the service modules:

For example:

{:ok, [camera | _]} = ExOxvif.discover()
{:ok, session} = ExOxvif.connect(hd(camera.xaddrs), username: "admin", password: "secret")
{:ok, [profile | _]} = ExOxvif.Media.profiles(session)
:ok = ExOxvif.PTZ.absolute_move(session, profile.token, pan: 0.25, tilt: -0.1, zoom: 0.5)

How calls run

Each call is a NIF that returns at once. The request itself runs on a small Tokio runtime inside the native library, which sends the result back to the calling process. Camera network I/O never occupies a BEAM scheduler, and a slow camera only delays the process that asked.

Every call accepts a :timeout option in milliseconds (default 15000). oxvif bounds each HTTP exchange at 10 seconds, so the timeout is a backstop. If it fires, the call returns {:error, %ExOxvif.Error{kind: :timeout}}, and a reply that arrives later may land in the caller's mailbox as {:ex_oxvif_reply, id, result}. Processes that make calls with short timeouts (a GenServer, say) should ignore that message in handle_info/2.

All results are {:ok, value}, :ok, or {:error, %ExOxvif.Error{}}.

Summary

Functions

Connect to a device's ONVIF device service URL, usually http://<host>/onvif/device_service.

Probe the local network for ONVIF devices with WS-Discovery multicast.

Types

call_opts()

@type call_opts() :: [{:timeout, timeout()}]

Functions

connect(url, opts \\ [])

@spec connect(String.t(), keyword()) ::
  {:ok, ExOxvif.Session.t()} | {:error, ExOxvif.Error.t()}

Connect to a device's ONVIF device service URL, usually http://<host>/onvif/device_service.

Fetches the device's capabilities and caches its service URLs.

Options:

  • :username, :password - credentials for WS-Security UsernameToken and HTTP Digest. Give both or neither.
  • :clock_sync - read the device clock first and offset WS-Security timestamps to match it (default true). Cameras with a drifted clock otherwise reject authenticated requests.
  • :timeout - call timeout in milliseconds

discover(opts \\ [])

@spec discover(keyword()) ::
  {:ok, [ExOxvif.DiscoveredDevice.t()]} | {:error, ExOxvif.Error.t()}

Probe the local network for ONVIF devices with WS-Discovery multicast.

Options:

  • :probe_timeout - how long to listen for answers, in milliseconds (default 3000)
  • :timeout - overall call timeout (default probe_timeout + 5000)