sony_camera_remote_api 0.2.1 → 0.2.2
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/.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: []
|