Expand description
§oxvif
An async Rust client library for the ONVIF IP camera protocol.
ONVIF (Open Network Video Interface Forum) is the industry standard for interoperability between IP-based security cameras. This library provides a complete async client covering device management, media streaming, PTZ control, imaging, on-screen display, events, recording, search, and replay — all over SOAP/HTTP(S) with WS-Security and HTTP Digest authentication.
§ONVIF Profile coverage
| Profile | Description | Coverage | Notes |
|---|---|---|---|
| Profile S | Video streaming | ~95% | All core operations implemented |
| Profile T | Advanced streaming (H.265, focus, OSD, audio) | ~95% | HTTP Digest Auth, Media2 audio/metadata/analytics config, PTZ compat; Analytics rules and DeviceIO not yet implemented |
| Profile G | Recording & playback | ~85% | Read/search/replay + full recording/job write management; live-source job binding not yet implemented |
§Supported services
- Device — capabilities, scopes, device info, hostname, NTP, reboot, user management, network interfaces/protocols/DNS/gateway, relay outputs, storage configurations, system log/URIs, factory default, discovery mode, firmware upgrade / system restore (upload-URI flow), auxiliary commands (wiper/IR lamp)
- Media1 / Media2 — profiles, RTSP/snapshot URIs, video + audio config, OSD, metadata config, audio decoder/output config, video source modes, unified AddConfiguration/RemoveConfiguration
- PTZ — absolute/relative/continuous move, presets, home position, status, configurations, nodes, compatible configurations
- Imaging — brightness/contrast/exposure settings, focus move/stop/status
- Events — pull-point subscriptions, event polling, renew, unsubscribe,
continuous
event_stream, synchronization point - Recording — list stored recordings; create/delete recordings, tracks, and recording jobs
- Search — find recordings by scope, collect results, end search
- Replay — get RTSP playback URI for a stored recording
- WS-Discovery — UDP multicast probe to find cameras on the local network
§Optional features
health—health::HealthCheck, a fast read-only conformance check that returns ahealth::HealthReport(per-check Pass/Warn/Fail/Skip plus a Profile S/T/G assessment). Pure library code overOnvifSession. Reports serialise to JSON (to_json/to_json_pretty) and a later report can diff against an earlier one viaHealthReport::diff— seeexamples/healthcheck.rs --baseline <file.json>.mock/mock-server— a built-in mock ONVIF device for unit-testing client code without a camera (see themockmodule). Themockfeature also exposesfixtures::CapturingTransport/fixtures::FixtureTransportfor recording real-camera exchanges intotests/fixtures/<vendor>-<model>/and replaying them in tests without the device (seeexamples/record_fixtures.rs).
§Architecture
┌──────────────────────────────────────────────────────┐
│ OnvifSession │
│ caches service URLs — delegates every call │
├──────────────────────────────────────────────────────┤
│ OnvifClient │
│ stateless — you supply service URLs per call │
├──────────────────────────────────────────────────────┤
│ soap::SoapEnvelope │ soap::WsSecurityToken │ ← SOAP layer
├──────────────────────────────────────────────────────┤
│ Transport trait │ ← HTTP abstraction
│ (HttpTransport / mock in tests) │
└──────────────────────────────────────────────────────┘§Quick start
Two ways to use oxvif — pick whichever suits your workflow.
§OnvifSession — URL caching handled for you
OnvifSession calls GetCapabilities once at construction and caches all
service URLs. No URL parameters needed for individual methods.
use oxvif::{OnvifSession, OnvifError};
async fn run() -> Result<(), OnvifError> {
let session = OnvifSession::builder("http://192.168.1.100/onvif/device_service")
.with_credentials("admin", "password")
.with_clock_sync() // syncs WS-Security timestamp with device clock
.build()
.await?;
let profiles = session.get_profiles().await?;
let uri = session.get_stream_uri(&profiles[0].token).await?;
println!("RTSP stream: {}", uri.uri);
let status = session.ptz_get_status(&profiles[0].token).await?;
println!("Pan: {:?} Tilt: {:?}", status.pan, status.tilt);
Ok(())
}§OnvifClient — direct control, you manage service URLs
OnvifClient is stateless and gives direct control over every call.
You fetch and forward service URLs yourself for full routing control.
use oxvif::{OnvifClient, OnvifError};
async fn run() -> Result<(), OnvifError> {
let client = OnvifClient::new("http://192.168.1.100/onvif/device_service")
.with_credentials("admin", "password");
let dt = client.get_system_date_and_time().await?;
let client = client.with_utc_offset(dt.utc_offset_secs());
let caps = client.get_capabilities().await?;
let media_url = caps.media.url.as_deref().unwrap();
let profiles = client.get_profiles(media_url).await?;
let uri = client.get_stream_uri(media_url, &profiles[0].token).await?;
println!("RTSP stream: {}", uri.uri);
Ok(())
}§Testing without a real camera
Enable the mock feature for a built-in, stateful mock ONVIF device and
drive an OnvifClient against it — no network, no real camera. The
mock-server feature additionally provides a bound-port mock::MockServer
for cross-process / non-Rust clients. See the mock module for details.
// Cargo.toml: oxvif = { version = "0.9", features = ["mock"] }
use std::sync::Arc;
use oxvif::{OnvifClient, mock::MockTransport};
let client = OnvifClient::new("http://mock")
.with_transport(Arc::new(MockTransport::new()));
// exercise client commands — Set persists, Get reflects it.For full control you can instead implement transport::Transport yourself
to inject any fixture:
use oxvif::transport::{Transport, TransportError};
use async_trait::async_trait;
use std::sync::Arc;
struct FixtureTransport { xml: String }
#[async_trait]
impl Transport for FixtureTransport {
async fn soap_post(&self, _url: &str, _action: &str, _body: String)
-> Result<String, TransportError>
{
Ok(self.xml.clone())
}
}
let client = oxvif::OnvifClient::new("http://ignored")
.with_transport(Arc::new(FixtureTransport { xml: "<s:Envelope/>".into() }));§Health & conformance checks
Enable the health feature for health::HealthCheck — a fast,
read-only conformance check that reports Pass/Warn/Fail/Skip per ONVIF
service plus a Profile S/T/G verdict. It includes a parse-coverage
dimension that flags when a parser silently drops list data (a wrong element
name returning an empty result with no error). To validate the parsers
against real hardware, the conformance example dumps each device’s raw
responses next to the parsed summary so silent-parse gaps stand out.
Re-exports§
pub use client::OnvifClient;pub use client::notification_listener;pub use discovery::DiscoveredDevice;pub use discovery::DiscoveryEvent;pub use discovery::probe_unicast;pub use error::OnvifError;pub use fixtures::CapturingTransport;pub use fixtures::FixtureTransport;pub use health::HealthCheck;pub use health::HealthReport;pub use session::OnvifSession;pub use session::OnvifSessionBuilder;pub use types::AnalyticsCapabilities;pub use types::AudioDecoderConfiguration;pub use types::AudioEncoderConfiguration;pub use types::AudioEncoderConfigurationOptions;pub use types::AudioEncoderOptions;pub use types::AudioEncoding;pub use types::AudioOutputConfiguration;pub use types::AudioSource;pub use types::AudioSourceConfiguration;pub use types::BoundsRange;pub use types::Capabilities;pub use types::DeviceCapabilities;pub use types::DeviceInfo;pub use types::DeviceIoCapabilities;pub use types::DigitalInput;pub use types::DnsInformation;pub use types::EncoderInstanceInfo;pub use types::EventProperties;pub use types::EventsCapabilities;pub use types::FindRecordingResults;pub use types::FirmwareUpgradeStart;pub use types::FloatRange;pub use types::FocusMove;pub use types::H264Configuration;pub use types::H264Options;pub use types::H265Configuration;pub use types::H265Options;pub use types::Hostname;pub use types::ImagingCapabilities;pub use types::ImagingMoveOptions;pub use types::ImagingOptions;pub use types::ImagingSettings;pub use types::ImagingStatus;pub use types::IntRange;pub use types::IoCapabilities;pub use types::IpStackConfig;pub use types::JpegOptions;pub use types::ManualAddress;pub use types::Media2Capabilities;pub use types::MediaCapabilities;pub use types::MediaProfile;pub use types::MediaProfile2;pub use types::MetadataConfiguration;pub use types::MetadataConfigurationOptions;pub use types::MulticastConfiguration;pub use types::NetworkCapabilities;pub use types::NetworkGateway;pub use types::NetworkInterface;pub use types::NetworkInterfaceConfig;pub use types::NetworkProtocol;pub use types::NotificationMessage;pub use types::NtpInfo;pub use types::OnvifService;pub use types::OsdColor;pub use types::OsdConfiguration;pub use types::OsdOptions;pub use types::OsdPosition;pub use types::OsdTextString;pub use types::PtzCapabilities;pub use types::PtzConfiguration;pub use types::PtzConfigurationOptions;pub use types::PtzNode;pub use types::PtzPreset;pub use types::PtzSpaceRange;pub use types::PtzSpeed;pub use types::PtzStatus;pub use types::PullPointSubscription;pub use types::PushSubscription;pub use types::RecordingCapabilities;pub use types::RecordingConfiguration;pub use types::RecordingInformation;pub use types::RecordingItem;pub use types::RecordingJob;pub use types::RecordingJobConfiguration;pub use types::RecordingJobState;pub use types::RecordingSourceInformation;pub use types::RecordingTrack;pub use types::RelayOutput;pub use types::ReplayCapabilities;pub use types::Resolution;pub use types::SearchCapabilities;pub use types::SecurityCapabilities;pub use types::SetDateTimeRequest;pub use types::SnapshotUri;pub use types::SourceBounds;pub use types::StorageConfiguration;pub use types::StreamUri;pub use types::StreamingCapabilities;pub use types::SystemCapabilities;pub use types::SystemDateTime;pub use types::SystemLog;pub use types::SystemRestoreStart;pub use types::SystemUris;pub use types::User;pub use types::UtcDateTime;pub use types::VideoEncoderConfiguration;pub use types::VideoEncoderConfiguration2;pub use types::VideoEncoderConfigurationOptions;pub use types::VideoEncoderConfigurationOptions2;pub use types::VideoEncoderInstances;pub use types::VideoEncoderOptions2;pub use types::VideoEncoding;pub use types::VideoRateControl;pub use types::VideoRateControl2;pub use types::VideoSource;pub use types::VideoSourceConfiguration;pub use types::VideoSourceConfigurationOptions;pub use types::VideoSourceMode;
Modules§
- client
- High-level ONVIF client.
- discovery
- WS-Discovery — UDP multicast device probe.
- error
- Top-level error type for the oxvif library.
- fixtures
- Record-and-replay SOAP transports for fixture-based testing.
- health
- Fast, scriptable ONVIF health / conformance check for a target device.
- mock
- In-process / bound-port mock ONVIF device for testing client code without a real camera.
- session
- High-level session wrapper around
OnvifClient. - soap
- SOAP protocol layer for ONVIF.
- transport
- HTTP transport abstraction for SOAP over HTTP/HTTPS.
- types
- Typed response structs for all ONVIF operations.