sony_camera_remote_api 0.1.4 → 0.2.0
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/core_ext/hash_patch.rb +8 -3
- data/lib/sony_camera_remote_api/camera_api.rb +66 -28
- data/lib/sony_camera_remote_api/camera_api_group.rb +102 -19
- data/lib/sony_camera_remote_api/client/main.rb +8 -7
- data/lib/sony_camera_remote_api/client/shelf.rb +1 -1
- data/lib/sony_camera_remote_api/logging.rb +10 -1
- data/lib/sony_camera_remote_api/raw_api.rb +5 -5
- data/lib/sony_camera_remote_api/shelf.rb +29 -2
- data/lib/sony_camera_remote_api/version.rb +2 -1
- data/lib/sony_camera_remote_api.rb +197 -109
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1673c9a0e55968b5691e720ba4580f10fdc89301
|
4
|
+
data.tar.gz: b7dfb169b64c3625e80d5a480a8d50d3aa6a5af2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 41eef398296c1351f7c792c9ca67c38a7102f831790f97d381e8db2ce15deb252b9b335de830f91c3d922c54822120b56fad94868afff9b62765eac6a42a1107
|
7
|
+
data.tar.gz: 90bb27d0d5cad30a6d3999f640efa1caf4f47fc4f96a5c105cf35b363687ba844962b805765b5dceb74e07167690b0a22271f318e10590e6326f69ad7837b942
|
data/lib/core_ext/hash_patch.rb
CHANGED
@@ -1,13 +1,18 @@
|
|
1
|
+
# Hash extension for handling API response.
|
1
2
|
class Hash
|
2
|
-
# Get result element
|
3
|
+
# Get result element.
|
3
4
|
def result
|
4
5
|
self['result']
|
5
6
|
end
|
6
|
-
# Get
|
7
|
+
# Get results element.
|
8
|
+
def results
|
9
|
+
self['results']
|
10
|
+
end
|
11
|
+
# Get id element.
|
7
12
|
def id
|
8
13
|
self['id']
|
9
14
|
end
|
10
|
-
# Get error element
|
15
|
+
# Get error element.
|
11
16
|
def error
|
12
17
|
self['error']
|
13
18
|
end
|
@@ -14,11 +14,12 @@ module SonyCameraRemoteAPI
|
|
14
14
|
# Default timeout for waiting camera parameter changes
|
15
15
|
DEFAULT_PARAM_CHANGE_TIMEOUT = 15
|
16
16
|
|
17
|
-
def_delegators :@raw_api_manager, :apis, :support?
|
18
17
|
def_delegators :@api_group_manager, :get_parameter, :get_parameter!,
|
19
18
|
:set_parameter, :set_parameter!,
|
20
|
-
:get_current, :get_current
|
21
|
-
|
19
|
+
:get_current, :get_current!,
|
20
|
+
:parameters
|
21
|
+
def_delegators :@raw_api_manager, :apis
|
22
|
+
|
22
23
|
|
23
24
|
|
24
25
|
# Create CameraAPIManager object.
|
@@ -31,28 +32,6 @@ module SonyCameraRemoteAPI
|
|
31
32
|
end
|
32
33
|
|
33
34
|
|
34
|
-
# Call camera APIs with checking if it is available by 'getAvailableApiList'.
|
35
|
-
# If not available, wait a minute until the called API turns to be available.
|
36
|
-
# @param [String] service_type
|
37
|
-
# @param [String] method
|
38
|
-
# @param [Array,String] params
|
39
|
-
# @param [Fixnum] id
|
40
|
-
# @param [String] version
|
41
|
-
# @param [Fixnum] timeout Timeout in seconds for waiting until the API is available
|
42
|
-
def call_api_safe(service_type, method, params, id, version, timeout = DEFAULT_API_CALL_TIMEOUT, **args)
|
43
|
-
unless getAvailableApiList['result'][0].include? method
|
44
|
-
log.error "Method '#{method}' is not available now! waiting..."
|
45
|
-
begin
|
46
|
-
wait_event(timeout: timeout) { |res| res[0]['names'].include? method }
|
47
|
-
rescue EventTimeoutError => e
|
48
|
-
raise APINotAvailable.new, "Method '#{method}' is not available now!"
|
49
|
-
end
|
50
|
-
log.info "Method '#{method}' has become available."
|
51
|
-
end
|
52
|
-
@raw_api_manager.call_api(service_type, method, params, id, version)
|
53
|
-
end
|
54
|
-
|
55
|
-
|
56
35
|
# getEvent API.
|
57
36
|
# Long polling flag is set true as default.
|
58
37
|
# @param [Array,String] params
|
@@ -92,6 +71,7 @@ module SonyCameraRemoteAPI
|
|
92
71
|
# * polling = true : Always use long polling in getEvent call
|
93
72
|
# * polling = false : Never use long polling in getEvent call
|
94
73
|
# @raise EventTimeoutError
|
74
|
+
# @todo add example
|
95
75
|
def wait_event(timeout: DEFAULT_PARAM_CHANGE_TIMEOUT, polling: nil, &block)
|
96
76
|
start_time = Time.now if timeout
|
97
77
|
# Long-polling is disabled only at the first call
|
@@ -117,13 +97,33 @@ module SonyCameraRemoteAPI
|
|
117
97
|
|
118
98
|
|
119
99
|
# Ghost method, which handles almost API calls.
|
120
|
-
#
|
100
|
+
# You can call an API as a method with the same name.
|
101
|
+
# We don't have to specify service_type and version for almost APIs.
|
102
|
+
# But some APIs have multiple service types and versions, so that we have to specify one service type or version.
|
103
|
+
# When '!' is appended to the end of the method name, it does not raise Exception even if any error occurred.
|
121
104
|
# @param [String] method
|
122
105
|
# @param [Array,String] params
|
123
106
|
# @param [String] service_type
|
124
107
|
# @param [Fixnum] id
|
125
108
|
# @param [String] version
|
126
109
|
# @param [Fixnum] timeout Timeout in seconds for waiting until the API is available
|
110
|
+
# @example
|
111
|
+
# # Initialize
|
112
|
+
# cam = SonyCameraRemoteAPI::Camera.new
|
113
|
+
# cam.change_function_to_shoot 'still', 'Single'
|
114
|
+
#
|
115
|
+
# # Call getMethodTypes API with parameter: ['1.0'], service type: 'camera' and id: 1.
|
116
|
+
# response = cam.getMethodTypes ['1.0'], service_type: 'camera', id: 1
|
117
|
+
# puts response.id
|
118
|
+
# response.results.each do |r|
|
119
|
+
# puts '----'
|
120
|
+
# puts r
|
121
|
+
# end
|
122
|
+
#
|
123
|
+
# # Call setCurrentTime API if supported.
|
124
|
+
# cam.setCurrentTime! [{'dateTime' => Time.now.utc.iso8601,
|
125
|
+
# 'timeZoneOffsetMinute' => 540,
|
126
|
+
# 'dstOffsetMinute' => 0}]
|
127
127
|
def method_missing(method, params = [], *args, **opts)
|
128
128
|
ignore_error = true if method.to_s.end_with? '!'
|
129
129
|
method = method.to_s.delete('!').to_sym
|
@@ -141,7 +141,7 @@ module SonyCameraRemoteAPI
|
|
141
141
|
else
|
142
142
|
response = @raw_api_manager.call_api(service, name, params, id, version)
|
143
143
|
end
|
144
|
-
rescue APINotSupported, APINotAvailable, IllegalArgument, HTTPClient::BadResponseError => e
|
144
|
+
rescue APIForbidden, APINotSupported, APINotAvailable, IllegalArgument, HTTPClient::BadResponseError => e
|
145
145
|
if ignore_error
|
146
146
|
return nil
|
147
147
|
else
|
@@ -153,8 +153,47 @@ module SonyCameraRemoteAPI
|
|
153
153
|
end
|
154
154
|
|
155
155
|
|
156
|
+
# Get whether the API or API group is supported by a camera.
|
157
|
+
# @param [Symbol] api_or_group_name The API or API group name
|
158
|
+
# @return [Boolean] +true+ if supported, +false+ otherwise.
|
159
|
+
# @example
|
160
|
+
# # Initialize
|
161
|
+
# cam = SonyCameraRemoteAPI::Camera.new
|
162
|
+
# cam.change_function_to_shoot 'still', 'Single'
|
163
|
+
#
|
164
|
+
# # Check if actZoom API is supported.
|
165
|
+
# puts cam.support? :actZoom
|
166
|
+
# # Check if ZoomSetting API group is supported.
|
167
|
+
# puts cam.support? :ZoomSetting
|
168
|
+
def support?(api_or_group_name)
|
169
|
+
@raw_api_manager.support?(api_or_group_name) || @api_group_manager.support_group?(api_or_group_name)
|
170
|
+
end
|
171
|
+
|
172
|
+
|
156
173
|
private
|
157
174
|
|
175
|
+
# Call camera APIs with checking if it is available by 'getAvailableApiList'.
|
176
|
+
# If not available, wait a minute until the called API turns to be available.
|
177
|
+
# @param [String] service_type
|
178
|
+
# @param [String] method
|
179
|
+
# @param [Array,String] params
|
180
|
+
# @param [Fixnum] id
|
181
|
+
# @param [String] version
|
182
|
+
# @param [Fixnum] timeout Timeout in seconds for waiting until the API is available
|
183
|
+
def call_api_safe(service_type, method, params, id, version, timeout = DEFAULT_API_CALL_TIMEOUT, **args)
|
184
|
+
unless getAvailableApiList['result'][0].include? method
|
185
|
+
log.error "Method '#{method}' is not available now! waiting..."
|
186
|
+
begin
|
187
|
+
wait_event(timeout: timeout) { |res| res[0]['names'].include? method }
|
188
|
+
rescue EventTimeoutError => e
|
189
|
+
raise APINotAvailable.new, "Method '#{method}' is not available now!"
|
190
|
+
end
|
191
|
+
log.info "Method '#{method}' has become available."
|
192
|
+
end
|
193
|
+
@raw_api_manager.call_api(service_type, method, params, id, version)
|
194
|
+
end
|
195
|
+
|
196
|
+
|
158
197
|
# Call getEvent without polling if getEvent with polling failed.
|
159
198
|
def get_event_both(poll, timeout: nil)
|
160
199
|
getEvent(poll, timeout: timeout)
|
@@ -194,6 +233,5 @@ module SonyCameraRemoteAPI
|
|
194
233
|
retry_count += 1
|
195
234
|
retry
|
196
235
|
end
|
197
|
-
|
198
236
|
end
|
199
237
|
end
|
@@ -130,32 +130,58 @@ module SonyCameraRemoteAPI
|
|
130
130
|
end
|
131
131
|
|
132
132
|
|
133
|
-
# Get current value of
|
133
|
+
# Get current value of the camera parameter.
|
134
134
|
# @param [Symbol] group_name Parameter name
|
135
|
-
# @return [Object]
|
136
|
-
# @raise APINotSupported, APINotAvailable, IllegalArgument
|
135
|
+
# @return [Object] Current value
|
136
|
+
# @raise APIForbidden, APINotSupported, APINotAvailable, IllegalArgument
|
137
|
+
# @example
|
138
|
+
# # Initialize
|
139
|
+
# cam = SonyCameraRemoteAPI::Camera.new
|
140
|
+
# cam.change_function_to_shoot 'still', 'Single'
|
141
|
+
#
|
142
|
+
# value = cam.get_current :ContShootingMode
|
143
|
+
# puts value #=> 'Burst', 'MotionShot', Continuous' ...
|
137
144
|
def get_current(group_name, **opts)
|
138
145
|
get_parameter(group_name, available: false, supported: false, **opts)[:current]
|
139
146
|
end
|
140
147
|
|
141
148
|
|
142
|
-
# Almost same as get_current, but this method does not raise Exception
|
143
|
-
#
|
144
|
-
# @
|
145
|
-
# @
|
149
|
+
# Almost same as get_current, but this method does not raise Exception.
|
150
|
+
# @return [Object, nil] Current value or nil if any error occurred.
|
151
|
+
# @see get_current
|
152
|
+
# @example
|
153
|
+
# # Initialize
|
154
|
+
# cam = SonyCameraRemoteAPI::Camera.new
|
155
|
+
# cam.change_function_to_shoot 'still', 'Single'
|
156
|
+
#
|
157
|
+
# value = cam.get_current! :ContShootingMode
|
158
|
+
# if value
|
159
|
+
# puts "ContShootingMode is supported, and current value is #{value}"
|
160
|
+
# else
|
161
|
+
# puts 'ContShootingMode is not supported.'
|
162
|
+
# end
|
146
163
|
def get_current!(group_name, **opts)
|
147
164
|
get_parameter!(group_name, available: false, supported: false, **opts)[:current]
|
148
165
|
end
|
149
166
|
|
150
167
|
|
151
|
-
# Get supported/available/current value of
|
168
|
+
# Get supported/available/current value of the camera parameter.
|
152
169
|
# @param [Symbol] group_name Parameter name
|
153
170
|
# @param [Boolean] available Flag to get available values
|
154
171
|
# @param [Boolean] supported Flag to get supported values
|
155
172
|
# @return [Hash] current/available/supported values
|
156
|
-
# @raise APINotSupported, APINotAvailable, IllegalArgument
|
173
|
+
# @raise APIForbidden, APINotSupported, APINotAvailable, IllegalArgument
|
174
|
+
# @example
|
175
|
+
# # Initialize
|
176
|
+
# cam = SonyCameraRemoteAPI::Camera.new
|
177
|
+
# cam.change_function_to_shoot 'movie'
|
178
|
+
#
|
179
|
+
# result = cam.get_parameter :ExposureMode
|
180
|
+
# puts "current value : #{result[:current]}"
|
181
|
+
# puts "available values: #{result[:available]}"
|
182
|
+
# puts "supported values: #{result[:supported]}"
|
157
183
|
def get_parameter(group_name, available: true, supported: true, **opts)
|
158
|
-
result = { current: nil, available:
|
184
|
+
result = { current: nil, available: nil, supported: nil }
|
159
185
|
begin
|
160
186
|
grp = search_group group_name
|
161
187
|
rescue APIForbidden, APINotSupported => e
|
@@ -178,8 +204,25 @@ module SonyCameraRemoteAPI
|
|
178
204
|
end
|
179
205
|
|
180
206
|
|
181
|
-
# Almost same as get_parameter, but this method does not raise Exception
|
182
|
-
#
|
207
|
+
# Almost same as get_parameter, but this method does not raise Exception.
|
208
|
+
# @return [Hash] current/available/supported values. If any error occurs, the value that cannot get become nil.
|
209
|
+
# @see get_parameter
|
210
|
+
# @example
|
211
|
+
# # Initialize
|
212
|
+
# cam = SonyCameraRemoteAPI::Camera.new
|
213
|
+
# cam.change_function_to_shoot 'still', 'Single'
|
214
|
+
#
|
215
|
+
# result = cam.get_parameter! :ExposureMode
|
216
|
+
# if result[:current]
|
217
|
+
# puts 'ExposureMode is supported.'
|
218
|
+
# if result[:available] && result[:supported]
|
219
|
+
# puts 'And you can change the value by #set_parameter.'
|
220
|
+
# else
|
221
|
+
# puts 'And you can change the value by the hardware dial or switch (NOT by #set_parameter).'
|
222
|
+
# end
|
223
|
+
# else
|
224
|
+
# puts 'ExposureMode is not supported!'
|
225
|
+
# end
|
183
226
|
def get_parameter!(group_name, **opts)
|
184
227
|
get_parameter(group_name, **opts)
|
185
228
|
rescue APIForbidden, APINotSupported, APINotAvailable, IllegalArgument => e
|
@@ -190,13 +233,28 @@ module SonyCameraRemoteAPI
|
|
190
233
|
end
|
191
234
|
|
192
235
|
|
193
|
-
# Set
|
236
|
+
# Set the camera parameter to the given value.
|
194
237
|
# @param [Symbol] group_name Parameter name
|
195
238
|
# @param [Object] value New value to be set
|
196
|
-
# @return [Hash] current/available/old values
|
197
|
-
#
|
239
|
+
# @return [Hash] current/available/old values after setting parameter.
|
240
|
+
# If given value is equal to current value, available/old values become nil.
|
241
|
+
# @raise APIForbidden, APINotSupported, APINotAvailable, IllegalArgument
|
242
|
+
# @example
|
243
|
+
# # Initialize
|
244
|
+
# cam = SonyCameraRemoteAPI::Camera.new
|
245
|
+
# cam.change_function_to_shoot 'still', 'Single'
|
246
|
+
#
|
247
|
+
# result = cam.set_parameter :FlashMode, 'slowSync'
|
248
|
+
# if result[:old]
|
249
|
+
# puts "The value is changed from '#{result[:old]}' to '#{result[:current]}'."
|
250
|
+
# else
|
251
|
+
# puts 'The value is not changed.'
|
252
|
+
# end
|
253
|
+
# puts "current value : #{result[:current]}"
|
254
|
+
# puts "available values: #{result[:available]}"
|
255
|
+
# puts "old value : #{result[:old]}"
|
198
256
|
def set_parameter(group_name, value, *args, **opts)
|
199
|
-
result = { current: nil, available:
|
257
|
+
result = { current: nil, available: nil, old: nil }
|
200
258
|
begin
|
201
259
|
grp = search_group group_name
|
202
260
|
rescue APIForbidden, APINotSupported => e
|
@@ -208,7 +266,6 @@ module SonyCameraRemoteAPI
|
|
208
266
|
value = grp.preprocess_value(value, args, condition)
|
209
267
|
# If value is equal to current value, do nothing.
|
210
268
|
result.merge! grp.current_value(@api_manager, condition, **opts)
|
211
|
-
result[:old] = result[:current]
|
212
269
|
if grp.eq_current? value, result[:current], condition
|
213
270
|
return result
|
214
271
|
end
|
@@ -229,8 +286,27 @@ module SonyCameraRemoteAPI
|
|
229
286
|
end
|
230
287
|
|
231
288
|
|
232
|
-
# Almost same as set_parameter, but this method does not raise Exception
|
233
|
-
#
|
289
|
+
# Almost same as set_parameter, but this method does not raise Exception.
|
290
|
+
# @return [Hash] current/available/old values after setting parameter.
|
291
|
+
# If given value is equal to current value, available/old values become nil.
|
292
|
+
# If any error occurs, the values that cannot get become nil.
|
293
|
+
# @see set_parameter
|
294
|
+
# @example
|
295
|
+
# # Initialize
|
296
|
+
# cam = SonyCameraRemoteAPI::Camera.new
|
297
|
+
# cam.change_function_to_shoot 'still', 'Single'
|
298
|
+
#
|
299
|
+
# result = cam.set_parameter! :FlashMode, 'on'
|
300
|
+
# if result[:current]
|
301
|
+
# puts 'FlashMode is supported.'
|
302
|
+
# if result[:current] == 'on'
|
303
|
+
# puts "And successfully set the value to '#{result[:current]}'."
|
304
|
+
# else
|
305
|
+
# puts 'But cannot set the value.'
|
306
|
+
# end
|
307
|
+
# else
|
308
|
+
# puts 'FlashMode is not supported!'
|
309
|
+
# end
|
234
310
|
def set_parameter!(group_name, value, **opts)
|
235
311
|
set_parameter(group_name, value, **opts)
|
236
312
|
rescue APIForbidden, APINotSupported, APINotAvailable, IllegalArgument => e
|
@@ -241,6 +317,13 @@ module SonyCameraRemoteAPI
|
|
241
317
|
end
|
242
318
|
|
243
319
|
|
320
|
+
# Get an array of supported camera parameters.
|
321
|
+
# @return [Array<String>] supported camera parameters
|
322
|
+
def parameters
|
323
|
+
@api_groups.keys
|
324
|
+
end
|
325
|
+
|
326
|
+
|
244
327
|
# Returns whether the parameter is supported or not.
|
245
328
|
# @return [Boolean] +true+ if the parameter is supported, false otherwise.
|
246
329
|
def support_group?(group_name)
|
@@ -11,12 +11,13 @@ require 'time'
|
|
11
11
|
require 'pp'
|
12
12
|
|
13
13
|
module SonyCameraRemoteAPI
|
14
|
-
#
|
14
|
+
# sonycam client module
|
15
15
|
module Client
|
16
16
|
|
17
17
|
# Default config file saved in home directory.
|
18
18
|
GLOBAL_CONFIG_FILE = File.expand_path('~/.sonycamconf')
|
19
19
|
|
20
|
+
# Main class of client
|
20
21
|
class Main < Thor
|
21
22
|
include Utils
|
22
23
|
include Scripts
|
@@ -39,9 +40,9 @@ module SonyCameraRemoteAPI
|
|
39
40
|
def load_camera_config
|
40
41
|
# If SSID is specified, load the camera config.
|
41
42
|
if options[:ssid]
|
42
|
-
@shelf.get options[:ssid] || @shelf.
|
43
|
+
@shelf.get options[:ssid] || @shelf.get
|
43
44
|
else
|
44
|
-
@shelf.
|
45
|
+
@shelf.get
|
45
46
|
end
|
46
47
|
end
|
47
48
|
|
@@ -67,7 +68,7 @@ module SonyCameraRemoteAPI
|
|
67
68
|
puts 'Initializing camera...'
|
68
69
|
if config['endpoints'].nil?
|
69
70
|
@cam = SonyCameraRemoteAPI::Camera.new reconnect_by: method(:load_and_connect)
|
70
|
-
@shelf.
|
71
|
+
@shelf.set_ep config['ssid'], @cam.endpoints
|
71
72
|
puts 'SSDP configuration saved.'
|
72
73
|
else
|
73
74
|
@cam = SonyCameraRemoteAPI::Camera.new endpoints: config['endpoints'],
|
@@ -108,7 +109,7 @@ module SonyCameraRemoteAPI
|
|
108
109
|
# Show for other parameter
|
109
110
|
def show_normal(result)
|
110
111
|
array = []
|
111
|
-
|
112
|
+
unless result[:supported]
|
112
113
|
# If current value is present but NO supported value, it is immutable.
|
113
114
|
result[:supported] = [result[:current]]
|
114
115
|
end
|
@@ -127,7 +128,7 @@ module SonyCameraRemoteAPI
|
|
127
128
|
# Show for WhiteBalance parameter
|
128
129
|
def show_WhiteBalance(result)
|
129
130
|
array = []
|
130
|
-
|
131
|
+
unless result[:supported]
|
131
132
|
# If current value is present but NO supported value, it is immutable.
|
132
133
|
result[:supported] = [result[:current]]
|
133
134
|
end
|
@@ -374,7 +375,7 @@ module SonyCameraRemoteAPI
|
|
374
375
|
option :transfer, type: :boolean, desc: 'Transfer postview image', default: false
|
375
376
|
def rapid
|
376
377
|
init_camera
|
377
|
-
unless @cam.
|
378
|
+
unless @cam.support? :ContShootingMode
|
378
379
|
puts 'This camera does not support continuous shooting mode. Exiting...'
|
379
380
|
exit 1
|
380
381
|
end
|
@@ -35,10 +35,16 @@ module Logging
|
|
35
35
|
# Log file is common in each user class.
|
36
36
|
# @param [String, IO, Array<String, IO>] log_file file name or stream to output log.
|
37
37
|
# @return [void]
|
38
|
-
def
|
38
|
+
def set_output(*log_file)
|
39
39
|
Logging.log_file self.class.name, log_file
|
40
40
|
end
|
41
41
|
|
42
|
+
# Set log level.
|
43
|
+
# @param [Fixnum] level Log level for Logger object.
|
44
|
+
def set_level(level)
|
45
|
+
@@level = level
|
46
|
+
end
|
47
|
+
|
42
48
|
#--------------------PUBLIC METHODS END----------------------
|
43
49
|
|
44
50
|
|
@@ -47,6 +53,8 @@ module Logging
|
|
47
53
|
# Use a hash class-ivar to cache a unique Logger per class.
|
48
54
|
@loggers = {}
|
49
55
|
|
56
|
+
@@level = Logger::DEBUG
|
57
|
+
|
50
58
|
# These module class methods are private to user class.
|
51
59
|
class << self
|
52
60
|
# Set log files and streams. Logger class instance is re-created.
|
@@ -70,6 +78,7 @@ module Logging
|
|
70
78
|
end
|
71
79
|
logger = Logger.new MultiDelegator.delegate(:write, :close).to(*fios)
|
72
80
|
logger.progname = classname.split('::')[-1]
|
81
|
+
logger.level = @@level
|
73
82
|
logger
|
74
83
|
end
|
75
84
|
end
|
@@ -157,12 +157,12 @@ module SonyCameraRemoteAPI
|
|
157
157
|
end
|
158
158
|
version = api_info.versions[0]
|
159
159
|
end
|
160
|
-
if opts.key? :
|
161
|
-
service = opts[:
|
162
|
-
if api_info.service_types.include? opts[:
|
163
|
-
service = opts[:
|
160
|
+
if opts.key? :service_type
|
161
|
+
service = opts[:service_type]
|
162
|
+
if api_info.service_types.include? opts[:service_type]
|
163
|
+
service = opts[:service_type]
|
164
164
|
else
|
165
|
-
raise ServiceTypeInvalid, "The service type '#{opts[:
|
165
|
+
raise ServiceTypeInvalid, "The service type '#{opts[:service_type]}' is invalid for method '#{method}'."
|
166
166
|
end
|
167
167
|
else
|
168
168
|
# raise error if service type is not given for method having multi service types
|
@@ -4,6 +4,7 @@ require 'yaml'
|
|
4
4
|
|
5
5
|
|
6
6
|
module SonyCameraRemoteAPI
|
7
|
+
# Class for handling multiple camera's connection configurations.
|
7
8
|
class Shelf
|
8
9
|
include Utils
|
9
10
|
|
@@ -125,7 +126,7 @@ module SonyCameraRemoteAPI
|
|
125
126
|
|
126
127
|
# Set endpoint information to a camera config.
|
127
128
|
# @return [Boolean] +true+ if successfully set endpoints, +false+ otherwise.
|
128
|
-
def
|
129
|
+
def set_ep(endpoints, ssid = nil)
|
129
130
|
entry = get(ssid)
|
130
131
|
if entry
|
131
132
|
entry['endpoints'] = endpoints
|
@@ -136,9 +137,21 @@ module SonyCameraRemoteAPI
|
|
136
137
|
end
|
137
138
|
|
138
139
|
|
140
|
+
# Get endpoint information to a camera config.
|
141
|
+
# @return [Boolean] +true+ if successfully set endpoints, +false+ otherwise.
|
142
|
+
def ep(ssid = nil)
|
143
|
+
entry = get(ssid)
|
144
|
+
if entry
|
145
|
+
entry['endpoints']
|
146
|
+
else
|
147
|
+
nil
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
151
|
+
|
139
152
|
# Set interface by which the camera is connected.
|
140
153
|
# @return [Boolean] +true+ if successfully set default camera, +false+ otherwise.
|
141
|
-
def
|
154
|
+
def set_if(interface, ssid = nil)
|
142
155
|
entry = get(ssid)
|
143
156
|
if entry
|
144
157
|
entry['interface'] = interface
|
@@ -163,6 +176,20 @@ module SonyCameraRemoteAPI
|
|
163
176
|
end
|
164
177
|
|
165
178
|
|
179
|
+
# Restart interface, and then connect to the camera.
|
180
|
+
# If SSID is not given, default camera is used.
|
181
|
+
# @param [String] ssid SSID
|
182
|
+
# @return [Boolean] +true+ if successfully connected, +false+ otherwise.
|
183
|
+
def reconnect(ssid = nil)
|
184
|
+
entry = get(ssid)
|
185
|
+
if entry
|
186
|
+
Scripts.restart_and_connect entry['interface'], entry['ssid'], entry['pass']
|
187
|
+
else
|
188
|
+
false
|
189
|
+
end
|
190
|
+
end
|
191
|
+
|
192
|
+
|
166
193
|
private
|
167
194
|
|
168
195
|
# Get camera whose SSID uniquely matches with specified string.
|
@@ -4,6 +4,7 @@ require 'sony_camera_remote_api/ssdp'
|
|
4
4
|
require 'sony_camera_remote_api/utils'
|
5
5
|
require 'sony_camera_remote_api/camera_api'
|
6
6
|
require 'sony_camera_remote_api/packet'
|
7
|
+
require 'sony_camera_remote_api/shelf'
|
7
8
|
require 'core_ext/hash_patch'
|
8
9
|
require 'httpclient'
|
9
10
|
require 'active_support'
|
@@ -21,10 +22,11 @@ module SonyCameraRemoteAPI
|
|
21
22
|
include SSDP
|
22
23
|
include Utils
|
23
24
|
|
24
|
-
def_delegators :@api_manager, :
|
25
|
-
|
26
|
-
|
27
|
-
|
25
|
+
def_delegators :@api_manager, :method_missing, :getEvent, :getAvailableApiList, :wait_event,
|
26
|
+
:get_parameter, :get_parameter!,
|
27
|
+
:set_parameter, :set_parameter!,
|
28
|
+
:get_current, :get_current!,
|
29
|
+
:support?, :parameters, :apis
|
28
30
|
|
29
31
|
attr_reader :endpoints
|
30
32
|
|
@@ -41,8 +43,9 @@ module SonyCameraRemoteAPI
|
|
41
43
|
# @param [String, IO, Array<String, IO>] log_file file name or stream to output log.
|
42
44
|
# @param [Boolean] finalize If true, stopRecMode API is called in the destructor.
|
43
45
|
# As far as I know, we don't have any trouble even if we never call stopRecMode.
|
44
|
-
def initialize(endpoints: nil, reconnect_by: nil, log_file: $stdout, finalize: false)
|
45
|
-
|
46
|
+
def initialize(endpoints: nil, reconnect_by: nil, log_file: $stdout, log_level: Logger::INFO, finalize: false)
|
47
|
+
set_output log_file
|
48
|
+
set_level log_level
|
46
49
|
@endpoints = endpoints || ssdp_search
|
47
50
|
@reconnect_by = reconnect_by
|
48
51
|
@api_manager = CameraAPIManager.new @endpoints, reconnect_by: @reconnect_by
|
@@ -102,7 +105,6 @@ module SonyCameraRemoteAPI
|
|
102
105
|
# * Single : take a single picture
|
103
106
|
# * Burst : take 10 pictures at a time
|
104
107
|
# * MotionShot : take 10 pictures and render the movement into a single picture
|
105
|
-
# @param [Boolean] focus Flag to focus on before capturing.
|
106
108
|
# @param [Boolean] transfer Flag to transfer the postview image.
|
107
109
|
# @param [String] filename Name of image file to be transferred. If not given, original name is used.
|
108
110
|
# Only available in Single/MotionShot shooting mode.
|
@@ -111,17 +113,16 @@ module SonyCameraRemoteAPI
|
|
111
113
|
# @param [String] dir Directory where image file is saved. If not given, current directory is used.
|
112
114
|
# @return [String, Array<String>, nil] Filename of the transferred image(s). If 'transfer' is false, returns nil.
|
113
115
|
# @example
|
114
|
-
# #
|
115
|
-
#
|
116
|
-
#
|
117
|
-
#
|
116
|
+
# # Initialize
|
117
|
+
# cam = SonyCameraRemoteAPI::Camera.new
|
118
|
+
# # Capture a single still image, and then save it as images/TEST.JPG.
|
119
|
+
# cam.change_function_to_shoot 'still', 'Single'
|
120
|
+
# cam.capture_still filename: 'TEST.JPG', dir: 'images'
|
118
121
|
#
|
119
|
-
# # Capture 10 images by burst shooting
|
120
|
-
# change_function_to_shoot
|
121
|
-
# capture_still
|
122
|
-
|
123
|
-
def capture_still(focus: true, transfer: true, filename: nil, prefix: nil, dir: nil)
|
124
|
-
act_focus if focus
|
122
|
+
# # Capture 10 images by burst shooting and save them as 'TEST_0.jpg', ... 'TEST_9.jpg'.
|
123
|
+
# cam.change_function_to_shoot 'still', 'Burst'
|
124
|
+
# cam.capture_still prefix: 'TEST'
|
125
|
+
def capture_still(transfer: true, filename: nil, prefix: nil, dir: nil)
|
125
126
|
wait_event { |r| r[1]['cameraStatus'] == 'IDLE' }
|
126
127
|
log.info 'Capturing...'
|
127
128
|
postview_url = ''
|
@@ -151,15 +152,16 @@ module SonyCameraRemoteAPI
|
|
151
152
|
# @note You have to set shooting mode to 'still' and continuous shooting mode to following modes:
|
152
153
|
# * Continuous : take pictures continuously until stopped.
|
153
154
|
# * Spd Priority Cont. : take pictures continuously at a rate faster than 'Continuous'.
|
154
|
-
# @param [Boolean] focus Flag to focus on before capturing.
|
155
155
|
# @return [void]
|
156
|
-
# @example
|
157
|
-
#
|
158
|
-
#
|
156
|
+
# @example
|
157
|
+
# # Initialize
|
158
|
+
# cam = SonyCameraRemoteAPI::Camera.new
|
159
|
+
# # Start continuous shooting and transfer all images.
|
160
|
+
# cam.change_function_to_shoot('still', 'Continuous')
|
161
|
+
# cam.start_continuous_shooting
|
159
162
|
# ...
|
160
|
-
# stop_continuous_shooting(transfer: true)
|
161
|
-
def start_continuous_shooting
|
162
|
-
act_focus if focus
|
163
|
+
# cam.stop_continuous_shooting(transfer: true)
|
164
|
+
def start_continuous_shooting
|
163
165
|
wait_event { |r| r[1]['cameraStatus'] == 'IDLE' }
|
164
166
|
startContShooting
|
165
167
|
wait_event { |r| r[1]['cameraStatus'] == 'StillCapturing' }
|
@@ -205,11 +207,14 @@ module SonyCameraRemoteAPI
|
|
205
207
|
# To stop recording, call stop_movie_recording method.
|
206
208
|
# @note You have to set shooting mode to 'movie' before calling this method.
|
207
209
|
# @return [void]
|
208
|
-
# @example
|
209
|
-
#
|
210
|
-
#
|
210
|
+
# @example
|
211
|
+
# # Initialize
|
212
|
+
# cam = SonyCameraRemoteAPI::Camera.new
|
213
|
+
# # Record movie and transfer it.
|
214
|
+
# cam.change_function_to_shoot('movie')
|
215
|
+
# cam.start_movie_recording
|
211
216
|
# ...
|
212
|
-
# stop_movie_recording(transfer: true)
|
217
|
+
# cam.stop_movie_recording(transfer: true)
|
213
218
|
def start_movie_recording
|
214
219
|
wait_event { |r| r[1]['cameraStatus'] == 'IDLE' }
|
215
220
|
startMovieRec
|
@@ -238,13 +243,16 @@ module SonyCameraRemoteAPI
|
|
238
243
|
# To stop recording, call stop_interval_recording method.
|
239
244
|
# @note You have to set shooting mode to 'intervalstill' before calling this method.
|
240
245
|
# @return [void]
|
241
|
-
# @example
|
242
|
-
#
|
243
|
-
#
|
246
|
+
# @example
|
247
|
+
# # Initialize
|
248
|
+
# cam = SonyCameraRemoteAPI::Camera.new
|
249
|
+
# # Start interval still recording (does not transfer).
|
250
|
+
# cam.change_function_to_shoot('intervalstill')
|
251
|
+
# cam.start_interval_recording
|
244
252
|
# ...
|
245
|
-
# stop_interval_recording
|
253
|
+
# cam.stop_interval_recording
|
246
254
|
def start_interval_recording
|
247
|
-
|
255
|
+
wait_event { |r| r[1]['cameraStatus'] == 'IDLE' }
|
248
256
|
startIntervalStillRec
|
249
257
|
wait_event { |r| r[1]['cameraStatus'] == 'IntervalRecording' }
|
250
258
|
log.info 'Started interval still recording.'
|
@@ -272,11 +280,14 @@ module SonyCameraRemoteAPI
|
|
272
280
|
# To stop recording, call stop_loop_recording method.
|
273
281
|
# @note You have to set shooting mode to 'looprec' before calling this method.
|
274
282
|
# @return [void]
|
275
|
-
# @example
|
276
|
-
#
|
277
|
-
#
|
283
|
+
# @example
|
284
|
+
# # Initialize
|
285
|
+
# cam = SonyCameraRemoteAPI::Camera.new
|
286
|
+
# # Start loop movie recording (does not transfer).
|
287
|
+
# cam.change_function_to_shoot('looprec')
|
288
|
+
# cam.start_loop_recording
|
278
289
|
# ...
|
279
|
-
# stop_loop_recording
|
290
|
+
# cam.stop_loop_recording
|
280
291
|
def start_loop_recording
|
281
292
|
wait_event { |r| r[1]['cameraStatus'] == 'IDLE' }
|
282
293
|
startLoopRec
|
@@ -308,9 +319,11 @@ module SonyCameraRemoteAPI
|
|
308
319
|
# @param [Fixnum] relative Relative percecntage to current position of the lense.
|
309
320
|
# @return [Array<Fixnum>] Array of initial zoom position and current zoom position.
|
310
321
|
# @example
|
311
|
-
#
|
312
|
-
#
|
313
|
-
# act_zoom(
|
322
|
+
# # Initialize
|
323
|
+
# cam = SonyCameraRemoteAPI::Camera.new
|
324
|
+
# cam.act_zoom(absolute: 0) # zoom out to the wide-end
|
325
|
+
# cam.act_zoom(absolute: 100) # zoom in to the tele-end
|
326
|
+
# cam.act_zoom(relative: -50) # zoom out by -50 from the current position
|
314
327
|
def act_zoom(absolute: nil, relative: nil)
|
315
328
|
# Check arguments
|
316
329
|
return if [relative, absolute].none?
|
@@ -349,16 +362,22 @@ module SonyCameraRemoteAPI
|
|
349
362
|
end
|
350
363
|
|
351
364
|
|
352
|
-
#
|
353
|
-
# If already focued, this method does nothing unless 'force' parameter specified as true.
|
354
|
-
# @param [Boolean] force Re-forcus if the camera has already focused.
|
365
|
+
# Do focus, which is the same as half-pressing the shutter button.
|
355
366
|
# @return [Boolean] +true+ if focus succeeded, +false+ if failed.
|
356
367
|
# @example
|
357
|
-
# #
|
358
|
-
#
|
359
|
-
|
368
|
+
# # Initialize
|
369
|
+
# cam = SonyCameraRemoteAPI::Camera.new
|
370
|
+
# # Focus function is available only 'still' shoot mode
|
371
|
+
# cam.change_function_to_shoot 'still'
|
372
|
+
# # Capture forever only when focus succeeded.
|
373
|
+
# loop do
|
374
|
+
# if cam.act_focus
|
375
|
+
# cam.capture_still
|
376
|
+
# end
|
377
|
+
# end
|
378
|
+
def act_focus
|
360
379
|
return false unless support? :actHalfPressShutter
|
361
|
-
|
380
|
+
cancel_focus
|
362
381
|
actHalfPressShutter
|
363
382
|
rsp = wait_event { |r| ['Focused', 'Failed'].include? r[35]['focusStatus'] }
|
364
383
|
if rsp[35]['focusStatus'] =='Focused'
|
@@ -373,24 +392,23 @@ module SonyCameraRemoteAPI
|
|
373
392
|
end
|
374
393
|
|
375
394
|
|
376
|
-
#
|
377
|
-
# The focus position is expressed by percentage to the origin of coordinates, which is upper left of liveview images.
|
378
|
-
# If already focued, this method does nothing unless 'force' parameter specified as true.
|
395
|
+
# Do touch focus, by which we can specify the focus position.
|
379
396
|
# @note Tracking focus and Touch focus is exclusive function.
|
380
397
|
# Tracking focus is disabled automatically by calling this method.
|
381
398
|
# @param [Fixnum] x Percentage of X-axis position.
|
382
399
|
# @param [Fixnum] y Percentage of Y-axis position.
|
383
|
-
# @param [Boolean] force Re-forcus if the camera has already focused.
|
384
400
|
# @return [Boolean] AFType ('Touch' or 'Wide') if focus succeeded. nil if failed.
|
385
401
|
# @see Touch AF position parameter in API reference
|
386
402
|
# @example
|
387
|
-
# #
|
388
|
-
#
|
389
|
-
# # Try to focus on upper-
|
390
|
-
# act_touch_focus(
|
391
|
-
|
403
|
+
# # Initialize
|
404
|
+
# cam = SonyCameraRemoteAPI::Camera.new
|
405
|
+
# # Try to focus on upper-middle position.
|
406
|
+
# if cam.act_touch_focus(50, 10)
|
407
|
+
# cam.capture_still
|
408
|
+
# end
|
409
|
+
def act_touch_focus(x, y)
|
392
410
|
return false unless support? :setTouchAFPosition
|
393
|
-
|
411
|
+
cancel_focus
|
394
412
|
set_parameter! :TrackingFocus, 'Off'
|
395
413
|
|
396
414
|
x = [[x, 100].min, 0].max
|
@@ -407,21 +425,32 @@ module SonyCameraRemoteAPI
|
|
407
425
|
end
|
408
426
|
|
409
427
|
|
410
|
-
#
|
428
|
+
# Do tracking focus, by which the focus position automatically track the object.
|
411
429
|
# The focus position is expressed by percentage to the origin of coordinates, which is upper left of liveview images.
|
412
|
-
# If already focued, this method does nothing unless 'force' parameter specified as true.
|
413
430
|
# @param [Fixnum] x Percentage of X-axis position.
|
414
431
|
# @param [Fixnum] y Percentage of Y-axis position.
|
415
|
-
# @param [Boolean] force Re-forcus if the camera has already focused.
|
416
432
|
# @return [Boolean] +true+ if focus succeeded, +false+ if failed.
|
417
433
|
# @example
|
418
|
-
# #
|
419
|
-
#
|
420
|
-
|
421
|
-
|
422
|
-
|
434
|
+
# # Initialize
|
435
|
+
# cam = SonyCameraRemoteAPI::Camera.new
|
436
|
+
# cam.change_function_to_shoot 'still'
|
437
|
+
# # Start tracking focus from the center position
|
438
|
+
# if cam.act_tracking_focus(50, 50)
|
439
|
+
# th = cam.start_liveview_thread do |img, info|
|
440
|
+
# info.frames.each do |f|
|
441
|
+
# # Get tracking focus position from the liveview frame info
|
442
|
+
# puts "top-left: (#{f.top_left.x}, #{f.top_left.y})"
|
443
|
+
# puts "bottom-right: (#{f.bottom_right.x}, #{f.bottom_right.y})"
|
444
|
+
# end
|
445
|
+
# end
|
446
|
+
# th.join
|
447
|
+
# end
|
448
|
+
def act_tracking_focus(x, y)
|
449
|
+
return false unless support? :TrackingFocus
|
450
|
+
cancel_focus
|
423
451
|
set_parameter :TrackingFocus, 'On'
|
424
452
|
|
453
|
+
|
425
454
|
x = [[x, 100].min, 0].max
|
426
455
|
y = [[y, 100].min, 0].max
|
427
456
|
actTrackingFocus(['xPosition': x, 'yPosition': y]).result
|
@@ -438,14 +467,35 @@ module SonyCameraRemoteAPI
|
|
438
467
|
|
439
468
|
# Return whether the camera has focused or not.
|
440
469
|
# @return [Boolean] +true+ if focused, +false+ otherwise.
|
470
|
+
# @see act_focus
|
471
|
+
# @see act_touch_focus
|
441
472
|
def focused?
|
442
473
|
result = getEvent(false).result
|
443
474
|
result[35] && result[35]['focusStatus'] == 'Focused'
|
444
475
|
end
|
445
476
|
|
446
477
|
|
447
|
-
#
|
478
|
+
# Return whether the camera is tracking an object for tracking focus.
|
479
|
+
# @return [Boolean] +true+ if focused, +false+ otherwise.
|
480
|
+
# @see act_tracking_focus
|
481
|
+
def tracking?
|
482
|
+
result = getEvent(false).result
|
483
|
+
result[54] && result[54]['trackingFocusStatus'] == 'Tracking'
|
484
|
+
end
|
485
|
+
|
486
|
+
|
487
|
+
# Cancel focus If camera has been focused.
|
448
488
|
# @return [void]
|
489
|
+
# @example
|
490
|
+
# # Initialize
|
491
|
+
# cam = SonyCameraRemoteAPI::Camera.new
|
492
|
+
# cam.change_function_to_shoot 'still', 'Single'
|
493
|
+
# # Try to focus on upper-middle position.
|
494
|
+
# if cam.act_tracking_focus(50, 10)
|
495
|
+
# puts cam.focused?
|
496
|
+
# cam.capture_still
|
497
|
+
# puts cam.focused?
|
498
|
+
# end
|
449
499
|
def cancel_focus
|
450
500
|
result = getEvent(false).result
|
451
501
|
# Canceling tracking/touch focus should be preceded for half-press
|
@@ -468,15 +518,27 @@ module SonyCameraRemoteAPI
|
|
468
518
|
# Starts a new thread that downloads streamed liveview images.
|
469
519
|
# This liveview thread continues downloading unless the one of the following conditions meets:
|
470
520
|
# The both hook method is called called each time after a liveview image or frame is downloaded.
|
471
|
-
# @param [String] size
|
472
|
-
# @param [Fixnum] time
|
521
|
+
# @param [String] size The liveview size.
|
522
|
+
# @param [Fixnum] time Time in seconds until finishing liveview streaming.
|
473
523
|
# @yield [LiveviewImage, LiveviewFrameInformation] The block called every time a liveview image is downloaded.
|
474
524
|
# @yieldparam [LiveviewImage] liveview image of each frame.
|
475
525
|
# @yieldparam [LiveviewFrameInformation] liveview frame information of each frame.
|
476
526
|
# If liveview frame information is not supported, nil is always given.
|
477
527
|
# @return [Thread] liveview downloading thread object
|
528
|
+
# @example
|
529
|
+
# # Initialize
|
530
|
+
# cam = SonyCameraRemoteAPI::Camera.new
|
531
|
+
# cam.change_function_to_shoot 'still', 'Single'
|
532
|
+
#
|
533
|
+
# # Start liveview streaming
|
534
|
+
# th = cam.start_liveview_thread do |img|
|
535
|
+
# filename = "liveview/#{img.sequence_number}.jpg"
|
536
|
+
# File.write filename, img.jpeg_data
|
537
|
+
# puts "wrote #{filename}."
|
538
|
+
# end
|
539
|
+
# th.join
|
478
540
|
def start_liveview_thread(size: nil, time: nil)
|
479
|
-
liveview_url = init_liveview size: size
|
541
|
+
liveview_url, frame_info_enabled = init_liveview size: size
|
480
542
|
log.debug "liveview URL: #{liveview_url}"
|
481
543
|
|
482
544
|
th = Thread.new do
|
@@ -512,14 +574,18 @@ module SonyCameraRemoteAPI
|
|
512
574
|
log.debug " sequence : #{obj.sequence_number}"
|
513
575
|
log.debug " data_size : #{obj.payload.payload_data_size_wo_padding}"
|
514
576
|
log.debug " pad_size : #{obj.payload.padding_size}"
|
515
|
-
|
516
|
-
|
577
|
+
if frame_info_enabled && frame_info.nil?
|
578
|
+
log.debug 'frame info is not present. skipping...'
|
579
|
+
else
|
580
|
+
block_time = Benchmark.realtime do
|
581
|
+
yield(LiveviewImage.new(obj), frame_info)
|
582
|
+
end
|
583
|
+
log.debug "block time : #{format('%.2f', block_time*1000)} ms."
|
517
584
|
end
|
518
|
-
log.info "block time : #{format('%.2f', block_time*1000)} ms."
|
519
585
|
count += 1
|
520
586
|
when 0x02
|
521
587
|
# When payload is liveview frame information
|
522
|
-
log.
|
588
|
+
log.debug "frame count = #{obj.payload.frame_count}"
|
523
589
|
if obj.payload.frame_count > 0
|
524
590
|
obj.payload.frame_data.each do |d|
|
525
591
|
log.debug " category : #{d.category}"
|
@@ -573,15 +639,27 @@ module SonyCameraRemoteAPI
|
|
573
639
|
# Unlike the one of request parameter of getContentList API, you can specify over 100.
|
574
640
|
# @return [Array<Hash>] Content informations
|
575
641
|
# @see getContentList API in the API reference.
|
576
|
-
# @example
|
577
|
-
#
|
642
|
+
# @example
|
643
|
+
# # Initialize
|
644
|
+
# cam = SonyCameraRemoteAPI::Camera.new
|
645
|
+
# cam.change_function_to_transfer
|
646
|
+
#
|
647
|
+
# # Get all contents
|
648
|
+
# contents = cam.get_content_list
|
649
|
+
# # Get still contents created on 2016/8/1
|
650
|
+
# contents = cam.get_content_list(type: 'still', date: '20160801')
|
651
|
+
# # Get 3 oldest movie contents
|
652
|
+
# contents = cam.get_content_list(type: ['movie_xavcs', 'movie_mp4'], sort: 'ascending', count: 3)
|
578
653
|
#
|
579
|
-
# # Get
|
580
|
-
#
|
581
|
-
#
|
582
|
-
#
|
583
|
-
#
|
584
|
-
#
|
654
|
+
# # Get filenames and URL of each content
|
655
|
+
# contents.each do |c|
|
656
|
+
# filename = c['content']['original'][0]['fileName']
|
657
|
+
# url = c['content']['original'][0]['url']
|
658
|
+
# puts "#{filename}, #{url}"
|
659
|
+
# end
|
660
|
+
#
|
661
|
+
# # Transfer contents
|
662
|
+
# cam.transfer_contents(contents)
|
585
663
|
def get_content_list(type: nil, date: nil, sort: 'descending', count: nil)
|
586
664
|
type = Array(type) if type.is_a? String
|
587
665
|
|
@@ -633,14 +711,26 @@ module SonyCameraRemoteAPI
|
|
633
711
|
# @param [Fixnum] date_count Number of dates to get.
|
634
712
|
# @param [Fixnum] content_count Number of contents to get
|
635
713
|
# @return [Array< Array<String, Fixnum> >] Array of pairs of a date in format of 'YYYYMMDD' and a number of contents of the date.
|
636
|
-
# @example
|
637
|
-
#
|
714
|
+
# @example
|
715
|
+
# # Initialize
|
716
|
+
# cam = SonyCameraRemoteAPI::Camera.new
|
717
|
+
# cam.change_function_to_transfer
|
718
|
+
#
|
638
719
|
# # Get all dates and the number of contents of the date
|
639
|
-
# get_date_list
|
640
|
-
# # Get 5 newest dates that contains at least one
|
641
|
-
# get_date_list(type:
|
720
|
+
# dates = cam.get_date_list
|
721
|
+
# # Get 5 newest dates that contains at least one XAVC-S movie content.
|
722
|
+
# dates = cam.get_date_list(type: 'movie_xavcs', date_count: 5)
|
642
723
|
# # Get all dates that contains at least 10 still contents.
|
643
|
-
# get_date_list(type: 'still', content_count: 10)
|
724
|
+
# dates = cam.get_date_list(type: 'still', content_count: 10)
|
725
|
+
#
|
726
|
+
# dates.each do |date, count|
|
727
|
+
# # Get date and its content count
|
728
|
+
# puts "#{date['title']}, #{count}"
|
729
|
+
# # Get contents of each date
|
730
|
+
# contents = cam.get_content_list date: date['title']
|
731
|
+
# # Transfer contents
|
732
|
+
# cam.transfer_contents contents
|
733
|
+
# end
|
644
734
|
def get_date_list(type: nil, sort: 'descending', date_count: nil, content_count: nil)
|
645
735
|
type = Array(type) if type.is_a? String
|
646
736
|
|
@@ -677,10 +767,9 @@ module SonyCameraRemoteAPI
|
|
677
767
|
# @param [Array<Hash>] contents Array of content information, which can be obtained by get_content_list
|
678
768
|
# @param [Array<String>] filenames Array of filename strings
|
679
769
|
# @param [String] size Content size. available values are 'original', 'large', 'small', 'thumbnail'.
|
680
|
-
# @
|
681
|
-
#
|
682
|
-
#
|
683
|
-
# transfer_contents(contents) # transfer them
|
770
|
+
# @see get_content_list
|
771
|
+
# @see get_date_list
|
772
|
+
# @todo If 'contents' is directory (date), get all contents of the directory.
|
684
773
|
def transfer_contents(contents, filenames=[], dir: nil, size: 'original')
|
685
774
|
if SIZE_LIST.exclude?(size)
|
686
775
|
log.error "#{size} is invalid for size option!"
|
@@ -730,10 +819,14 @@ module SonyCameraRemoteAPI
|
|
730
819
|
# Delete content(s) of camera storage.
|
731
820
|
# @note You have to set camera function to 'Contents Transfer' before calling this method.
|
732
821
|
# @param [Array<Hash>] contents array of content hashes, which can be obtained by get_content_list
|
733
|
-
# @example
|
734
|
-
#
|
735
|
-
#
|
736
|
-
#
|
822
|
+
# @example
|
823
|
+
# # Initialize
|
824
|
+
# cam = SonyCameraRemoteAPI::Camera.new
|
825
|
+
# cam.change_function_to_transfer
|
826
|
+
#
|
827
|
+
# # Delete 10 newest still contents
|
828
|
+
# contents = cam.get_content_list(type: 'still', count: 10)
|
829
|
+
# cam.delete_contents(contents)
|
737
830
|
def delete_contents(contents)
|
738
831
|
contents = [contents].compact unless contents.is_a? Array
|
739
832
|
count = contents.size
|
@@ -935,20 +1028,15 @@ module SonyCameraRemoteAPI
|
|
935
1028
|
end
|
936
1029
|
|
937
1030
|
|
938
|
-
def needs_focus?(force: false)
|
939
|
-
if force
|
940
|
-
cancel_focus
|
941
|
-
true
|
942
|
-
else
|
943
|
-
! focused?
|
944
|
-
end
|
945
|
-
end
|
946
|
-
|
947
|
-
|
948
1031
|
# Initialize and start liveview
|
949
1032
|
def init_liveview(size: nil)
|
950
1033
|
# Enable liveview frame information if available
|
951
|
-
setLiveviewFrameInfo!([{'frameInfo' => true}])
|
1034
|
+
rsp = setLiveviewFrameInfo!([{'frameInfo' => true}])
|
1035
|
+
if rsp && rsp.result
|
1036
|
+
frame_info_enabled = true
|
1037
|
+
else
|
1038
|
+
frame_info_enabled = false
|
1039
|
+
end
|
952
1040
|
|
953
1041
|
if size
|
954
1042
|
# need to stop liveview when the liveview size is changed
|
@@ -957,9 +1045,9 @@ module SonyCameraRemoteAPI
|
|
957
1045
|
unless available.include?(size)
|
958
1046
|
raise IllegalArgument, new, "The value '#{size}' is not available for parameter 'LiveviewSize'. current: #{current}, available: #{available}"
|
959
1047
|
end
|
960
|
-
startLiveviewWithSize([size]).result[0]
|
1048
|
+
[ startLiveviewWithSize([size]).result[0], frame_info_enabled ]
|
961
1049
|
else
|
962
|
-
startLiveview.result[0]
|
1050
|
+
[ startLiveview.result[0], frame_info_enabled ]
|
963
1051
|
end
|
964
1052
|
end
|
965
1053
|
|
@@ -1041,4 +1129,4 @@ module SonyCameraRemoteAPI
|
|
1041
1129
|
reconnect_and_retry(retrying: false, &block)
|
1042
1130
|
end
|
1043
1131
|
end
|
1044
|
-
end
|
1132
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sony_camera_remote_api
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- kota65535
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-09-
|
11
|
+
date: 2016-09-25 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|