airplay 0.2.4 → 0.2.5
Sign up to get free protection for your applications and to get access to all the features.
- data/airplay.gemspec +2 -1
- data/examples/jobs.jpg +0 -0
- data/examples/send_image.rb +5 -0
- data/examples/send_video.rb +7 -0
- data/lib/airplay.rb +2 -1
- data/lib/airplay/protocol.rb +7 -6
- data/test/fixtures/cassettes/airplay/authenticate_all_the_things_.yml +36 -16
- data/test/fixtures/cassettes/airplay/control_a_video_being_played_in_apple_tv.yml +48 -16
- data/test/fixtures/cassettes/airplay/get_current_scrub_from_apple_tv.yml +12 -4
- data/test/fixtures/cassettes/airplay/go_to_a_given_position_in_the_video.yml +30 -10
- data/test/fixtures/cassettes/airplay/send_audio_to_apple_tv.yml +6 -2
- data/test/fixtures/cassettes/airplay/send_image_to_apple_tv.yml +399 -1171
- data/test/fixtures/cassettes/airplay/send_image_to_apple_tv_with_effects.yml +24 -8
- data/test/fixtures/cassettes/airplay/send_video_to_apple_tv.yml +6 -22
- data/test/helper.rb +1 -1
- data/test/images.rb +1 -1
- metadata +28 -14
data/airplay.gemspec
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
Gem::Specification.new do |s|
|
2
2
|
s.name = "airplay"
|
3
|
-
s.version = "0.2.
|
3
|
+
s.version = "0.2.5"
|
4
4
|
s.summary = "Airplay client"
|
5
5
|
s.description = "Send image/video to an airplay enabled device"
|
6
6
|
s.authors = ["elcuervo"]
|
@@ -10,6 +10,7 @@ Gem::Specification.new do |s|
|
|
10
10
|
s.test_files = `git ls-files spec`.split("\n")
|
11
11
|
|
12
12
|
s.add_dependency("dnssd")
|
13
|
+
s.add_dependency("net-http-persistent")
|
13
14
|
s.add_dependency("net-http-digest_auth")
|
14
15
|
|
15
16
|
s.add_development_dependency("cutest")
|
data/examples/jobs.jpg
ADDED
Binary file
|
data/lib/airplay.rb
CHANGED
data/lib/airplay/protocol.rb
CHANGED
@@ -1,27 +1,28 @@
|
|
1
1
|
class Airplay::Protocol
|
2
2
|
attr_reader :host, :resource, :request
|
3
3
|
|
4
|
-
DEFAULT_HEADERS = {"User-Agent" => "MediaControl/1.0"}
|
4
|
+
DEFAULT_HEADERS = { "User-Agent" => "MediaControl/1.0" }
|
5
5
|
SEARCH = '_airplay._tcp.'
|
6
6
|
PORT = 7000
|
7
7
|
|
8
8
|
def initialize(host, port, password)
|
9
|
+
@device = { :host => host, :port => port }
|
9
10
|
@password = password
|
10
|
-
@http = Net::HTTP.new
|
11
|
-
@http.
|
11
|
+
@http = Net::HTTP::Persistent.new
|
12
|
+
@http.debug_output = $stdout if ENV.has_key?('HTTP_DEBUG')
|
12
13
|
end
|
13
14
|
|
14
15
|
def make_request(request)
|
15
|
-
uri = URI.parse "http://#{@
|
16
|
+
uri = URI.parse "http://#{@device.fetch(:host)}:#{@device.fetch(:port)}#{request.path}"
|
16
17
|
uri.user = "Airplay"
|
17
18
|
uri.password = @password
|
18
19
|
|
19
|
-
response = @http.request(request)
|
20
|
+
response = @http.request(uri, request) {}
|
20
21
|
if response['www-authenticate']
|
21
22
|
digest_auth = Net::HTTP::DigestAuth.new
|
22
23
|
authentication = digest_auth.auth_header uri, response['www-authenticate'], request.method
|
23
24
|
request.add_field 'Authorization', authentication
|
24
|
-
response = @http.request(request)
|
25
|
+
response = @http.request(uri, request) {}
|
25
26
|
end
|
26
27
|
|
27
28
|
raise Airplay::Protocol::InvalidRequestError if response.code == "404"
|
@@ -2,49 +2,59 @@
|
|
2
2
|
- !ruby/struct:VCR::HTTPInteraction
|
3
3
|
request: !ruby/struct:VCR::Request
|
4
4
|
method: :get
|
5
|
-
uri: http://
|
5
|
+
uri: http://192.168.1.101:7000/scrub
|
6
6
|
body: !!null
|
7
7
|
headers:
|
8
8
|
user-agent:
|
9
9
|
- MediaControl/1.0
|
10
10
|
content-type:
|
11
11
|
- text/x-apple-plist+xml
|
12
|
+
connection:
|
13
|
+
- keep-alive
|
14
|
+
keep-alive:
|
15
|
+
- 30
|
12
16
|
response: !ruby/struct:VCR::Response
|
13
17
|
status: !ruby/struct:VCR::ResponseStatus
|
14
18
|
code: 401
|
15
19
|
message: Unauthorized
|
16
20
|
headers:
|
17
21
|
date:
|
18
|
-
-
|
22
|
+
- Thu, 13 Oct 2011 01:40:53 GMT
|
19
23
|
content-length:
|
20
24
|
- '0'
|
21
25
|
www-authenticate:
|
22
|
-
- Digest realm="AirPlay", nonce="
|
26
|
+
- Digest realm="AirPlay", nonce="MTMxODQ3MDA1MyCLYqeU6GyjP/SIKrzz9Xdl"
|
23
27
|
body: !!null
|
24
28
|
http_version: '1.1'
|
25
29
|
ignored: false
|
26
30
|
- !ruby/struct:VCR::HTTPInteraction
|
27
31
|
request: !ruby/struct:VCR::Request
|
28
32
|
method: :get
|
29
|
-
uri: http://
|
33
|
+
uri: http://192.168.1.101:7000/scrub
|
30
34
|
body: !!null
|
31
35
|
headers:
|
32
36
|
user-agent:
|
33
37
|
- MediaControl/1.0
|
34
38
|
content-type:
|
35
39
|
- text/x-apple-plist+xml
|
40
|
+
connection:
|
41
|
+
- keep-alive
|
42
|
+
- keep-alive
|
43
|
+
keep-alive:
|
44
|
+
- 30
|
45
|
+
- 30
|
36
46
|
host:
|
37
|
-
-
|
47
|
+
- 192.168.1.101:7000
|
38
48
|
authorization:
|
39
|
-
- Digest username="Airplay", realm="AirPlay", uri="/scrub", nonce="
|
40
|
-
nc=00000000, cnonce="
|
49
|
+
- Digest username="Airplay", realm="AirPlay", uri="/scrub", nonce="MTMxODQ3MDA1MyCLYqeU6GyjP/SIKrzz9Xdl",
|
50
|
+
nc=00000000, cnonce="7b5d7a15a148d48d3b262ba3cffce384", response="175d37f9dbf57f5f5935f0673e5e550f"
|
41
51
|
response: !ruby/struct:VCR::Response
|
42
52
|
status: !ruby/struct:VCR::ResponseStatus
|
43
53
|
code: 200
|
44
54
|
message: OK
|
45
55
|
headers:
|
46
56
|
date:
|
47
|
-
-
|
57
|
+
- Thu, 13 Oct 2011 01:40:53 GMT
|
48
58
|
content-type:
|
49
59
|
- text/parameters
|
50
60
|
content-length:
|
@@ -59,49 +69,59 @@
|
|
59
69
|
- !ruby/struct:VCR::HTTPInteraction
|
60
70
|
request: !ruby/struct:VCR::Request
|
61
71
|
method: :get
|
62
|
-
uri: http://
|
72
|
+
uri: http://192.168.1.101:7000/scrub
|
63
73
|
body: !!null
|
64
74
|
headers:
|
65
75
|
user-agent:
|
66
76
|
- MediaControl/1.0
|
67
77
|
content-type:
|
68
78
|
- text/x-apple-plist+xml
|
79
|
+
connection:
|
80
|
+
- keep-alive
|
81
|
+
keep-alive:
|
82
|
+
- 30
|
69
83
|
response: !ruby/struct:VCR::Response
|
70
84
|
status: !ruby/struct:VCR::ResponseStatus
|
71
85
|
code: 401
|
72
86
|
message: Unauthorized
|
73
87
|
headers:
|
74
88
|
date:
|
75
|
-
-
|
89
|
+
- Thu, 13 Oct 2011 01:40:53 GMT
|
76
90
|
content-length:
|
77
91
|
- '0'
|
78
92
|
www-authenticate:
|
79
|
-
- Digest realm="AirPlay", nonce="
|
93
|
+
- Digest realm="AirPlay", nonce="MTMxODQ3MDA1MyCLYqeU6GyjP/SIKrzz9Xdl"
|
80
94
|
body: !!null
|
81
95
|
http_version: '1.1'
|
82
96
|
ignored: false
|
83
97
|
- !ruby/struct:VCR::HTTPInteraction
|
84
98
|
request: !ruby/struct:VCR::Request
|
85
99
|
method: :get
|
86
|
-
uri: http://
|
100
|
+
uri: http://192.168.1.101:7000/scrub
|
87
101
|
body: !!null
|
88
102
|
headers:
|
89
103
|
user-agent:
|
90
104
|
- MediaControl/1.0
|
91
105
|
content-type:
|
92
106
|
- text/x-apple-plist+xml
|
107
|
+
connection:
|
108
|
+
- keep-alive
|
109
|
+
- keep-alive
|
110
|
+
keep-alive:
|
111
|
+
- 30
|
112
|
+
- 30
|
93
113
|
host:
|
94
|
-
-
|
114
|
+
- 192.168.1.101:7000
|
95
115
|
authorization:
|
96
|
-
- Digest username="Airplay", realm="AirPlay", uri="/scrub", nonce="
|
97
|
-
nc=00000000, cnonce="
|
116
|
+
- Digest username="Airplay", realm="AirPlay", uri="/scrub", nonce="MTMxODQ3MDA1MyCLYqeU6GyjP/SIKrzz9Xdl",
|
117
|
+
nc=00000000, cnonce="f86894f4489b02319259ca7b59a09214", response="175d37f9dbf57f5f5935f0673e5e550f"
|
98
118
|
response: !ruby/struct:VCR::Response
|
99
119
|
status: !ruby/struct:VCR::ResponseStatus
|
100
120
|
code: 200
|
101
121
|
message: OK
|
102
122
|
headers:
|
103
123
|
date:
|
104
|
-
-
|
124
|
+
- Thu, 13 Oct 2011 01:40:53 GMT
|
105
125
|
content-type:
|
106
126
|
- text/parameters
|
107
127
|
content-length:
|
@@ -2,7 +2,7 @@
|
|
2
2
|
- !ruby/struct:VCR::HTTPInteraction
|
3
3
|
request: !ruby/struct:VCR::Request
|
4
4
|
method: :post
|
5
|
-
uri: http://
|
5
|
+
uri: http://192.168.1.101:7000/play
|
6
6
|
body: ! 'Content-Location: http://www.yo-yo.org/mp4/yu.mp4
|
7
7
|
|
8
8
|
Start-Position: 0
|
@@ -11,13 +11,17 @@
|
|
11
11
|
headers:
|
12
12
|
user-agent:
|
13
13
|
- MediaControl/1.0
|
14
|
+
connection:
|
15
|
+
- keep-alive
|
16
|
+
keep-alive:
|
17
|
+
- 30
|
14
18
|
response: !ruby/struct:VCR::Response
|
15
19
|
status: !ruby/struct:VCR::ResponseStatus
|
16
20
|
code: 200
|
17
21
|
message: OK
|
18
22
|
headers:
|
19
23
|
date:
|
20
|
-
- Thu,
|
24
|
+
- Thu, 13 Oct 2011 01:39:12 GMT
|
21
25
|
content-length:
|
22
26
|
- '0'
|
23
27
|
body: !!null
|
@@ -26,18 +30,22 @@
|
|
26
30
|
- !ruby/struct:VCR::HTTPInteraction
|
27
31
|
request: !ruby/struct:VCR::Request
|
28
32
|
method: :post
|
29
|
-
uri: http://
|
33
|
+
uri: http://192.168.1.101:7000/rate?value=0
|
30
34
|
body: !!null
|
31
35
|
headers:
|
32
36
|
user-agent:
|
33
37
|
- MediaControl/1.0
|
38
|
+
connection:
|
39
|
+
- keep-alive
|
40
|
+
keep-alive:
|
41
|
+
- 30
|
34
42
|
response: !ruby/struct:VCR::Response
|
35
43
|
status: !ruby/struct:VCR::ResponseStatus
|
36
44
|
code: 200
|
37
45
|
message: OK
|
38
46
|
headers:
|
39
47
|
date:
|
40
|
-
- Thu,
|
48
|
+
- Thu, 13 Oct 2011 01:39:12 GMT
|
41
49
|
content-length:
|
42
50
|
- '0'
|
43
51
|
body: !!null
|
@@ -46,18 +54,22 @@
|
|
46
54
|
- !ruby/struct:VCR::HTTPInteraction
|
47
55
|
request: !ruby/struct:VCR::Request
|
48
56
|
method: :post
|
49
|
-
uri: http://
|
57
|
+
uri: http://192.168.1.101:7000/rate?value=1
|
50
58
|
body: !!null
|
51
59
|
headers:
|
52
60
|
user-agent:
|
53
61
|
- MediaControl/1.0
|
62
|
+
connection:
|
63
|
+
- keep-alive
|
64
|
+
keep-alive:
|
65
|
+
- 30
|
54
66
|
response: !ruby/struct:VCR::Response
|
55
67
|
status: !ruby/struct:VCR::ResponseStatus
|
56
68
|
code: 200
|
57
69
|
message: OK
|
58
70
|
headers:
|
59
71
|
date:
|
60
|
-
- Thu,
|
72
|
+
- Thu, 13 Oct 2011 01:39:12 GMT
|
61
73
|
content-length:
|
62
74
|
- '0'
|
63
75
|
body: !!null
|
@@ -66,20 +78,24 @@
|
|
66
78
|
- !ruby/struct:VCR::HTTPInteraction
|
67
79
|
request: !ruby/struct:VCR::Request
|
68
80
|
method: :get
|
69
|
-
uri: http://
|
81
|
+
uri: http://192.168.1.101:7000/scrub
|
70
82
|
body: !!null
|
71
83
|
headers:
|
72
84
|
user-agent:
|
73
85
|
- MediaControl/1.0
|
74
86
|
content-type:
|
75
87
|
- text/x-apple-plist+xml
|
88
|
+
connection:
|
89
|
+
- keep-alive
|
90
|
+
keep-alive:
|
91
|
+
- 30
|
76
92
|
response: !ruby/struct:VCR::Response
|
77
93
|
status: !ruby/struct:VCR::ResponseStatus
|
78
94
|
code: 200
|
79
95
|
message: OK
|
80
96
|
headers:
|
81
97
|
date:
|
82
|
-
- Thu,
|
98
|
+
- Thu, 13 Oct 2011 01:39:12 GMT
|
83
99
|
content-type:
|
84
100
|
- text/parameters
|
85
101
|
content-length:
|
@@ -94,20 +110,24 @@
|
|
94
110
|
- !ruby/struct:VCR::HTTPInteraction
|
95
111
|
request: !ruby/struct:VCR::Request
|
96
112
|
method: :get
|
97
|
-
uri: http://
|
113
|
+
uri: http://192.168.1.101:7000/scrub
|
98
114
|
body: !!null
|
99
115
|
headers:
|
100
116
|
user-agent:
|
101
117
|
- MediaControl/1.0
|
102
118
|
content-type:
|
103
119
|
- text/x-apple-plist+xml
|
120
|
+
connection:
|
121
|
+
- keep-alive
|
122
|
+
keep-alive:
|
123
|
+
- 30
|
104
124
|
response: !ruby/struct:VCR::Response
|
105
125
|
status: !ruby/struct:VCR::ResponseStatus
|
106
126
|
code: 200
|
107
127
|
message: OK
|
108
128
|
headers:
|
109
129
|
date:
|
110
|
-
- Thu,
|
130
|
+
- Thu, 13 Oct 2011 01:39:12 GMT
|
111
131
|
content-type:
|
112
132
|
- text/parameters
|
113
133
|
content-length:
|
@@ -122,20 +142,24 @@
|
|
122
142
|
- !ruby/struct:VCR::HTTPInteraction
|
123
143
|
request: !ruby/struct:VCR::Request
|
124
144
|
method: :get
|
125
|
-
uri: http://
|
145
|
+
uri: http://192.168.1.101:7000/scrub
|
126
146
|
body: !!null
|
127
147
|
headers:
|
128
148
|
user-agent:
|
129
149
|
- MediaControl/1.0
|
130
150
|
content-type:
|
131
151
|
- text/x-apple-plist+xml
|
152
|
+
connection:
|
153
|
+
- keep-alive
|
154
|
+
keep-alive:
|
155
|
+
- 30
|
132
156
|
response: !ruby/struct:VCR::Response
|
133
157
|
status: !ruby/struct:VCR::ResponseStatus
|
134
158
|
code: 200
|
135
159
|
message: OK
|
136
160
|
headers:
|
137
161
|
date:
|
138
|
-
- Thu,
|
162
|
+
- Thu, 13 Oct 2011 01:39:12 GMT
|
139
163
|
content-type:
|
140
164
|
- text/parameters
|
141
165
|
content-length:
|
@@ -150,18 +174,22 @@
|
|
150
174
|
- !ruby/struct:VCR::HTTPInteraction
|
151
175
|
request: !ruby/struct:VCR::Request
|
152
176
|
method: :post
|
153
|
-
uri: http://
|
177
|
+
uri: http://192.168.1.101:7000/scrub?position=0
|
154
178
|
body: !!null
|
155
179
|
headers:
|
156
180
|
user-agent:
|
157
181
|
- MediaControl/1.0
|
182
|
+
connection:
|
183
|
+
- keep-alive
|
184
|
+
keep-alive:
|
185
|
+
- 30
|
158
186
|
response: !ruby/struct:VCR::Response
|
159
187
|
status: !ruby/struct:VCR::ResponseStatus
|
160
188
|
code: 200
|
161
189
|
message: OK
|
162
190
|
headers:
|
163
191
|
date:
|
164
|
-
- Thu,
|
192
|
+
- Thu, 13 Oct 2011 01:39:12 GMT
|
165
193
|
content-length:
|
166
194
|
- '0'
|
167
195
|
body: !!null
|
@@ -170,18 +198,22 @@
|
|
170
198
|
- !ruby/struct:VCR::HTTPInteraction
|
171
199
|
request: !ruby/struct:VCR::Request
|
172
200
|
method: :post
|
173
|
-
uri: http://
|
201
|
+
uri: http://192.168.1.101:7000/stop
|
174
202
|
body: !!null
|
175
203
|
headers:
|
176
204
|
user-agent:
|
177
205
|
- MediaControl/1.0
|
206
|
+
connection:
|
207
|
+
- keep-alive
|
208
|
+
keep-alive:
|
209
|
+
- 30
|
178
210
|
response: !ruby/struct:VCR::Response
|
179
211
|
status: !ruby/struct:VCR::ResponseStatus
|
180
212
|
code: 200
|
181
213
|
message: OK
|
182
214
|
headers:
|
183
215
|
date:
|
184
|
-
- Thu,
|
216
|
+
- Thu, 13 Oct 2011 01:39:12 GMT
|
185
217
|
content-length:
|
186
218
|
- '0'
|
187
219
|
body: !!null
|
@@ -2,20 +2,24 @@
|
|
2
2
|
- !ruby/struct:VCR::HTTPInteraction
|
3
3
|
request: !ruby/struct:VCR::Request
|
4
4
|
method: :get
|
5
|
-
uri: http://
|
5
|
+
uri: http://192.168.1.101:7000/scrub
|
6
6
|
body: !!null
|
7
7
|
headers:
|
8
8
|
user-agent:
|
9
9
|
- MediaControl/1.0
|
10
10
|
content-type:
|
11
11
|
- text/x-apple-plist+xml
|
12
|
+
connection:
|
13
|
+
- keep-alive
|
14
|
+
keep-alive:
|
15
|
+
- 30
|
12
16
|
response: !ruby/struct:VCR::Response
|
13
17
|
status: !ruby/struct:VCR::ResponseStatus
|
14
18
|
code: 200
|
15
19
|
message: OK
|
16
20
|
headers:
|
17
21
|
date:
|
18
|
-
-
|
22
|
+
- Thu, 13 Oct 2011 01:39:13 GMT
|
19
23
|
content-type:
|
20
24
|
- text/parameters
|
21
25
|
content-length:
|
@@ -30,20 +34,24 @@
|
|
30
34
|
- !ruby/struct:VCR::HTTPInteraction
|
31
35
|
request: !ruby/struct:VCR::Request
|
32
36
|
method: :get
|
33
|
-
uri: http://
|
37
|
+
uri: http://192.168.1.101:7000/scrub
|
34
38
|
body: !!null
|
35
39
|
headers:
|
36
40
|
user-agent:
|
37
41
|
- MediaControl/1.0
|
38
42
|
content-type:
|
39
43
|
- text/x-apple-plist+xml
|
44
|
+
connection:
|
45
|
+
- keep-alive
|
46
|
+
keep-alive:
|
47
|
+
- 30
|
40
48
|
response: !ruby/struct:VCR::Response
|
41
49
|
status: !ruby/struct:VCR::ResponseStatus
|
42
50
|
code: 200
|
43
51
|
message: OK
|
44
52
|
headers:
|
45
53
|
date:
|
46
|
-
-
|
54
|
+
- Thu, 13 Oct 2011 01:39:13 GMT
|
47
55
|
content-type:
|
48
56
|
- text/parameters
|
49
57
|
content-length:
|