2014-08-08 00:06:22 +08:00
|
|
|
#!/usr/bin/perl -w
|
|
|
|
#
|
2014-07-15 02:36:18 +08:00
|
|
|
# ==========================================================================
|
|
|
|
#
|
|
|
|
# ZoneMinder ONVIF Control Protocol Module
|
|
|
|
# Copyright (C) Jan M. Hochstein
|
|
|
|
#
|
|
|
|
# This program is free software; you can redistribute it and/or
|
|
|
|
# modify it under the terms of the GNU General Public License
|
|
|
|
# as published by the Free Software Foundation; either version 2
|
|
|
|
# of the License, or (at your option) any later version.
|
|
|
|
#
|
|
|
|
# This program is distributed in the hope that it will be useful,
|
|
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
# GNU General Public License for more details.
|
|
|
|
#
|
|
|
|
# You should have received a copy of the GNU General Public License
|
|
|
|
# along with this program; if not, write to the Free Software
|
|
|
|
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
|
|
#
|
|
|
|
# ==========================================================================
|
|
|
|
#
|
|
|
|
# This module contains the implementation of the ONVIF capability prober
|
|
|
|
#
|
|
|
|
|
2014-07-19 21:42:08 +08:00
|
|
|
require ONVIF::Client;
|
2014-07-15 02:36:18 +08:00
|
|
|
|
|
|
|
require WSDiscovery::Interfaces::WSDiscovery::WSDiscoveryPort;
|
|
|
|
require WSDiscovery::Elements::Types;
|
|
|
|
require WSDiscovery::Elements::Scopes;
|
|
|
|
|
|
|
|
require WSDiscovery::TransportUDP;
|
|
|
|
|
2014-07-19 21:42:08 +08:00
|
|
|
#
|
2014-07-15 02:36:18 +08:00
|
|
|
# ========================================================================
|
|
|
|
# Globals
|
|
|
|
|
2014-07-19 21:42:08 +08:00
|
|
|
my $client;
|
2014-07-15 02:36:18 +08:00
|
|
|
|
|
|
|
# =========================================================================
|
|
|
|
|
|
|
|
sub discover
|
|
|
|
{
|
|
|
|
my $svc_discover = WSDiscovery::Interfaces::WSDiscovery::WSDiscoveryPort->new();
|
|
|
|
|
|
|
|
my $result = $svc_discover->ProbeOp(
|
|
|
|
{ # WSDiscovery::Types::ProbeType
|
|
|
|
Types => { 'dn:NetworkVideoTransmitter', 'tds:Device' }, # QNameListType
|
|
|
|
Scopes => { value => '' },
|
|
|
|
},,
|
|
|
|
);
|
|
|
|
die $result if not $result;
|
|
|
|
# print $result;
|
|
|
|
|
|
|
|
foreach my $xaddr (split ' ', $result->get_ProbeMatch()->get_XAddrs()) {
|
|
|
|
# find IPv4 address
|
2014-07-19 21:42:08 +08:00
|
|
|
if($xaddr =~ m|//[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+/|) {
|
2014-07-15 02:36:18 +08:00
|
|
|
print $xaddr . ", ";
|
|
|
|
last;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
print "(";
|
|
|
|
my $scopes = $result->get_ProbeMatch()->get_Scopes();
|
|
|
|
my $count = 0;
|
|
|
|
foreach my $scope(split ' ', $scopes) {
|
|
|
|
if($scope =~ m|onvif://www\.onvif\.org/(.+)/(.*)|) {
|
|
|
|
my ($attr, $value) = ($1,$2);
|
|
|
|
if( 0 < $count ++) {
|
|
|
|
print ", ";
|
|
|
|
}
|
|
|
|
print $attr . "=\'" . $value . "\'";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
print ")\n";
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
sub profiles
|
|
|
|
{
|
|
|
|
# my $result = $services{media}{ep}->GetVideoSources( { } ,, );
|
|
|
|
# die $result if not $result;
|
|
|
|
# print $result . "\n";
|
|
|
|
|
2014-07-19 21:42:08 +08:00
|
|
|
my $result = $client->get_endpoint('media')->GetProfiles( { } ,, );
|
2014-07-15 02:36:18 +08:00
|
|
|
die $result if not $result;
|
|
|
|
# print $result . "\n";
|
|
|
|
|
|
|
|
my $profiles = $result->get_Profiles();
|
|
|
|
|
|
|
|
foreach my $profile ( @{ $profiles } ) {
|
|
|
|
|
|
|
|
my $token = $profile->attr()->get_token() ;
|
|
|
|
print $token . ", " .
|
|
|
|
$profile->get_Name() . ", " .
|
|
|
|
$profile->get_VideoEncoderConfiguration()->get_Encoding() . ", " .
|
|
|
|
$profile->get_VideoEncoderConfiguration()->get_Resolution()->get_Width() . ", " .
|
|
|
|
$profile->get_VideoEncoderConfiguration()->get_Resolution()->get_Height() . ", " .
|
|
|
|
$profile->get_VideoEncoderConfiguration()->get_RateControl()->get_FrameRateLimit() .
|
|
|
|
", ";
|
|
|
|
|
2014-07-19 21:42:08 +08:00
|
|
|
$result = $client->get_endpoint('media')->GetStreamUri( {
|
2014-07-15 02:36:18 +08:00
|
|
|
StreamSetup => { # ONVIF::Media::Types::StreamSetup
|
|
|
|
Stream => 'RTP_unicast', # StreamType
|
|
|
|
Transport => { # ONVIF::Media::Types::Transport
|
|
|
|
Protocol => 'RTSP', # TransportProtocol
|
|
|
|
},
|
|
|
|
},
|
|
|
|
ProfileToken => $token, # ReferenceToken
|
|
|
|
} ,, );
|
|
|
|
die $result if not $result;
|
|
|
|
# print $result . "\n";
|
|
|
|
|
|
|
|
print $result->get_MediaUri()->get_Uri() .
|
|
|
|
"\n";
|
|
|
|
}
|
|
|
|
|
|
|
|
#
|
|
|
|
# use message parser without schema validation ???
|
|
|
|
#
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
sub move
|
|
|
|
{
|
|
|
|
my ($dir) = @_;
|
|
|
|
|
|
|
|
|
2014-07-19 21:42:08 +08:00
|
|
|
my $result = $client->get_endpoint('ptz')->GetNodes( { } ,, );
|
2014-07-15 02:36:18 +08:00
|
|
|
|
|
|
|
die $result if not $result;
|
|
|
|
print $result . "\n";
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2014-07-19 21:42:08 +08:00
|
|
|
sub metadata
|
|
|
|
{
|
|
|
|
my $result = $client->get_endpoint('media')->GetMetadataConfigurations( { } ,, );
|
|
|
|
die $result if not $result;
|
|
|
|
print $result . "\n";
|
|
|
|
|
2014-08-08 00:06:22 +08:00
|
|
|
$result = $client->get_endpoint('media')->GetVideoAnalyticsConfigurations( { } ,, );
|
2014-07-19 21:42:08 +08:00
|
|
|
die $result if not $result;
|
|
|
|
print $result . "\n";
|
|
|
|
|
|
|
|
$result = $client->get_endpoint('analytics')->GetServiceCapabilities( { } ,, );
|
|
|
|
die $result if not $result;
|
|
|
|
print $result . "\n";
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2014-07-15 02:36:18 +08:00
|
|
|
# ========================================================================
|
|
|
|
# MAIN
|
|
|
|
|
|
|
|
my $action = shift;
|
|
|
|
|
|
|
|
if($action eq "probe") {
|
|
|
|
discover();
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
# all other actions need URI and credentials
|
|
|
|
my $url_svc_device = shift;
|
|
|
|
my $username = shift;
|
|
|
|
my $password = shift;
|
|
|
|
|
2014-07-19 21:42:08 +08:00
|
|
|
$client = ONVIF::Client->new( { 'url_svc_device' => $url_svc_device } );
|
2014-07-15 02:36:18 +08:00
|
|
|
|
2014-07-19 21:42:08 +08:00
|
|
|
$client->set_credentials($username, $password, 1);
|
2014-07-15 02:36:18 +08:00
|
|
|
|
2014-07-19 21:42:08 +08:00
|
|
|
$client->create_services();
|
2014-07-15 02:36:18 +08:00
|
|
|
|
|
|
|
|
|
|
|
if($action eq "profiles") {
|
|
|
|
|
|
|
|
profiles();
|
|
|
|
}
|
|
|
|
elsif($action eq "move") {
|
|
|
|
my $dir = shift;
|
|
|
|
move($dir);
|
|
|
|
}
|
2014-07-19 21:42:08 +08:00
|
|
|
elsif($action eq "metadata") {
|
|
|
|
metadata();
|
|
|
|
}
|
2014-07-15 02:36:18 +08:00
|
|
|
else {
|
|
|
|
print("Error: Unknown command\"$action\"");
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
}
|