Skip to main content

Crate oxvif

Crate oxvif 

Source
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

ProfileDescriptionCoverageNotes
Profile SVideo streaming~95%All core operations implemented
Profile TAdvanced 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 GRecording & 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

  • healthhealth::HealthCheck, a fast read-only conformance check that returns a health::HealthReport (per-check Pass/Warn/Fail/Skip plus a Profile S/T/G assessment). Pure library code over OnvifSession.
  • mock / mock-server — a built-in mock ONVIF device for unit-testing client code without a camera (see the mock module).

§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() }));

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 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::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::JpegOptions;
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::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.
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.