sony_camera_remote_api 0.1.4 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 6375fb3082ba64b715c9274945dc2b6b1dd59886
4
- data.tar.gz: 9472f59d3577ccbd5c2e004f4c58b81692559883
3
+ metadata.gz: 1673c9a0e55968b5691e720ba4580f10fdc89301
4
+ data.tar.gz: b7dfb169b64c3625e80d5a480a8d50d3aa6a5af2
5
5
  SHA512:
6
- metadata.gz: e9ba24e31f964de2c2071cd5130bb357fdd64634c5c3856c9aa5b1c7011257baaeb7adcae210ee18f28efe3fd99a9d10893f7718277d684b8d761d1cc7ca3fbf
7
- data.tar.gz: c4dac8ad1de4ef5df1db9b0aedf1197e19507746a0fdbbbdd5abc1a49a28ff28a5cc2852cc8fffb8979b1e6d4e6c35971cae2684bf2070b9810ebc61c0ef20cb
6
+ metadata.gz: 41eef398296c1351f7c792c9ca67c38a7102f831790f97d381e8db2ce15deb252b9b335de830f91c3d922c54822120b56fad94868afff9b62765eac6a42a1107
7
+ data.tar.gz: 90bb27d0d5cad30a6d3999f640efa1caf4f47fc4f96a5c105cf35b363687ba844962b805765b5dceb74e07167690b0a22271f318e10590e6326f69ad7837b942
@@ -1,13 +1,18 @@
1
+ # Hash extension for handling API response.
1
2
  class Hash
2
- # Get result element of API response.
3
+ # Get result element.
3
4
  def result
4
5
  self['result']
5
6
  end
6
- # Get id element of API response.
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 of API response.
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
- def_delegator :@api_group_manager, :support_group?
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
- # If Camera API (servie type == camera) is called, call_api_safe() is used.
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 a camera parameter.
133
+ # Get current value of the camera parameter.
134
134
  # @param [Symbol] group_name Parameter name
135
- # @return [Object] current value
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
- # even if the parameter is not supported, available or its arguments illegal.
144
- # @param [Symbol] group_name Parameter name
145
- # @return [Object] current value
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 a camera parameter.
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: [], supported: [] }
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
- # even if the parameter is not supported, available or its arguments illegal.
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 a camera parameter to the given value.
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
- # @raise APINotSupported, APINotAvailable, IllegalArgument
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: [], old: nil }
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
- # even if the parameter is not supported, available or its arguments illegal.
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
- # CLI client module
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.get_default
43
+ @shelf.get options[:ssid] || @shelf.get
43
44
  else
44
- @shelf.get_default
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.set_endpoints config['ssid'], @cam.endpoints
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
- if result[:supported].empty?
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
- if result[:supported].empty?
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.support_group? :ContShootingMode
378
+ unless @cam.support? :ContShootingMode
378
379
  puts 'This camera does not support continuous shooting mode. Exiting...'
379
380
  exit 1
380
381
  end
@@ -155,7 +155,7 @@ module SonyCameraRemoteAPI
155
155
  return
156
156
  end
157
157
  end
158
- @shelf.set_interface if_name, specified['ssid'] if specified
158
+ @shelf.set_if if_name, specified['ssid'] if specified
159
159
  invoke :list, [], options
160
160
  end
161
161
 
@@ -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 output_to(*log_file)
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? :service
161
- service = opts[:service]
162
- if api_info.service_types.include? opts[:service]
163
- service = opts[:service]
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[:service]}' is invalid for method '#{method}'."
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 set_endpoints(endpoints, ssid = nil)
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 set_interface(interface, ssid = nil)
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.
@@ -1,3 +1,4 @@
1
1
  module SonyCameraRemoteAPI
2
- VERSION = '0.1.4'.freeze
2
+ # Version
3
+ VERSION = '0.2.0'.freeze
3
4
  end
@@ -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, :apis, :method_missing, :getEvent, :getAvailableApiList,
25
- :wait_event,
26
- :get_parameter, :get_parameter!, :set_parameter, :set_parameter!, :get_current, :get_current!,
27
- :support?, :support_group?
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
- output_to log_file if log_file.present?
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
- # # Capture single still image and save it as 'a.jpg' to 'image' directory
115
- # change_function_to_shoot('still', 'Single')
116
- # capture_still
117
- # capture_still(filename: 'a.jpg', dir: 'image')
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 mode and save them as 'TEST_0.jpg', ... 'TEST_9.jpg'.
120
- # change_function_to_shoot('still', 'Burst')
121
- # capture_still
122
- # capture_still(prefix: 'TEST')
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 Do continuous shooting and transfer:
157
- # change_function_to_shoot('still', 'Continuous')
158
- # start_continuous_shooting
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(focus: true)
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 Record movie and transfer:
209
- # change_function_to_shoot('movie')
210
- # start_movie_recording
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 Do interval still recording:
242
- # change_function_to_shoot('intervalstill')
243
- # start_interval_recording
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(transfer: true)
253
+ # cam.stop_interval_recording
246
254
  def start_interval_recording
247
- act_focus
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 Typical usage:
276
- # change_function_to_shoot('looprec')
277
- # start_loop_recording
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(transfer: true)
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
- # act_zoom(absolute: 0) # zoom out to the wide-end
312
- # act_zoom(absolute: 100) # zoom in to the tele-end
313
- # act_zoom(relative: -50) # zoom out by -50 from the current position
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
- # Act focus, which is the same as half-pressing shutter button.
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
- # # Try to focus on and succeeded.
358
- # act_focus #=> true
359
- def act_focus(force: false)
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
- return true unless needs_focus?(force: force)
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
- # Act touch focus, by which we can specify the focus position.
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
- # # Try to focus on bottom-left position and succeeded with 'Wide' type focus.
388
- # act_touch_focus(10, 90) #=> 'Wide'
389
- # # Try to focus on upper-right position but failed.
390
- # act_touch_focus(90, 10) #=> nil
391
- def act_touch_focus(x, y, force: false)
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
- return true unless needs_focus?(force: force)
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
- # Act trackig focus, by which the focus position automatically track the object.
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
- # # Act tracking focus from the center position, and succeeded to start tracking.
419
- # act_tracking_focus(50, 50) #=> true
420
- def act_tracking_focus(x, y, force: false)
421
- return false unless support_group? :TrackingFocus
422
- return true unless needs_focus?(force: force)
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
- # Cancel all type of focuses (half press, touch focus, tracking focus).
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 The liveview size.
472
- # @param [Fixnum] time Time in seconds until finishing liveview streaming.
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
- block_time = Benchmark.realtime do
516
- yield(LiveviewImage.new(obj), frame_info)
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.info "frame count = #{obj.payload.frame_count}"
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 Typical usage:
577
- # change_function_to_transfer
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 all contents in the storage
580
- # get_content_list
581
- # # Get still contents captured on 2016/8/1
582
- # get_content_list(type: 'still', date: '20160801')
583
- # # Get 3 oldest XAVC-S movie contents
584
- # get_content_list(type: 'movie_xavcs', sort: 'ascending', count: 3)
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 Typical usage:
637
- # change_function_to_transfer
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 MP4 and XAVC-S movie content.
641
- # get_date_list(type: ['movie_mp4','movie_xavcs'], date_count: 5)
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
- # @example Typical usage:
681
- # change_function_to_transfer
682
- # contents = get_content_list(type: 'still', count: 10) # get 10 newest still contents
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 Typical usage:
734
- # change_function_to_transfer
735
- # contents = get_content_list(type: still, count: 10) # get 10 newest still contents
736
- # delete_contents(contents) # delete them
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.1.4
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-19 00:00:00.000000000 Z
11
+ date: 2016-09-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler