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, 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

§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

Implement transport::Transport to inject any XML fixture:

use oxvif::transport::{Transport, TransportError};
use async_trait::async_trait;
use std::sync::Arc;

struct MockTransport { xml: String }

#[async_trait]
impl Transport for MockTransport {
    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(MockTransport { 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 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::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::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.
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.