easy_onvif 2.1.3+7 easy_onvif: ^2.1.3+7 copied to clipboard
A pure Dart library designed primarily for command line automation of Onvif compatible devices, but can be used anywhere Dart is used.
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.
Table of contents #
- Getting Started
- Lower level requests
- Onvif cli (Onvif at the command prompt)
- Supported Onvif Operations
- Tested Onvif Devices
- New for version 2.1.x
- New for version 2.0.x
- Onvif specifications and documentation
- Features and bugs
- Known Issues
- Breaking changes
- Contributors
- Contributing
Getting Started #
Dependency #
To use this package in your code, first add the dependency to your project:
dependencies:
...
easy_onvif: ^2.1.3+7
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 #
Refer to the tables below for the supported operations.
Through the deviceManagement
operations you can get information about the connected device.
var deviceInfo = await onvif.deviceManagement.getDeviceInformation();
print(deviceInfo.model);
Many operations require you to supply a profileToken
which can be retrieved through media
operations.
var profiles = await onvif.media.getProfiles();
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);
//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);
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>
.
// sample low level request
//
// build a xml fragment for the specific Onvif operation
Transport.builder.element('GetAudioOutputs', nest: () {
Transport.builder.namespace(Xmlns.trt);
});
final requestFragment = Transport.builder.buildFragment();
// 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 envelope = await transport.sendRequest(
onvif.media.media1.uri, transport.securedEnvelope(requestFragment));
print(envelope.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 "$HOME/.onvif/credentials.json")
--log-level [all, debug, info, warning, error, off (default)]
Available commands:
authorize Generate an authentication file for an Onvif device
device-management Device management commands.
media1 Media1 commands.
media2 Media2 commands.
probe Probe/device discovery command.
ptz PTZ 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 1 #
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 2 #
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> |
[ ] |
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 | Known Issue |
---|---|---|
Happytimesoft | IPCamera | limited capabilities |
ONVIF | ENP1A14-IR/25X | commands not implemented¹ |
D-Link Corporation | DCS-6511 | commands not implemented² |
NONE | GX728MF-IR28 | commands not implemented³ |
LOREX | LNB4421SB | testing in progress |
¹ 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
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();
New for version 2.0.x #
Device discovery is finally here. If you're using the command line utility that became available from v1.0.0, you can discover Onvif devices on your network with the command:
onvif probe
Or, in dart code:
final multicastProbe = MulticastProbe();
await multicastProbe.probe();
for (var device in multicastProbe.onvifDevices) {
print(
'${device.name} ${device.location} ${device.hardware} ${device.xAddr}');
}
Onvif specifications and documentation #
https://www.onvif.org/profiles/specifications/
Features and bugs #
Please file feature requests and bugs with the issue tracker.
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 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.
Issue #23 #
Github Issue #23, in Flutter when using v2.0.13+4 and above you may see the following message when performing a dart pub get
:
Because every version of flutter from sdk depends on collection 1.16.0 and xml >=6.2.0 depends on collection ^1.17.0, flutter from sdk is incompatible with xml >=6.2.0.
And because easy_onvif >=2.0.13+11 depends on xml ^6.2.2, flutter from sdk is incompatible with easy_onvif >=2.0.13+11.
So, because cow depends on both flutter from sdk and easy_onvif ^2.0.13+13, version solving failed.
pub get failed (1; So, because cow depends on both flutter from sdk and easy_onvif ^2.0.13+13, version solving failed.)
The fix for this is to add the following section to your pubspec.yaml
:
dependency_overrides:
collection: ^1.17.0
Breaking changes #
v2.1.x #
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.