ruby_onvif_client 0.0.4 → 0.0.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/ruby_onvif_client/action.rb +5 -1
- data/lib/ruby_onvif_client/media/get_profile.rb +271 -0
- data/lib/ruby_onvif_client/media/get_video_encoder_configurations.rb +82 -0
- data/lib/ruby_onvif_client/media/set_video_encoder_configuration.rb +98 -0
- data/lib/ruby_onvif_client/message.rb +4 -1
- data/lib/ruby_onvif_client/service.rb +4 -2
- data/ruby-onvif-client.gemspec +1 -1
- metadata +4 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 41d830293695b797d378c96f2ab41cec0d89bdd5
|
|
4
|
+
data.tar.gz: af2b4022086bc5c5886029afa8908595b6681b52
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 3e4eefa3f319eca2724e476cac2042f57a1890bbef6322163f38a0b0fff730401c1081de05164010f06ba2be77af360a33b365f485dc1a2bd6d539c9d5b3b8e3
|
|
7
|
+
data.tar.gz: 121c7c082edb76d846e260f504db35e7874516156b9e2631f0013dd9f959926c2cc50ffe0d13dbe4c09d9c097c20d6b6c0e4770aab52137aac2ae4584602cba0
|
|
@@ -2,11 +2,15 @@ require_relative 'message'
|
|
|
2
2
|
|
|
3
3
|
module ONVIF
|
|
4
4
|
class Action
|
|
5
|
-
def initialize client
|
|
5
|
+
def initialize client, username, password
|
|
6
6
|
@client = client
|
|
7
|
+
@username = username
|
|
8
|
+
@password = password
|
|
7
9
|
end
|
|
8
10
|
|
|
9
11
|
def send_message message
|
|
12
|
+
message.username = @username
|
|
13
|
+
message.password = @password
|
|
10
14
|
@client.send message.to_s do |success, result|
|
|
11
15
|
yield success, result
|
|
12
16
|
end
|
|
@@ -0,0 +1,271 @@
|
|
|
1
|
+
require_relative '../action'
|
|
2
|
+
|
|
3
|
+
module ONVIF
|
|
4
|
+
module MediaAction
|
|
5
|
+
class GetProfile < Action
|
|
6
|
+
# p_token 的结构
|
|
7
|
+
# p_token //[ReferenceToken] this command requests a specific profile
|
|
8
|
+
#
|
|
9
|
+
def run p_token, cb
|
|
10
|
+
message = create_media_onvif_message
|
|
11
|
+
message.body = ->(xml) do
|
|
12
|
+
xml.wsdl(:GetProfile) do
|
|
13
|
+
xml.wsdl(:ProfileToken, p_token)
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
send_message message do |success, result|
|
|
17
|
+
if success
|
|
18
|
+
xml_doc = Nokogiri::XML(result[:content])
|
|
19
|
+
root_node = xml_doc.at_xpath('//trt:Profile')
|
|
20
|
+
video_source = root_node.at_xpath("tt:VideoSourceConfiguration")
|
|
21
|
+
audio_source = root_node.at_xpath("tt:AudioSourceConfiguration")
|
|
22
|
+
video_encoder = root_node.at_xpath("tt:VideoEncoderConfiguration")
|
|
23
|
+
audio_encoder = root_node.at_xpath("tt:AudioEncoderConfiguration")
|
|
24
|
+
video_analytics = root_node.at_xpath("tt:VideoAnalyticsConfiguration")
|
|
25
|
+
ptz = root_node.at_xpath("tt:PTZConfiguration")
|
|
26
|
+
metadata = root_node.at_xpath("tt:MetadataConfiguration")
|
|
27
|
+
profile = {
|
|
28
|
+
name: _get_name(root_node),
|
|
29
|
+
token: _get_token(root_node),
|
|
30
|
+
fixed: attribute(root_node, "fixed"),
|
|
31
|
+
extension: ""
|
|
32
|
+
}
|
|
33
|
+
profile["video_source_configuration"] = _get_video_source_configuration(video_source) unless video_source.nil?
|
|
34
|
+
profile["audio_source_configuration"] = _get_audio_source_configuration(audio_source) unless audio_source.nil?
|
|
35
|
+
profile["video_encoder_configuration"] = _get_video_encoder_configuration(video_encoder) unless video_encoder.nil?
|
|
36
|
+
profile["audio_encoder_configuration"] = _get_audio_encoder_configuration(audio_encoder) unless audio_encoder.nil?
|
|
37
|
+
profile["video_analytics_configuration"] = _get_video_analytics_configuration(video_analytics) unless video_analytics.nil?
|
|
38
|
+
profile["ptz_configuration"] = _get_ptz_configuration(ptz) unless ptz.nil?
|
|
39
|
+
profile["metadata_configuration"] = _get_metadata_configuration(metadata) unless metadata.nil?
|
|
40
|
+
callback cb, success, profile
|
|
41
|
+
else
|
|
42
|
+
callback cb, success, result
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def _get_node parent_node, node_name
|
|
48
|
+
parent_node.at_xpath(node_name)
|
|
49
|
+
end
|
|
50
|
+
def _get_name parent_node
|
|
51
|
+
value(parent_node, "tt:Name")
|
|
52
|
+
end
|
|
53
|
+
def _get_use_count parent_node
|
|
54
|
+
value(parent_node, "tt:UseCount")
|
|
55
|
+
end
|
|
56
|
+
def _get_token parent_node
|
|
57
|
+
attribute(parent_node, "token")
|
|
58
|
+
end
|
|
59
|
+
def _get_min_max xml_doc, parent_name
|
|
60
|
+
this_node = xml_doc
|
|
61
|
+
unless parent_name.nil?
|
|
62
|
+
this_node = xml_doc.at_xpath(parent_name)
|
|
63
|
+
end
|
|
64
|
+
return {
|
|
65
|
+
min: value(this_node, "tt:Min"),
|
|
66
|
+
max: value(this_node, "tt:Max")
|
|
67
|
+
}
|
|
68
|
+
end
|
|
69
|
+
def _get_public_sector parent_node
|
|
70
|
+
{
|
|
71
|
+
name: _get_name(parent_node),
|
|
72
|
+
token: _get_token(parent_node),
|
|
73
|
+
use_count: _get_use_count(parent_node)
|
|
74
|
+
}
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
def _get_video_source_configuration parent_node
|
|
78
|
+
configuration = _get_public_sector(parent_node)
|
|
79
|
+
configuration["source_token"] = value(parent_node, "tt:SourceToken")
|
|
80
|
+
bounds = parent_node.at_xpath("tt:Bounds")
|
|
81
|
+
configuration["bounds"] = {
|
|
82
|
+
x: attribute(bounds, "x"),
|
|
83
|
+
y: attribute(bounds, "y"),
|
|
84
|
+
width: attribute(bounds, "width"),
|
|
85
|
+
height: attribute(bounds, "height")
|
|
86
|
+
}
|
|
87
|
+
return configuration
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
def _get_audio_source_configuration parent_node
|
|
91
|
+
configuration = _get_public_sector(parent_node)
|
|
92
|
+
configuration["source_token"] = value(parent_node, "tt:SourceToken")
|
|
93
|
+
return configuration
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
def _get_video_encoder_configuration parent_node
|
|
97
|
+
configuration = _get_public_sector(parent_node)
|
|
98
|
+
configuration["encoding"] = value(parent_node, "tt:Encoding")
|
|
99
|
+
configuration["resolution"] = {
|
|
100
|
+
width: value(_get_node(parent_node, "tt:Resolution"), "tt:Width"),
|
|
101
|
+
height: value(_get_node(parent_node, "tt:Resolution"), "tt:Height")
|
|
102
|
+
}
|
|
103
|
+
configuration["quality"] = value(parent_node, "tt:Quality")
|
|
104
|
+
configuration["rate_control"] = {
|
|
105
|
+
frame_rate_limit: value(_get_node(parent_node, "tt:RateControl"), "tt:FrameRateLimit"),
|
|
106
|
+
encoding_interval: value(_get_node(parent_node, "tt:RateControl"), "tt:EncodingInterval"),
|
|
107
|
+
bitrate_limit: value(_get_node(parent_node, "tt:RateControl"), "tt:BitrateLimit")
|
|
108
|
+
}
|
|
109
|
+
unless parent_node.at_xpath('//tt:MPEG4').nil?
|
|
110
|
+
configuration["MPEG4"] = {
|
|
111
|
+
gov_length: value(_get_node(parent_node, "tt:MPEG4"), "tt:GovLength"),
|
|
112
|
+
mpeg4_profile: value(_get_node(parent_node, "tt:MPEG4"), "tt:Mpeg4Profile")
|
|
113
|
+
}
|
|
114
|
+
end
|
|
115
|
+
unless parent_node.at_xpath('//tt:H264').nil?
|
|
116
|
+
configuration["H264"] = {
|
|
117
|
+
gov_length: value(_get_node(parent_node, "tt:H264"), "tt:GovLength"),
|
|
118
|
+
h264_profile: value(_get_node(parent_node, "tt:H264"), "tt:H264Profile")
|
|
119
|
+
}
|
|
120
|
+
end
|
|
121
|
+
configuration["multicast"] = _get_multicast(parent_node)
|
|
122
|
+
configuration["session_timeout"] = value(parent_node, "tt:SessionTimeout")
|
|
123
|
+
return configuration
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
def _get_audio_encoder_configuration parent_node
|
|
127
|
+
configuration = _get_public_sector(parent_node)
|
|
128
|
+
configuration["encoding"] = value(parent_node, "tt:Encoding")
|
|
129
|
+
configuration["bitrate"] = value(parent_node, "tt:Bitrate")
|
|
130
|
+
configuration["sample_rate"] = value(parent_node, "tt:SampleRate")
|
|
131
|
+
configuration["multicast"] = _get_multicast(parent_node)
|
|
132
|
+
configuration["session_timeout"] = value(parent_node, "tt:SessionTimeout")
|
|
133
|
+
return configuration
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
def _get_video_analytics_configuration parent_node
|
|
137
|
+
configuration = _get_public_sector(parent_node)
|
|
138
|
+
analytics_module = []; rule = []
|
|
139
|
+
parent_node.at_xpath("tt:AnalyticsEngineConfiguration//tt:AnalyticsModule").each do |node|
|
|
140
|
+
analytics_module << {
|
|
141
|
+
name: attribute(node, "Name"),
|
|
142
|
+
type: attribute(node, "Type"),
|
|
143
|
+
parameters: _get_parameters(node)
|
|
144
|
+
}
|
|
145
|
+
end
|
|
146
|
+
parent_node.at_xpath("tt:AnalyticsEngineConfiguration//tt:RuleEngineConfiguration").each do |node|
|
|
147
|
+
rule << {
|
|
148
|
+
name: attribute(node, "Name"),
|
|
149
|
+
type: attribute(node, "Type"),
|
|
150
|
+
parameters: _get_parameters(node)
|
|
151
|
+
}
|
|
152
|
+
end
|
|
153
|
+
configuration["analytics_engine_configuration"] = {
|
|
154
|
+
analytics_module: analytics_module,
|
|
155
|
+
extension: ""
|
|
156
|
+
}
|
|
157
|
+
configuration["rule_engine_configuration"] = {
|
|
158
|
+
rule: rule,
|
|
159
|
+
extension: ""
|
|
160
|
+
}
|
|
161
|
+
return configuration
|
|
162
|
+
end
|
|
163
|
+
|
|
164
|
+
def _get_ptz_configuration parent_node
|
|
165
|
+
configuration = _get_public_sector(parent_node)
|
|
166
|
+
configuration["node_token"] = value(parent_node, "tt:NodeToken")
|
|
167
|
+
configuration["default_absolute_pant_tilt_position_space"] = value(parent_node, "tt:DefaultAbsolutePantTiltPositionSpace")
|
|
168
|
+
configuration["default_absolute_zoom_position_space"] = value(parent_node, "tt:DefaultAbsoluteZoomPositionSpace")
|
|
169
|
+
configuration["default_relative_pan_tilt_translation_space"] = value(parent_node, "tt:DefaultRelativePanTiltTranslationSpace")
|
|
170
|
+
configuration["default_relative_zoom_translation_space"] = value(parent_node, "tt:DefaultRelativeZoomTranslationSpace")
|
|
171
|
+
configuration["default_continuous_pan_tilt_velocity_space"] = value(parent_node, "tt:DefaultContinuousPanTiltVelocitySpace")
|
|
172
|
+
configuration["default_continuous_zoom_velocity_space"] = value(parent_node, "tt:DefaultContinuousZoomVelocitySpace")
|
|
173
|
+
pan_tilt = _get_node(parent_node,"//tt:DefaultPTZSpeed//tt:PanTilt")
|
|
174
|
+
zoom = _get_node(parent_node,"//tt:DefaultPTZSpeed//tt:Zoom")
|
|
175
|
+
configuration["default_ptz_speed"] = {
|
|
176
|
+
pan_tilt:{
|
|
177
|
+
x: attribute(pan_tilt, "x"),
|
|
178
|
+
y: attribute(pan_tilt, "y"),
|
|
179
|
+
space: attribute(pan_tilt, "space")
|
|
180
|
+
},
|
|
181
|
+
zoom: {
|
|
182
|
+
x: attribute(zoom, "x"),
|
|
183
|
+
space: attribute(zoom, "space")
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
configuration["fefault_ptz_timeout"] = value(parent_node, "tt:DefaultPTZTimeout")
|
|
187
|
+
configuration["pan_tilt_limits"] = {
|
|
188
|
+
range: {
|
|
189
|
+
uri: value(_get_node(parent_node, "tt:PanTiltLimits//tt:Range"), "tt:URI"),
|
|
190
|
+
x_range: _get_min_max(_get_node(parent_node,"tt:PanTiltLimits//tt:Range"), "tt:XRange"),
|
|
191
|
+
y_range: _get_min_max(_get_node(parent_node,"tt:PanTiltLimits//tt:Range"), "tt:YRange")
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
configuration["zoom_limits"] = {
|
|
195
|
+
range: {
|
|
196
|
+
uri: value(_get_node(parent_node, "tt:PanTiltLimits//tt:Range"), "tt:URI"),
|
|
197
|
+
x_range: _get_min_max(_get_node(parent_node,"tt:PanTiltLimits//tt:Range"), "tt:XRange"),
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
configuration["extension"] = ""
|
|
201
|
+
return configuration
|
|
202
|
+
end
|
|
203
|
+
|
|
204
|
+
def _get_metadata_configuration parent_node
|
|
205
|
+
configuration = _get_public_sector(parent_node)
|
|
206
|
+
configuration["ptz_status"] = {
|
|
207
|
+
status: value(_get_node(parent_node, "tt:PTZStatus"), "tt:Status"),
|
|
208
|
+
sosition: value(_get_node(parent_node, "tt:PTZStatus"), "tt:Position")
|
|
209
|
+
}
|
|
210
|
+
configuration["events"] = {
|
|
211
|
+
filter: value(_get_node(parent_node, "tt:Events"), "tt:Filter"),
|
|
212
|
+
subscription_policy: value(_get_node(parent_node, "tt:Events"), "tt:SubscriptionPolicy")
|
|
213
|
+
}
|
|
214
|
+
configuration["analytics"] = value(parent_node, "tt:Analytics")
|
|
215
|
+
configuration["multicast"] = _get_multicast(parent_node)
|
|
216
|
+
configuration["session_timeout"] = value(parent_node, "tt:SessionTimeout")
|
|
217
|
+
unless parent_node.at_xpath("tt:AnalyticsEngineConfiguration//tt:AnalyticsModule").nil?
|
|
218
|
+
analytics_module = []
|
|
219
|
+
parent_node.at_xpath("tt:AnalyticsEngineConfiguration//tt:AnalyticsModule").each do |node|
|
|
220
|
+
analytics_module << {
|
|
221
|
+
name: attribute(node, "Name"),
|
|
222
|
+
type: attribute(node, "Type"),
|
|
223
|
+
parameters: _get_parameters(node)
|
|
224
|
+
}
|
|
225
|
+
end
|
|
226
|
+
configuration["analytics_engine_configuration"] = {
|
|
227
|
+
analytics_module: analytics_module,
|
|
228
|
+
extension: ""
|
|
229
|
+
}
|
|
230
|
+
end
|
|
231
|
+
configuration["extension"] = ""
|
|
232
|
+
return configuration
|
|
233
|
+
end
|
|
234
|
+
|
|
235
|
+
def _get_multicast parent_node
|
|
236
|
+
{
|
|
237
|
+
address: {
|
|
238
|
+
type: value(_get_node(parent_node, "//tt:Multicast//tt:Address"), '//tt:Type'),
|
|
239
|
+
ipv4_address: value(_get_node(parent_node, "//tt:Multicast//tt:Address"), '//tt:IPv4Address'),
|
|
240
|
+
ipv6_address: value(_get_node(parent_node, "//tt:Multicast//tt:Address"), '//tt:IPv6Address')
|
|
241
|
+
},
|
|
242
|
+
port: value(_get_node(parent_node, "//tt:Multicast"), "tt:Port"),
|
|
243
|
+
ttl: value(_get_node(parent_node, "//tt:Multicast"), "tt:TTL"),
|
|
244
|
+
auto_start: value(_get_node(parent_node, "//tt:Multicast"), "tt:AutoStart")
|
|
245
|
+
}
|
|
246
|
+
end
|
|
247
|
+
|
|
248
|
+
def _get_parameters parent_node
|
|
249
|
+
simple_item = []
|
|
250
|
+
element_item = []
|
|
251
|
+
parent_node.at_xpath("tt:SimpleItem").each do |node|
|
|
252
|
+
simple_item << {
|
|
253
|
+
name: attribute(node, "Name"),
|
|
254
|
+
value: attribute(node, "Value")
|
|
255
|
+
}
|
|
256
|
+
end
|
|
257
|
+
parent_node.at_xpath("tt:ElementItem").each do |node|
|
|
258
|
+
element_item << {
|
|
259
|
+
xsd_any: value(node, "tt:xsd:any"),
|
|
260
|
+
name: attribute(node, "Name")
|
|
261
|
+
}
|
|
262
|
+
end
|
|
263
|
+
return {
|
|
264
|
+
simple_item: simple_item,
|
|
265
|
+
element_item: element_item,
|
|
266
|
+
extension: ""
|
|
267
|
+
}
|
|
268
|
+
end
|
|
269
|
+
end
|
|
270
|
+
end
|
|
271
|
+
end
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
require_relative '../action'
|
|
2
|
+
|
|
3
|
+
module ONVIF
|
|
4
|
+
module MediaAction
|
|
5
|
+
class GetVideoEncoderConfigurations < Action
|
|
6
|
+
def run cb
|
|
7
|
+
message = Message.new
|
|
8
|
+
message.body = ->(xml) do
|
|
9
|
+
xml.wsdl(:GetVideoEncoderConfigurations)
|
|
10
|
+
end
|
|
11
|
+
send_message message do |success, result|
|
|
12
|
+
if success
|
|
13
|
+
xml_doc = Nokogiri::XML(result[:content])
|
|
14
|
+
configuration = []
|
|
15
|
+
xml_doc.xpath('//trt:Configurations').each do |root_node|
|
|
16
|
+
success_result = {
|
|
17
|
+
name: value(root_node, "tt:Name"),
|
|
18
|
+
token: attribute(root_node, "token"),
|
|
19
|
+
use_count: value(root_node, "tt:UseCount"),
|
|
20
|
+
encoding: value(root_node, "tt:Encoding"),
|
|
21
|
+
resolution: {
|
|
22
|
+
width: value(_get_node(root_node, "tt:Resolution"), "tt:Width"),
|
|
23
|
+
height: value(_get_node(root_node, "tt:Resolution"), "tt:Height")
|
|
24
|
+
},
|
|
25
|
+
quality: value(root_node, "tt:Quality"),
|
|
26
|
+
rate_control: {
|
|
27
|
+
frame_rate_limit: value(_get_node(root_node, "tt:RateControl"), "tt:FrameRateLimit"),
|
|
28
|
+
encoding_interval: value(_get_node(root_node, "tt:RateControl"), "tt:EncodingInterval"),
|
|
29
|
+
bitrate_limit: value(_get_node(root_node, "tt:RateControl"), "tt:BitrateLimit")
|
|
30
|
+
},
|
|
31
|
+
multicast: _get_multicast(root_node),
|
|
32
|
+
session_timeout: value(root_node, "tt:SessionTimeout")
|
|
33
|
+
}
|
|
34
|
+
unless root_node.at_xpath('//tt:MPEG4').nil?
|
|
35
|
+
success_result["MPEG4"] = {
|
|
36
|
+
gov_length: value(_get_node(root_node, "tt:MPEG4"), "tt:GovLength"),
|
|
37
|
+
mpeg4_profile: value(_get_node(root_node, "tt:MPEG4"), "tt:Mpeg4Profile")
|
|
38
|
+
}
|
|
39
|
+
end
|
|
40
|
+
unless root_node.at_xpath('//tt:H264').nil?
|
|
41
|
+
success_result["H264"] = {
|
|
42
|
+
gov_length: value(_get_node(root_node, "tt:H264"), "tt:GovLength"),
|
|
43
|
+
h264_profile: value(_get_node(root_node, "tt:H264"), "tt:H264Profile")
|
|
44
|
+
}
|
|
45
|
+
end
|
|
46
|
+
configuration << success_result
|
|
47
|
+
end
|
|
48
|
+
callback cb, success, configuration
|
|
49
|
+
else
|
|
50
|
+
callback cb, success, result
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def _get_node parent_node, node_name
|
|
56
|
+
parent_node.at_xpath(node_name)
|
|
57
|
+
end
|
|
58
|
+
def _get_min_max xml_doc, parent_name
|
|
59
|
+
this_node = xml_doc
|
|
60
|
+
unless parent_name.nil?
|
|
61
|
+
this_node = xml_doc.at_xpath(parent_name)
|
|
62
|
+
end
|
|
63
|
+
return {
|
|
64
|
+
min: value(this_node, "tt:Min"),
|
|
65
|
+
max: value(this_node, "tt:Max")
|
|
66
|
+
}
|
|
67
|
+
end
|
|
68
|
+
def _get_multicast parent_node
|
|
69
|
+
{
|
|
70
|
+
address: {
|
|
71
|
+
type: value(_get_node(parent_node, "//tt:Multicast//tt:Address"), '//tt:Type'),
|
|
72
|
+
ipv4_address: value(_get_node(parent_node, "//tt:Multicast//tt:Address"), '//tt:IPv4Address'),
|
|
73
|
+
ipv6_address: value(_get_node(parent_node, "//tt:Multicast//tt:Address"), '//tt:IPv6Address')
|
|
74
|
+
},
|
|
75
|
+
port: value(_get_node(parent_node, "//tt:Multicast"), "tt:Port"),
|
|
76
|
+
ttl: value(_get_node(parent_node, "//tt:Multicast"), "tt:TTL"),
|
|
77
|
+
auto_start: value(_get_node(parent_node, "//tt:Multicast"), "tt:AutoStart")
|
|
78
|
+
}
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
end
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
require_relative '../action'
|
|
2
|
+
|
|
3
|
+
module ONVIF
|
|
4
|
+
module MediaAction
|
|
5
|
+
class SetVideoEncoderConfiguration < Action
|
|
6
|
+
# configuration 的结构
|
|
7
|
+
# {
|
|
8
|
+
# configuration: {
|
|
9
|
+
# token: 'xxxxx', //[ReferenceToken] Token that uniquely refernces this configuration. Length up to 64 characters.
|
|
10
|
+
# name: 'xxxxxx', //User readable name. Length up to 64 characters.
|
|
11
|
+
# use_count: 1, // [int]
|
|
12
|
+
# encoding: 'H264', // 'JPEG', 'MPEG4', 'H264'
|
|
13
|
+
# resolution: {
|
|
14
|
+
# width: 1280, //Number of the columns of the Video image.
|
|
15
|
+
# height: 720, //Number of the columns of the Video image.
|
|
16
|
+
# },
|
|
17
|
+
# quality: 100,// [float]
|
|
18
|
+
# rate_control: {
|
|
19
|
+
# frame_rate_limit: 25,//[int]
|
|
20
|
+
# encoding_interval: 25,//[int]
|
|
21
|
+
# bitrate_limit: 4096 //[int]
|
|
22
|
+
# },
|
|
23
|
+
# mpeg4: {// 可有可无
|
|
24
|
+
# gov_length: 30, // [int]
|
|
25
|
+
# mpeg4_profile: 'SP' //'SP', 'ASP'
|
|
26
|
+
# },
|
|
27
|
+
# h264: { //可有可无
|
|
28
|
+
# gov_length: 30, //[int]
|
|
29
|
+
# h264_profile: 'Main' // 'Baseline', 'Main', 'Extended', 'High'
|
|
30
|
+
# },
|
|
31
|
+
# multicast: {
|
|
32
|
+
# address: {
|
|
33
|
+
# type: 'IPv4', //'IPv4', 'IPv6'
|
|
34
|
+
# ipv4_address: '239.255.0.0', //[IPv4Address]
|
|
35
|
+
# ipv6_address: '0000:0000:0000:0000:0000:0000:0000:0000' //[IPv6Address]
|
|
36
|
+
# },
|
|
37
|
+
# port: 1024,//[int]
|
|
38
|
+
# ttl: 1,//[int]
|
|
39
|
+
# auto_start: false //[boolean]
|
|
40
|
+
# },
|
|
41
|
+
# session_timeout: 'PT0H1M26.400S', //[duration] The rtsp session timeout for the related video stream
|
|
42
|
+
# },
|
|
43
|
+
# force_persistence: false // [boolean] The ForcePersistence element is obsolete and should always be assumed to be true.
|
|
44
|
+
# }
|
|
45
|
+
def run configuration, cb
|
|
46
|
+
message = create_media_onvif_message namespaces: {:'xmlns:sch' => 'http://www.onvif.org/ver10/schema'}
|
|
47
|
+
message.body = ->(xml) do
|
|
48
|
+
xml.wsdl(:SetVideoEncoderConfiguration) do
|
|
49
|
+
xml.wsdl :Configuration, {"token" => configuration["configuration"]["token"]}
|
|
50
|
+
xml.wsdl(:Configuration) do
|
|
51
|
+
xml.sch :Name, configuration["configuration"]["name"]
|
|
52
|
+
xml.sch :UseCount, configuration["configuration"]["use_count"]
|
|
53
|
+
xml.sch :Encoding, configuration["configuration"]["encoding"]
|
|
54
|
+
xml.sch(:Resolution) do
|
|
55
|
+
xml.sch :Width, configuration["configuration"]["resolution"]["width"]
|
|
56
|
+
xml.sch :Height, configuration["configuration"]["resolution"]["height"]
|
|
57
|
+
end
|
|
58
|
+
xml.sch :Quality,configuration["configuration"]["quality"]
|
|
59
|
+
xml.sch(:RateControl) do
|
|
60
|
+
xml.sch :FrameRateLimit, configuration["configuration"]["rate_control"]["frame_rate_limit"]
|
|
61
|
+
xml.sch :EncodingInterval, configuration["configuration"]["rate_control"]["encoding_interval"]
|
|
62
|
+
xml.sch :BitrateLimit, configuration["configuration"]["rate_control"]["bitrate_limit"]
|
|
63
|
+
end
|
|
64
|
+
unless configuration["configuration"]["mpeg4"].nil?
|
|
65
|
+
xml.sch(:MPEG4) do
|
|
66
|
+
xml.sch :GovLength, configuration["configuration"]["mpeg4"]["gov_length"]
|
|
67
|
+
xml.sch :Mpeg4Profile, configuration["configuration"]["mpeg4"]["mpeg4_profile"]
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
unless configuration["configuration"]["h264"].nil?
|
|
71
|
+
xml.sch(:H264) do
|
|
72
|
+
xml.sch :GovLength, configuration["configuration"]["h264"]["gov_length"]
|
|
73
|
+
xml.sch :H264Profile, configuration["configuration"]["h264"]["h264_profile"]
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
xml.sch(:Multicast) do
|
|
77
|
+
xml.sch(:Address) do
|
|
78
|
+
xml.sch :Type, configuration["configuration"]["multicast"]["address"]["type"]
|
|
79
|
+
xml.sch :IPv4Address, configuration["configuration"]["multicast"]["address"]["ipv4_address"]
|
|
80
|
+
xml.sch :IPv6Address, configuration["configuration"]["multicast"]["address"]["ipv6_address"]
|
|
81
|
+
end
|
|
82
|
+
xml.sch :Port, configuration["configuration"]["multicast"]["port"]
|
|
83
|
+
xml.sch :TTL, configuration["configuration"]["multicast"]["ttl"]
|
|
84
|
+
xml.sch :AutoStart, configuration["configuration"]["multicast"]["auto_start"]
|
|
85
|
+
end
|
|
86
|
+
xml.sch :SessionTimeout, configuration["configuration"]["session_timeout"]
|
|
87
|
+
end
|
|
88
|
+
xml.wsdl :ForcePersistence, configuration["force_persistence"]
|
|
89
|
+
end
|
|
90
|
+
end
|
|
91
|
+
send_message message do |success, result|
|
|
92
|
+
#????
|
|
93
|
+
callback cb, success, result
|
|
94
|
+
end
|
|
95
|
+
end
|
|
96
|
+
end
|
|
97
|
+
end
|
|
98
|
+
end
|
|
@@ -5,6 +5,7 @@ require "akami"
|
|
|
5
5
|
module ONVIF
|
|
6
6
|
class Message
|
|
7
7
|
attr_writer :body
|
|
8
|
+
attr_accessor :username, :password
|
|
8
9
|
|
|
9
10
|
def initialize options = {}
|
|
10
11
|
@options = {
|
|
@@ -17,11 +18,13 @@ module ONVIF
|
|
|
17
18
|
:'xmlns:soap' => "http://www.w3.org/2003/05/soap-envelope",
|
|
18
19
|
:'xmlns:wsdl' => "http://www.onvif.org/ver10/device/wsdl"
|
|
19
20
|
}.merge(@options[:namespaces])
|
|
21
|
+
self.username = @options[:username]
|
|
22
|
+
self.password = @options[:password]
|
|
20
23
|
end
|
|
21
24
|
|
|
22
25
|
def header
|
|
23
26
|
wsse = Akami.wsse
|
|
24
|
-
wsse.credentials(
|
|
27
|
+
wsse.credentials(username, password)
|
|
25
28
|
wsse.created_at = Time.now
|
|
26
29
|
wsse.to_xml
|
|
27
30
|
end
|
|
@@ -3,10 +3,12 @@ require "active_support/all"
|
|
|
3
3
|
|
|
4
4
|
module ONVIF
|
|
5
5
|
class Service
|
|
6
|
-
def initialize address
|
|
6
|
+
def initialize address, username = 'admin', password = 'admin'
|
|
7
7
|
@client = ONVIF::Client.new(
|
|
8
8
|
address: address
|
|
9
9
|
)
|
|
10
|
+
@username = username
|
|
11
|
+
@password = password
|
|
10
12
|
end
|
|
11
13
|
|
|
12
14
|
def method_missing(m, *args, &blcok)
|
|
@@ -14,7 +16,7 @@ module ONVIF
|
|
|
14
16
|
unless action_class.nil?
|
|
15
17
|
self.class.class_exec do
|
|
16
18
|
define_method m do |*r|
|
|
17
|
-
action_class.new(@client).run(*r)
|
|
19
|
+
action_class.new(@client, @username, @password).run(*r)
|
|
18
20
|
end
|
|
19
21
|
end
|
|
20
22
|
self.send m, *args
|
data/ruby-onvif-client.gemspec
CHANGED
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: ruby_onvif_client
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.0.
|
|
4
|
+
version: 0.0.5
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- jimxl
|
|
@@ -93,10 +93,13 @@ files:
|
|
|
93
93
|
- lib/ruby_onvif_client/media/get_audio_encoder_configurations.rb
|
|
94
94
|
- lib/ruby_onvif_client/media/get_audio_encoder_configuration_options.rb
|
|
95
95
|
- lib/ruby_onvif_client/media/get_audio_encoder_configuration.rb
|
|
96
|
+
- lib/ruby_onvif_client/media/get_profile.rb
|
|
96
97
|
- lib/ruby_onvif_client/media/get_profiles.rb
|
|
97
98
|
- lib/ruby_onvif_client/media/get_video_source_configuration.rb
|
|
98
99
|
- lib/ruby_onvif_client/media/get_video_source_configurations.rb
|
|
99
100
|
- lib/ruby_onvif_client/media/get_audio_source_configurations.rb
|
|
101
|
+
- lib/ruby_onvif_client/media/set_video_encoder_configuration.rb
|
|
102
|
+
- lib/ruby_onvif_client/media/get_video_encoder_configurations.rb
|
|
100
103
|
- lib/ruby_onvif_client/media/get_stream_uri.rb
|
|
101
104
|
- lib/ruby_onvif_client/action.rb
|
|
102
105
|
- lib/ruby_onvif_client/device_discovery.rb
|