sony_camera_remote_api 0.2.1 → 0.2.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.simplecov +2 -2
- data/README.md +2 -2
- data/lib/sony_camera_remote_api/camera_api.rb +2 -2
- data/lib/sony_camera_remote_api/client/main.rb +4 -4
- data/lib/sony_camera_remote_api/client/shelf.rb +0 -21
- data/lib/sony_camera_remote_api/version.rb +1 -1
- data/lib/sony_camera_remote_api.rb +110 -54
- data/sony_camera_remote_api.gemspec +1 -1
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d22147c515ca8ec69ab26b0eaf6c244c04030e5e
|
4
|
+
data.tar.gz: b6f7dd99685957579340411cda11133e29c3ebf6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: fc07a67d20bdad6c13d02b6c3bd6fb763882fc40c540ecc734329ee7cf8cd868aa2e871e74347df9800aa3bb54431b75617fccb7181fb11c0cb2d185d9e8e68c
|
7
|
+
data.tar.gz: e1f1e9047a6d92284207f5f73b00ba5a66d58fb8ddfaa4ca1151292b1144076771a24b12f7984f4096e0ed85dcc87f5d404b1e565d145febab206d7849f33970
|
data/.simplecov
CHANGED
@@ -1,9 +1,9 @@
|
|
1
1
|
if !ENV['COVERAGE'].nil?
|
2
2
|
SimpleCov.start do
|
3
3
|
add_filter '/spec'
|
4
|
-
# Merge all tests run in
|
4
|
+
# Merge all tests run in 2 hours
|
5
5
|
use_merging true
|
6
|
-
merge_timeout
|
6
|
+
merge_timeout 7200
|
7
7
|
command_name "cmd_#{Time.now}"
|
8
8
|
puts 'SimpleCov started!!!'
|
9
9
|
# minimum_coverage(91.69)
|
data/README.md
CHANGED
@@ -212,7 +212,8 @@ module SonyCameraRemoteAPI
|
|
212
212
|
yield
|
213
213
|
rescue HTTPClient::TimeoutError, Errno::EHOSTUNREACH, Errno::ECONNREFUSED => e
|
214
214
|
retry_count ||= 0
|
215
|
-
|
215
|
+
retry_count += 1
|
216
|
+
raise e if @reconnect_by.nil? || retry_count > num
|
216
217
|
log.error "#{e.class}: #{e.message}"
|
217
218
|
log.error 'The camera seems to be disconnected! Reconnecting...'
|
218
219
|
unless @reconnect_by.call
|
@@ -231,7 +232,6 @@ module SonyCameraRemoteAPI
|
|
231
232
|
raise e
|
232
233
|
end
|
233
234
|
end
|
234
|
-
retry_count += 1
|
235
235
|
retry
|
236
236
|
end
|
237
237
|
end
|
@@ -574,12 +574,12 @@ module SonyCameraRemoteAPI
|
|
574
574
|
|
575
575
|
puts 'Retrieving...'
|
576
576
|
if options[:datelist]
|
577
|
-
dates
|
578
|
-
num_contents = dates.map { |d
|
577
|
+
dates = @cam.get_date_list date_count: options[:count]
|
578
|
+
num_contents = dates.map { |d| d['contentCount'] }.inject(:+)
|
579
579
|
puts "#{dates.size} date folders / #{num_contents} contents found."
|
580
580
|
puts "Dates\t\tN-Contents"
|
581
|
-
dates.each do |date
|
582
|
-
puts "#{date['title']}\t#{
|
581
|
+
dates.each do |date|
|
582
|
+
puts "#{date['title']}\t#{date['contentCount']}"
|
583
583
|
end
|
584
584
|
return
|
585
585
|
end
|
@@ -160,27 +160,6 @@ module SonyCameraRemoteAPI
|
|
160
160
|
end
|
161
161
|
|
162
162
|
|
163
|
-
desc 'default', 'Show the default camera currently selected'
|
164
|
-
option :json, type: :boolean, desc: 'output in JSON format'
|
165
|
-
def default
|
166
|
-
read_or_create_shelf
|
167
|
-
|
168
|
-
default = @shelf.get
|
169
|
-
unless default
|
170
|
-
puts 'ERROR: Default camera is not selected yet!'
|
171
|
-
return
|
172
|
-
end
|
173
|
-
|
174
|
-
if options[:json]
|
175
|
-
puts JSON.pretty_generate default
|
176
|
-
else
|
177
|
-
puts "SSID : #{default['ssid']} "
|
178
|
-
puts "Password : #{default['pass']} "
|
179
|
-
puts "Interface : #{default['interface']} "
|
180
|
-
end
|
181
|
-
end
|
182
|
-
|
183
|
-
|
184
163
|
desc 'connect [options]', 'Connect to the default camera'
|
185
164
|
option :restart, aliases: '-r', type: :boolean, desc: 'Restart interface', default: false
|
186
165
|
option :ssid, aliases: '-s', type: :string, desc: 'Specify camera by SSID'
|
@@ -422,9 +422,24 @@ module SonyCameraRemoteAPI
|
|
422
422
|
# cam = SonyCameraRemoteAPI::Camera.new
|
423
423
|
# cam.change_function_to_shoot 'still'
|
424
424
|
#
|
425
|
-
#
|
426
|
-
#
|
427
|
-
#
|
425
|
+
# th = cam.start_liveview_thread do |img, info|
|
426
|
+
# focus_frame = info.frames.find { |f| f.category == 1 }
|
427
|
+
# if focus_frame
|
428
|
+
# # Get current focus position.
|
429
|
+
# puts " top-left = (#{focus_frame.top_left.x}, #{focus_frame.top_left.y})"
|
430
|
+
# puts " bottom-right = (#{focus_frame.bottom_right.x}, #{focus_frame.bottom_right.y})"
|
431
|
+
# else
|
432
|
+
# puts 'No focus frame!'
|
433
|
+
# end
|
434
|
+
# end
|
435
|
+
#
|
436
|
+
# # Do touch focus ramdonly, and capture a still if focused.
|
437
|
+
# loop do
|
438
|
+
# cam.act_touch_focus rand(101), rand(101)
|
439
|
+
# if cam.focused?
|
440
|
+
# cam.capture_still
|
441
|
+
# end
|
442
|
+
# sleep 1
|
428
443
|
# end
|
429
444
|
def act_touch_focus(x, y)
|
430
445
|
return false unless support? :setTouchAFPosition
|
@@ -456,23 +471,31 @@ module SonyCameraRemoteAPI
|
|
456
471
|
# cam = SonyCameraRemoteAPI::Camera.new
|
457
472
|
# cam.change_function_to_shoot 'still'
|
458
473
|
#
|
459
|
-
#
|
460
|
-
#
|
461
|
-
#
|
462
|
-
#
|
463
|
-
#
|
464
|
-
#
|
465
|
-
#
|
466
|
-
#
|
474
|
+
# th = cam.start_liveview_thread do |img, info|
|
475
|
+
# tracking_frame = info.frames.find { |f| f.category == 5 }
|
476
|
+
# if tracking_frame
|
477
|
+
# # Get tracking focus position from the liveview frame info
|
478
|
+
# puts " top-left = (#{tracking_frame.top_left.x}, #{tracking_frame.top_left.y})"
|
479
|
+
# puts " bottom-right = (#{tracking_frame.bottom_right.x}, #{tracking_frame.bottom_right.y})"
|
480
|
+
# else
|
481
|
+
# puts 'No tracking frame!'
|
482
|
+
# end
|
483
|
+
# end
|
484
|
+
#
|
485
|
+
# # Capture a still image while tracking.
|
486
|
+
# loop do
|
487
|
+
# if cam.tracking?
|
488
|
+
# cam.capture_still
|
489
|
+
# else
|
490
|
+
# cam.act_tracking_focus 50, 50
|
467
491
|
# end
|
468
|
-
#
|
492
|
+
# sleep 1
|
469
493
|
# end
|
470
494
|
def act_tracking_focus(x, y)
|
471
495
|
return false unless support? :TrackingFocus
|
472
496
|
cancel_focus
|
473
497
|
set_parameter :TrackingFocus, 'On'
|
474
498
|
|
475
|
-
|
476
499
|
x = [[x, 100].min, 0].max
|
477
500
|
y = [[y, 100].min, 0].max
|
478
501
|
actTrackingFocus(['xPosition': x, 'yPosition': y]).result
|
@@ -690,7 +713,7 @@ module SonyCameraRemoteAPI
|
|
690
713
|
source = getSourceList([{'scheme' => scheme}]).result[0][0]['source']
|
691
714
|
|
692
715
|
if date
|
693
|
-
date_found
|
716
|
+
date_found = get_date_list.find { |d| d['title'] == date }
|
694
717
|
if date_found
|
695
718
|
contents = get_content_list_sub date_found['uri'], type: type, view: 'date', sort: sort, count: count
|
696
719
|
else
|
@@ -702,19 +725,19 @@ module SonyCameraRemoteAPI
|
|
702
725
|
if type.present?
|
703
726
|
# if 'type' option is specified, call getContentList with date view for every date.
|
704
727
|
# this is because getContentList with flat view is extremely slow as a number of contents grows.
|
705
|
-
|
728
|
+
dates = get_date_list type: type, sort: sort
|
706
729
|
contents = []
|
707
730
|
if count.present?
|
708
|
-
|
709
|
-
num = [
|
731
|
+
dates.each do |date|
|
732
|
+
num = [date['contentCount'], count - contents.size].min
|
710
733
|
contents += get_content_list_sub date['uri'], type: type, view: 'date', sort: sort, count: num
|
711
734
|
break if contents.size >= count
|
712
735
|
end
|
713
736
|
# it is no problem that a number of contents is less than count
|
714
737
|
contents = contents[0, count]
|
715
738
|
else
|
716
|
-
|
717
|
-
contents += get_content_list_sub date['uri'], type: type, view: 'date', sort: sort, count:
|
739
|
+
dates.each do |date|
|
740
|
+
contents += get_content_list_sub date['uri'], type: type, view: 'date', sort: sort, count: date['contentCount']
|
718
741
|
end
|
719
742
|
end
|
720
743
|
else
|
@@ -733,22 +756,22 @@ module SonyCameraRemoteAPI
|
|
733
756
|
# @param [String] sort Same as 'sort' request parameter of getContentList API
|
734
757
|
# @param [Fixnum] date_count Number of dates to get.
|
735
758
|
# @param [Fixnum] content_count Number of contents to get
|
736
|
-
# @return [Array<
|
759
|
+
# @return [Array<Hash>] An array of dates in format of 'YYYYMMdd' and an array of number of contents of the associated date.
|
737
760
|
# @example
|
738
761
|
# # Initialize
|
739
762
|
# cam = SonyCameraRemoteAPI::Camera.new
|
740
763
|
# cam.change_function_to_transfer
|
741
764
|
#
|
742
|
-
# # Get all dates and
|
765
|
+
# # Get all dates and content counts of the associated date.
|
743
766
|
# dates = cam.get_date_list
|
744
|
-
# # Get 5 newest dates that contains
|
767
|
+
# # Get 5 newest dates that contains XAVC-S movie contents.
|
745
768
|
# dates = cam.get_date_list(type: 'movie_xavcs', date_count: 5)
|
746
|
-
# # Get
|
747
|
-
# dates = cam.get_date_list(type: 'still', content_count:
|
769
|
+
# # Get dates until the sum of still contents of each date exceeds 100.
|
770
|
+
# dates = cam.get_date_list(type: 'still', content_count: 100)
|
748
771
|
#
|
749
|
-
# dates.each do |date
|
750
|
-
# # Get date
|
751
|
-
# puts "#{date['
|
772
|
+
# dates.each do |date|
|
773
|
+
# puts "date: #{date['title']}" # Get date in the format 'YYYYMMdd'
|
774
|
+
# puts "count: #{date['contentCount']}" # Get content count
|
752
775
|
# # Get contents of each date
|
753
776
|
# contents = cam.get_content_list date: date['title']
|
754
777
|
# # Transfer contents
|
@@ -773,9 +796,12 @@ module SonyCameraRemoteAPI
|
|
773
796
|
dates.each do |d|
|
774
797
|
cnt = getContentCount([{'uri' => d['uri'], 'type' => type, 'view' => 'date'}]).result[0]['count']
|
775
798
|
# Exclude days of 0 contents.
|
776
|
-
|
799
|
+
if cnt > 0
|
800
|
+
d['contentCount'] = cnt
|
801
|
+
filtered_dates << d
|
802
|
+
end
|
777
803
|
# Break if contents count exceeds.
|
778
|
-
break if content_count and filtered_dates.map { |d
|
804
|
+
break if content_count and filtered_dates.map { |d| d['contentCount'] }.inject(0, :+) > content_count
|
779
805
|
# Break if date count exceeds.
|
780
806
|
break if date_count and filtered_dates.size > date_count
|
781
807
|
end
|
@@ -784,7 +810,7 @@ module SonyCameraRemoteAPI
|
|
784
810
|
|
785
811
|
|
786
812
|
# Predefined transfer sizes
|
787
|
-
|
813
|
+
TRANSFER_SIZE_LIST = %w(original large small thumbnail).freeze
|
788
814
|
# Transfer content(s) from the camera storage.
|
789
815
|
# @note You have to set camera function to 'Contents Transfer' before calling this method.
|
790
816
|
# @param [Array<Hash>] contents Array of content information, which can be obtained by get_content_list
|
@@ -794,13 +820,15 @@ module SonyCameraRemoteAPI
|
|
794
820
|
# @see get_date_list
|
795
821
|
# @todo If 'contents' is directory (date), get all contents of the directory.
|
796
822
|
def transfer_contents(contents, filenames=[], dir: nil, size: 'original')
|
797
|
-
|
798
|
-
|
823
|
+
contents = [contents].compact unless contents.is_a? Array
|
824
|
+
filenames = [filenames].compact unless filenames.is_a? Array
|
825
|
+
size = [size].compact unless size.is_a? Array
|
826
|
+
unless size.map { |s| TRANSFER_SIZE_LIST.include? s }.all?
|
827
|
+
log.error "'size' argument contains invalid size name!"
|
828
|
+
log.error "Available sizes are: #{TRANSFER_SIZE_LIST}"
|
799
829
|
return nil
|
800
830
|
end
|
801
831
|
|
802
|
-
contents = [contents].compact unless contents.is_a? Array
|
803
|
-
filenames = [filenames].compact unless filenames.is_a? Array
|
804
832
|
if !filenames.empty?
|
805
833
|
if contents.size > filenames.size
|
806
834
|
log.warn 'Size of filename list is smaller than that of contents list!'
|
@@ -810,25 +838,12 @@ module SonyCameraRemoteAPI
|
|
810
838
|
end
|
811
839
|
end
|
812
840
|
|
813
|
-
urls_filenames = contents
|
814
|
-
|
815
|
-
|
816
|
-
|
817
|
-
when 'original'
|
818
|
-
raise StandardError if content['content']['original'].size > 1 # FIXME: When do we come here???
|
819
|
-
content['content']['original'][0]['url']
|
820
|
-
when 'large'
|
821
|
-
content['content']['largeUrl']
|
822
|
-
when 'small'
|
823
|
-
content['content']['smallUrl']
|
824
|
-
when 'thumbnail'
|
825
|
-
content['content']['thumbnailUrl']
|
826
|
-
end
|
827
|
-
filename ||= content['content']['original'][0]['fileName']
|
828
|
-
[url, filename]
|
841
|
+
urls_filenames = get_content_url(contents, filenames, size)
|
842
|
+
if urls_filenames.empty?
|
843
|
+
log.warn 'No contents to be transferred.'
|
844
|
+
return []
|
829
845
|
end
|
830
|
-
|
831
|
-
log.info "#{contents.size} contents to be transferred."
|
846
|
+
log.info "#{urls_filenames.size} contents to be transferred."
|
832
847
|
transferred = transfer_contents_sub(urls_filenames, dir)
|
833
848
|
if transferred.size == urls_filenames.size
|
834
849
|
log.info 'All transfer completed.'
|
@@ -1113,6 +1128,47 @@ module SonyCameraRemoteAPI
|
|
1113
1128
|
end
|
1114
1129
|
|
1115
1130
|
|
1131
|
+
def get_content_url(contents, filenames, sizes)
|
1132
|
+
urls_filenames = []
|
1133
|
+
contents.zip(filenames).product(sizes).map { |e| e.flatten }.each do |content, filename, size|
|
1134
|
+
next unless content
|
1135
|
+
|
1136
|
+
filename ||= content['content']['original'][0]['fileName']
|
1137
|
+
base = File.basename filename, '.*'
|
1138
|
+
case size
|
1139
|
+
when 'original'
|
1140
|
+
raise StandardError if content['content']['original'].size > 1 # FIXME: When do we come here???
|
1141
|
+
url = content['content']['original'][0]['url']
|
1142
|
+
ext =
|
1143
|
+
case content['contentKind']
|
1144
|
+
when 'still'
|
1145
|
+
'.JPG'
|
1146
|
+
when 'movie_mp4'
|
1147
|
+
'.MP4'
|
1148
|
+
when 'movie_xavcs'
|
1149
|
+
'.MP4'
|
1150
|
+
end
|
1151
|
+
filename = "#{base}#{ext}"
|
1152
|
+
when 'large'
|
1153
|
+
url = content['content']['largeUrl']
|
1154
|
+
filename = "#{base}_large.JPG"
|
1155
|
+
when 'small'
|
1156
|
+
url = content['content']['smallUrl']
|
1157
|
+
filename = "#{base}_small.JPG"
|
1158
|
+
when 'thumbnail'
|
1159
|
+
url = content['content']['thumbnailUrl']
|
1160
|
+
filename = "#{base}_thumbnail.JPG"
|
1161
|
+
end
|
1162
|
+
if url.empty?
|
1163
|
+
log.error "Skipping empty URL for file: #{filename}, size: #{size}"
|
1164
|
+
else
|
1165
|
+
urls_filenames << [url, filename]
|
1166
|
+
end
|
1167
|
+
end
|
1168
|
+
urls_filenames
|
1169
|
+
end
|
1170
|
+
|
1171
|
+
|
1116
1172
|
# Try to run given block.
|
1117
1173
|
# If an error raised because of the Wi-Fi disconnection, try to reconnect and run the block again.
|
1118
1174
|
# If error still continues, give it up and raise the error.
|
@@ -1120,7 +1176,8 @@ module SonyCameraRemoteAPI
|
|
1120
1176
|
yield
|
1121
1177
|
rescue HTTPClient::BadResponseError, HTTPClient::TimeoutError, Errno::EHOSTUNREACH, Errno::ECONNREFUSED => e
|
1122
1178
|
retry_count ||= 0
|
1123
|
-
|
1179
|
+
retry_count += 1
|
1180
|
+
raise e if @reconnect_by.nil? || retry_count > num
|
1124
1181
|
log.error "#{e.class}: #{e.message}"
|
1125
1182
|
log.error 'The camera seems to be disconnected! Reconnecting...'
|
1126
1183
|
unless @reconnect_by.call
|
@@ -1138,7 +1195,6 @@ module SonyCameraRemoteAPI
|
|
1138
1195
|
raise e
|
1139
1196
|
end
|
1140
1197
|
end
|
1141
|
-
retry_count += 1
|
1142
1198
|
retry if retrying
|
1143
1199
|
end
|
1144
1200
|
|
@@ -9,7 +9,7 @@ Gem::Specification.new do |spec|
|
|
9
9
|
spec.authors = ["kota65535"]
|
10
10
|
spec.email = ["kota65535@gmail.com"]
|
11
11
|
|
12
|
-
spec.summary = %q{A Ruby Gem that facilitates the use of Sony Remote
|
12
|
+
spec.summary = %q{A Ruby Gem that facilitates the use of Sony Camera Remote API.}
|
13
13
|
# spec.description = %q{A Ruby Gem that facilitates the use of Sony Remote Camera API.}
|
14
14
|
spec.homepage = "https://github.com/kota65535/sony_camera_remote_api"
|
15
15
|
spec.license = "MIT"
|
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.2.
|
4
|
+
version: 0.2.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- kota65535
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-
|
11
|
+
date: 2016-10-01 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -227,5 +227,5 @@ rubyforge_project:
|
|
227
227
|
rubygems_version: 2.4.5.1
|
228
228
|
signing_key:
|
229
229
|
specification_version: 4
|
230
|
-
summary: A Ruby Gem that facilitates the use of Sony Remote
|
230
|
+
summary: A Ruby Gem that facilitates the use of Sony Camera Remote API.
|
231
231
|
test_files: []
|