Skip to content

This package works with a variety of ONVIF compatible devices allowing for IP Cameras and NVRs (network video recorders) to be integrated into Dart and Flutter applications.

License

Notifications You must be signed in to change notification settings

SentraCam/easy_onvif

 
 

Repository files navigation

Dart Implementation of ONVIF IP Camera Client

This package works with a variety of ONVIF compatible devices allowing for IP Cameras and NVRs (network video recorders) to be integrated into Dart and Flutter applications. The package includes the ability to control the PTZ (pan-tilt-zoom) movements of a device along with managing presets as well as controlling how video and audio is being streamed from the device. Review the documentation below to get more details on available features.

pub package License: MIT

Buy me a coffee

Build Status github last commit github build github issues

Table of contents

Getting Started

Dependency

To use this package in your code, first add the dependency to your project:

dependencies:
  ...
  easy_onvif: ^3.0.1+1

If you need additional help getting started with dart, check out these guides.

Usage Example

Import the easy_onvif library.

import 'package:easy_onvif/onvif.dart';

final onvif = await Onvif.connect(
 host: [hostname or ip address],
 username: [username],
 password: [password]);

Interacting with a device through Onvif operations

It's important to understand that all Onvif commands have an associated Access Policy assigned to them based on the table below:

Administrator Operator User Anonymous
PRE_AUTH X X X X
READ_SYSTEM X X X
READ_SYSTEM_SENSITIVE X X
READ_SYSTEM_SECRET X
WRITE_SYSTEM X
UNRECOVERABLE X
READ_MEDIA X X X
ACTUATE X X

You can find the command and it's Access Policy in the API reference or in the spec PDF (links in the table below). As shown in the above table, a user with Administrator access can use all Onvif commands. It is recommended that you authenticate with an Administrator while using this package to avoid unexpected errors when sending your device different Onvif commands.

Through the deviceManagement operations you can get information about the connected device.

var deviceInfo = await onvif.deviceManagement.getDeviceInformation(); // Access Class: READ_SYSTEM

print(deviceInfo.model);

Many operations require you to supply a profileToken which can be retrieved through media operations.

var profiles = await onvif.media.getProfiles(); // Access Class: READ_MEDIA

profiles.forEach((element) {
 print('${element.name}  ${element.token}');
});

var profileToken = profiles.first.token;

With the ptz operations you can get a list of camera presets from the connected device.

var presets = await onvif.ptz.getPresets(profileToken); // ACCESS CLASS: READ_MEDIA

//get a specific preset
var preset = presets[11];

//print the preset values
print(
 'preset: ${preset.position.panTilt?.x}  ${preset.position.panTilt?.y}  ${preset.position.zoom?.x}');

//use the GotoPreset operation to point the camera to the given preset
await onvif.ptz.gotoPreset(profileToken, preset); // ACCESS CLASS: ACTUATE

Be sure to look through the API Reference for information about the parameters required for the supported Onvif operations.

Lower level requests

In cases where there is no helper method for a specific Onvif operation, a low-level call can be used to make the request to the device. The code below performs the GetAudioOutputs Media1 operation. All responses take the form of a hashmap Map<String,dynamic>.

// code fragment for a sample low level request
//
// build a xml fragment for the specific Onvif operation
Transport.builder.element('GetStatus', nest: () { // ACCESS CLASS: READ_MEDIA
  Transport.builder.namespace(Xmlns.tptz);

  ReferenceToken(profileToken).buildXml(builder);
});

// using the connected onvif object from the earlier example
final transport = onvif.transport;

// build the soap request envelope and send the request
// since this is a media1 request, send to the media1 endpoint
final responseEnvelope = await transport.securedRequest( // include a Security header in the request
    onvif.ptz.uri,
    soap.Body(
      request: Transport.builder.buildFragment(),
    ));

print(responseEnvelope.body.response);

Onvif cli (Onvif at the command prompt)

A command line interface for controlling an Onvif device with cli commands

Install using dart pub:

dart pub global activate easy_onvif

Install using brew:

brew tap faithoflifedev/easy_onvif
brew install onvif

Run the following command to see help:

onvif --help

Result,

A command line interface for controlling Onvif compliant devices

Usage: onvif <command> [arguments]

Global options:
-h, --help           Print this usage information.
    --config-file    (defaults to "/Users/chris/.onvif/credentials.json")
    --log-level      [all, debug, info, warning, error, off (default)]

Available commands:
  authorize           Generate an authentication file for an Onvif device.
  debug               Generate a debug bundle for an Onvif device.
  device-management   Device management commands.
  imaging             Imaging commands.
  media1              Media ver10 commands.
  media2              Media ver20 commands.
  probe               Probe/device discovery command.
  ptz                 PTZ commands.
  recordings          Recordings commands.
  replay              Replay commands.
  search              Search commands.
  version             Display the package name and version.

Run "onvif help <command>" for more information about a command.

Please see the cli documentation README.md for more detailed usage information.

Supported Onvif Operations

Device Management

Onvif Operation Dart Method Dart Return Type Test
CreateUsers createUsers Future<bool> [x]
DeleteUsers deleteUsers Future<bool> [x]
GetCapabilities getCapabilities Future<Capabilities> [x]
GetDeviceInformation getDeviceInformation Future<GetDeviceInformationResponse> [x]
GetDiscoveryMode getDiscoveryMode Future<String> [x]
GetDNS getDNS Future<DnsInformation> [x]
GetEndpointReference getEndpointReference Future<Map<String, dynamic>> [ ]
GetHostname getHostname Future<HostnameInformation> [x]
GetNetworkProtocols getNetworkProtocols Future<List<NetworkProtocol>> [x]
GetNTP getNtp Future<NtpInformation> [x]
GetServiceCapabilities getServiceCapabilities Future<DeviceServiceCapabilities> [x]
GetServices getServices Future<List<Service>> [x]
GetStorageConfiguration getStorageConfiguration Future<StorageConfiguration> [ ]
GetStorageConfigurations getStorageConfigurations Future<List<StorageConfiguration>> [ ]
GetSystemDateAndTime getSystemDateAndTime Future<SystemDateAndTime> [x]
GetSystemUris getSystemUris Future<GetSystemUrisResponse> [x]
GetSystemLog getSystemLog Future<SystemInformation> [ ]
GetSystemSupportInformation getSystemSupportInformation Future<SystemInformation> [ ]
GetUsers getUsers Future<List<User>> [x]
SystemReboot systemReboot Future<String> [ ]

Imaging

Onvif Operation Dart Method Dart Return Type Test
GetCurrentPreset getCurrentPreset Future<ImagingPreset> [ ]
GetPresets getPresets Future<List<ImagingPreset>> [ ]
GetServiceCapabilities getServiceCapabilities Future<Capabilities> [ ]
GetStatus getStatus Future<Status> [ ]
SetCurrentPreset setCurrentPreset Future<bool> [ ]

Media 10

Onvif Operation Dart Method Dart Return Type Test
GetAudioSources getAudioSources Future<List<AudioSource>> [x]
GetMetadataConfiguration getMetadataConfiguration Future<MetadataConfiguration> [x]
GetMetadataConfigurations getMetadataConfigurations Future<List<MetadataConfiguration>> [x]
GetProfile getProfile Future<Profile> [x]
GetProfiles getProfiles Future<List<Profile>?> [x]
GetServiceCapabilities getServiceCapabilities Future<Capabilities1> [x]
GetSnapshotUri getSnapshotUri Future<MediaUri> [x]
GetStreamUri getStreamUri Future<MediaUri> [x]
GetVideoSources getVideoSources Future<VideoSources> [x]
StartMulticastStreaming startMulticastStreaming Future<bool> [x]
StopMulticastStreaming stopMulticastStreaming Future<bool> [x]

Media 20

Onvif Operation Dart Method Dart Return Type Test
GetMetadataConfigurationOptions getMetadataConfigurationOptions Future<MetadataConfigurationOptions> [x]
GetMetadataConfigurations getMetadataConfigurations Future<List<MetadataConfiguration>> [x]
GetProfiles getProfiles Future<List<MediaProfile>?> [x]
GetServiceCapabilities getServiceCapabilities Future<Capabilities2> [x]
GetSnapshotUri getSnapshotUri Future<String> [x]
GetStreamUri getStreamUri Future<String> [x]
GetVideoEncoderInstances getVideoEncoderInstances Future<Info> [ ]
GetVideoSourceConfigurationOptions getVideoSourceConfigurationOptions Future<VideoSourceConfigurationOptions> [x]
GetVideoEncoderConfigurations getVideoEncoderConfigurations Future<List<VideoEncoder2Configuration>> [ ]
StartMulticastStreaming startMulticastStreaming Future<bool> [x]
StopMulticastStreaming stopMulticastStreaming Future<bool> [x]

PTZ

Onvif Operation Dart Method Dart Return Type Test
AbsoluteMove absoluteMove Future<bool> [x]
ContinuousMove continuousMove Future<bool> [x]
GetCompatibleConfigurations getCompatibleConfigurations Future<List<PtzConfiguration>> [x]
GetConfiguration getConfiguration Future<PtzConfiguration> [x]
GetConfigurationOptions getConfigurationOptions Future<PtzConfigurationOptions> [x]
GetConfigurations getConfigurations Future<List<PtzConfiguration>> [x]
GetPresets getPresets Future<List<Preset>> [x]
GetPresetTour getPresetTour Future<PresetTour> [ ]
GetPresetTours getPresetTours Future<List<PresetTours>> [ ]
GetServiceCapabilities getServiceCapabilities Future<Capabilities> [x]
GetStatus getStatus Future<PtzStatus> [x]
GotoHomePosition gotoHomePosition Future<bool> [x]
GotoPreset gotoPreset Future<bool> [x]
RelativeMove relativeMove Future<bool> [x]
RemovePreset removePreset Future<bool> [x]
SetHomePosition setHomePosition Future<bool> [x]
SetPreset setPreset Future<String> [x]
Stop stop Future<bool> [x]

PTZ Helper Methods

Onvif Operation Dart Method Return Type
N/A move Future<void>
N/A moveDown Future<void>
N/A moveLeft Future<void>
N/A moveRight Future<void>
N/A moveUp Future<void>
N/A zoomIn Future<void>
N/A zoomOut Future<void>
N/A getCurrentPreset Future<Preset?>

Recording

Onvif Operation Dart Method Dart Return Type Test
CreateRecording createRecording Future<String> [ ]
CreateRecordingJob createRecordingJob Future<CreateRecordingJobResponse> [ ]
DeleteRecording deleteRecording Future<bool> [ ]
DeleteRecordingJob deleteRecordingJo Future<bool> [ ]
GetRecordingJobs getRecordingJobs Future<List<GetRecordingJobsResponseItem>> [ ]
GetRecordingJobState getRecordingJobState Future<List<RecordingJobStateInformation>> [ ]
GetRecordingOptions getRecordingOptions Future<List<RecordingOptions>> [ ]
GetRecordings getRecordings Future<List<GetRecordingsResponseItem>> [ ]
GetServiceCapabilities getServiceCapabilities Future<Capabilities> [ ]
setRecordingJobMode setRecordingJobMode Future<bool> [ ]

Replay

Onvif Operation Dart Method Dart Return Type Test
GetReplayConfiguration getReplayConfiguration Future<ReplayConfiguration> [ ]
GetReplayUri getReplayUri Future<String> [ ]
GetServiceCapabilities getServiceCapabilities Future<Capabilities> [ ]
SetReplayConfiguration setReplayConfiguration Future<bool> [ ]

Search

Onvif Operation Dart Method Dart Return Type Test
FindRecordings findRecordings Future<String> [ ]
GetRecordingSearchResults getRecordingSearchResults Future<List<FindRecordingResult>> [ ]
GetRecordingInformation getRecordingInformation Future<RecordingInformation> [ ]
GetRecordingSummary getRecordingSummary Future<RecordingSummary> [ ]

Tested Onvif Devices

The values returned by the Onvif API GetDeviceInformation call.

Manufacturer Model Firmware Version Known Issue
Happytimesoft IPCamera limited capabilities
ONVIF ENP1A14-IR/25X commands not implemented¹
D-Link Corporation DCS-6511 commands not implemented²
[empty] GX728MF-IR28 commands not implemented³
LOREX LNB4421SB testing in progress
ONVIF_IPNC IPG-8150PSS 1.3.0-20210203CN-PT commands not implemented⁴
SUNBA Performance-Series IPC-B2202.3.73.C06290.NB.230628 commands not implemented⁵

¹ The ENP1A14-IR/25X does not support the following commands:

  • Recordings
    • CreateRecording
    • DeleteRecording

² The DCS-6511 does not support the following commands:

  • Device Management:
    • GetServices
    • GetServiceCapabilities
  • Media1:
    • GetMetadataConfiguration
    • GetProfile
    • GetServiceCapabilities
  • Media2:
    • is not supported by this device
  • PTZ:
    • not tested

³ The GX728MF-IR28 does not support the following commands:

  • Device Management:
    • GetSystemUris
  • Media1:
    • GetMetadataConfiguration
    • GetProfile
    • GetStreamUri
    • StartMulticastStreaming
    • StopMulticastStreaming
  • Media2:
    • GetStreamUri
    • StartMulticastStreaming
    • StopMulticastStreaming
  • PTZ:
    • not supported

⁴ The IPG-8150PSS does not support the following commands:

  • Device Management:
    • GetStorageConfigurations
    • GetStorageConfiguration
    • GetEndpointReference
    • GetSystemSupportInformation
  • PTZ
    • GetPresetTours
    • GetPresetTour
    • GotoHomePosition - supported but not functioning
    • SetHomePosition - supported but not functioning

⁵ The SUNBA does not support the following commands:

  • Device Management:
    • CreateUsers
    • DeleteUsers
    • GetStorageConfigurations
    • GetStorageConfiguration
    • GetSystemUris
  • Media1:
    • GetStreamUri - but it works in Media2
  • PTZ:
    • GotoHomePosition - No Home Position
    • RelativeMove - work-around available with the move helper
    • SetHomePosition

New for version 3.0.0-dev.0

Bug fixes for a number of small bugs that got introduced through adding some experimental features in some of the previous releases. The main issues identified and resolved where in the areas of Authentication Issue #58, PTZ Issue #54 and the Media2 module (no issue reported). In addition all currently supported SOAP requests now have unit tests to confirm that the package continues to create the requests properly as the code evolves. Finally, there have been extensive code revisions to help with the long term maintenance of the package. As part of this a number of method signatures have changed as well as some of the objects in the object model have been renamed. For the most part these changes are in the lower level interfaces within the package and should not affect many users.

New for version 2.2.x

A new cli command has been added that will hopefully ease in debugging issues with this library when it comes to the vast variety of Onvif devices that are out in the wild. Once the cli utility has been installed and authorized per the quick start instructions, the command onvif debug will create a debug folder with a debug.txt and debug.zip that can be added to an issue to help to debug and resolve that issue.

New for version 2.1.x

  • Support for Media2 Onvif operations
  • Support for Recording Onvif operations (experimental)
  • Support for Replay Onvif operations (experimental)
// defaults to `MixedProfile` a special case object that has the fields for both 
// a media1 `Profile` and a media2 `MediaProfile`.
var profiles = await onvif.media.getProfiles();

// determine the media level supported
print(onvif.media.mediaSupportLevel.name);

// alternatively, make an explicit call to the Media1 operation
var profiles1 = await onvif.media.media1.getProfiles();

// or, make an explicit call to the Media2 operation
var profiles2 = await onvif.media.media2.getProfiles();

Onvif specifications and documentation

https://www.onvif.org/profiles/specifications/

Features and bugs

Please file feature requests and bugs with the issue tracker.

Possible unexpected behavior

The helper method move in the PTZ module will fallback to AbsoluteMove if RelativeMove is not supported by the device. The move command is not currently aware of the device bounds , so using the command to change the x position of the device hen the device has already at max x will have no affect. The same would go for the y position and for zoom.

Known Issues

Issue #45

Github Issue #45, when using v2.1.2+13 (and likely earlier) on Windows 11 (and probably 10) the following error will the displayed when attempting to use the Multicast.probe method.

Unhandled exception:
SocketException: Failed to create datagram socket (OS Error: The requested address is not valid in its context., errno = 10049), address = 239.255.255.250, port = 3702

This is due to a bug in the underlying Dart SDK #53477.

With the help of Viper-Bit (who has supplied a c++ workaround that uses Dart FFI) and Add00 (building and testing the c++ code on Windows 11) version 2.1.3 and up of the package now uses Dart FFI to resolve this issue on the Windows platform. For Flutter Windows applications there is a supplied discovery.dll file that must be placed in the assets folder and referenced in the pubspec.yaml, for Windows Dart (cli) apps the discovery.dll defaults to the folder derived as join(Directory.current.path, 'bin', 'discovery.dll'). Alternatively, cli apps on Windows can use the ONVIF_DISCOVERY_DLL environment variable to override the default path for instance:

$env:ONVIF_DISCOVERY_DLL="example/flutter_model/assets/discovery.dll"

dart run bin/onvif.dart probe list-devices

The discovery.dll file can be found in the bin folder of the project on GitHub.

Breaking changes

v3.0.0-dev.0

There have been extensive code revisions to help with the long term maintenance of the package. As part of this a number of method signatures have changed as well as some of the objects in the object model have been renamed. For the most part these changes are in the lower level interfaces within the package and should not affect too many users.

v2.3.0

For this release a number of Common classes where given name changes to better reflect the Onvif spec. Since these classes are used fairly deep in the API it's unlikely that if will affect many users. In addition in the current release these changes are limits to the PTZ module, so if the changes cause issue, it would only be in this section of the code.

v2.1.0

There is probably a number of breaking changes in this version since some method signatures have changed. Since a large portion of the code base was rebuilt from scratch tracking all the changes wasn't a priority. Sorry for any inconvenience.

Contributors

Contributing

Any help from the open-source community is always welcome and needed:

  • Found an issue?
    • Please fill a bug report with details.
  • Need a feature?
    • Open a feature request with use cases.
  • Are you using and liking the project?
    • Promote the project: create an article or post about it
    • Make a donation
  • Do you have a project that uses this package
    • let's cross promote, let me know and I'll add a link to your project
  • Are you a developer?
    • Fix a bug and send a pull request.
    • Implement a new feature.
    • Improve the Unit Tests.
  • Have you already helped in any way?
    • Many thanks from me, the contributors and everybody that uses this project!

If you donate 1 hour of your time, you can contribute a lot, because others will do the same, just be part and start with your 1 hour.

About

This package works with a variety of ONVIF compatible devices allowing for IP Cameras and NVRs (network video recorders) to be integrated into Dart and Flutter applications.

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages

  • Dart 95.3%
  • C++ 2.9%
  • CMake 1.3%
  • C 0.2%
  • Ruby 0.2%
  • Swift 0.1%