airplay 0.1
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.
- data/lib/airplay.rb +10 -0
- data/lib/airplay/client.rb +44 -0
- data/lib/airplay/node.rb +7 -0
- data/lib/airplay/protocol.rb +34 -0
- data/lib/airplay/protocol/image.rb +24 -0
- data/lib/airplay/protocol/video.rb +24 -0
- data/lib/airplay/version.rb +3 -0
- metadata +93 -0
data/lib/airplay.rb
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
class Airplay::Client
|
|
2
|
+
attr_reader :servers, :active_server
|
|
3
|
+
|
|
4
|
+
def initialize(server = false)
|
|
5
|
+
browse unless server
|
|
6
|
+
use servers.first if servers.size == 1
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def use(server)
|
|
10
|
+
@active_server = server.is_a?(Airplay::Node) ? server : find_by_name(server)
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def find_by_name(name)
|
|
14
|
+
found_server = @servers.detect do |server|
|
|
15
|
+
server if server.name == name
|
|
16
|
+
end
|
|
17
|
+
raise Airplay::Client::ServerNotFoundError unless found_server
|
|
18
|
+
found_server
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def browse
|
|
22
|
+
@servers = []
|
|
23
|
+
DNSSD.browse!(Airplay::Protocol::SEARCH) do |reply|
|
|
24
|
+
resolver = DNSSD::Service.new
|
|
25
|
+
target = nil
|
|
26
|
+
resolver.resolve(reply) do |resolved|
|
|
27
|
+
target = resolved.target
|
|
28
|
+
break unless resolved.flags.more_coming?
|
|
29
|
+
end
|
|
30
|
+
info = Socket.getaddrinfo(target, nil, Socket::AF_INET)
|
|
31
|
+
ip_address = info[0][2]
|
|
32
|
+
@servers << Airplay::Node.new(reply.name, reply.domain, ip_address)
|
|
33
|
+
break unless reply.flags.more_coming?
|
|
34
|
+
end
|
|
35
|
+
@servers
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def send_image(image, transition = :none)
|
|
39
|
+
Airplay::Protocol::Image.new(@active_server.ip).send(image, transition)
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
class Airplay::Client::ServerNotFoundError < StandardError; end;
|
data/lib/airplay/node.rb
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
class Airplay::Protocol
|
|
2
|
+
attr_reader :host, :resource, :request
|
|
3
|
+
|
|
4
|
+
DEFAULT_HEADERS = {"User-Agent" => "MediaControl/1.0"}
|
|
5
|
+
SEARCH = '_airplay._tcp.'
|
|
6
|
+
PORT = 7000
|
|
7
|
+
|
|
8
|
+
def initialize(host, port = PORT)
|
|
9
|
+
@http = Net::HTTP.new(host, port)
|
|
10
|
+
@http.set_debug_output($stdout) if ENV.has_key?('HTTP_DEBUG')
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def make_request(request)
|
|
14
|
+
response = @http.request(@request)
|
|
15
|
+
raise Airplay::Protocol::InvalidRequestError if response.code == 404
|
|
16
|
+
true
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def put(resource, body = nil, headers = {})
|
|
20
|
+
@request = Net::HTTP::Put.new resource
|
|
21
|
+
@request.body = body
|
|
22
|
+
@request.initialize_http_header DEFAULT_HEADERS.merge(headers)
|
|
23
|
+
make_request(@request)
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def get(resource, headers = {})
|
|
27
|
+
@request = Net::HTTP::Get.new resource
|
|
28
|
+
@request.initialize_http_header DEFAULT_HEADERS.merge(headers)
|
|
29
|
+
make_request(@request)
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
class Airplay::Protocol::InvalidRequestError < StandardError; end
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
class Airplay::Protocol::Image < Airplay::Protocol
|
|
2
|
+
|
|
3
|
+
def resource
|
|
4
|
+
"/photos"
|
|
5
|
+
end
|
|
6
|
+
|
|
7
|
+
def transitions
|
|
8
|
+
{
|
|
9
|
+
none: "None",
|
|
10
|
+
dissolve: "Dissolve"
|
|
11
|
+
}
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def transition_header(transition)
|
|
16
|
+
{"X-Apple-Transition" => transitions.fetch(transition)}
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def send(image, transition = :none)
|
|
20
|
+
body = File.exists?(image) ? File.read(image) : image
|
|
21
|
+
put(resource, body, transition_header(transition))
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
end
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
class Airplay::Protocol::Video < Airplay::Protocol
|
|
2
|
+
|
|
3
|
+
def resource
|
|
4
|
+
"/play"
|
|
5
|
+
end
|
|
6
|
+
|
|
7
|
+
def send(video)
|
|
8
|
+
# TODO: serve local file
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def play
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def pause
|
|
15
|
+
# TODO: know how to pause video
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def stop
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def scrub
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: airplay
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
prerelease:
|
|
5
|
+
version: "0.1"
|
|
6
|
+
platform: ruby
|
|
7
|
+
authors:
|
|
8
|
+
- elcuervo
|
|
9
|
+
autorequire:
|
|
10
|
+
bindir: bin
|
|
11
|
+
cert_chain: []
|
|
12
|
+
|
|
13
|
+
date: 2011-07-05 00:00:00 Z
|
|
14
|
+
dependencies:
|
|
15
|
+
- !ruby/object:Gem::Dependency
|
|
16
|
+
name: dnssd
|
|
17
|
+
prerelease: false
|
|
18
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
|
19
|
+
none: false
|
|
20
|
+
requirements:
|
|
21
|
+
- - ">="
|
|
22
|
+
- !ruby/object:Gem::Version
|
|
23
|
+
version: "0"
|
|
24
|
+
type: :runtime
|
|
25
|
+
version_requirements: *id001
|
|
26
|
+
- !ruby/object:Gem::Dependency
|
|
27
|
+
name: cutest
|
|
28
|
+
prerelease: false
|
|
29
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
|
30
|
+
none: false
|
|
31
|
+
requirements:
|
|
32
|
+
- - ">="
|
|
33
|
+
- !ruby/object:Gem::Version
|
|
34
|
+
version: "0"
|
|
35
|
+
type: :development
|
|
36
|
+
version_requirements: *id002
|
|
37
|
+
- !ruby/object:Gem::Dependency
|
|
38
|
+
name: capybara
|
|
39
|
+
prerelease: false
|
|
40
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
|
41
|
+
none: false
|
|
42
|
+
requirements:
|
|
43
|
+
- - ">="
|
|
44
|
+
- !ruby/object:Gem::Version
|
|
45
|
+
version: "0"
|
|
46
|
+
type: :development
|
|
47
|
+
version_requirements: *id003
|
|
48
|
+
description: Send image/video to an airplay enabled device
|
|
49
|
+
email:
|
|
50
|
+
- yo@brunoaguirre.com
|
|
51
|
+
executables: []
|
|
52
|
+
|
|
53
|
+
extensions: []
|
|
54
|
+
|
|
55
|
+
extra_rdoc_files: []
|
|
56
|
+
|
|
57
|
+
files:
|
|
58
|
+
- lib/airplay/client.rb
|
|
59
|
+
- lib/airplay/node.rb
|
|
60
|
+
- lib/airplay/protocol/image.rb
|
|
61
|
+
- lib/airplay/protocol/video.rb
|
|
62
|
+
- lib/airplay/protocol.rb
|
|
63
|
+
- lib/airplay/version.rb
|
|
64
|
+
- lib/airplay.rb
|
|
65
|
+
homepage: http://github.com/elcuervo/airplay
|
|
66
|
+
licenses: []
|
|
67
|
+
|
|
68
|
+
post_install_message:
|
|
69
|
+
rdoc_options: []
|
|
70
|
+
|
|
71
|
+
require_paths:
|
|
72
|
+
- lib
|
|
73
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
74
|
+
none: false
|
|
75
|
+
requirements:
|
|
76
|
+
- - ">="
|
|
77
|
+
- !ruby/object:Gem::Version
|
|
78
|
+
version: "0"
|
|
79
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
80
|
+
none: false
|
|
81
|
+
requirements:
|
|
82
|
+
- - ">="
|
|
83
|
+
- !ruby/object:Gem::Version
|
|
84
|
+
version: "0"
|
|
85
|
+
requirements: []
|
|
86
|
+
|
|
87
|
+
rubyforge_project:
|
|
88
|
+
rubygems_version: 1.7.2
|
|
89
|
+
signing_key:
|
|
90
|
+
specification_version: 3
|
|
91
|
+
summary: Airplay client
|
|
92
|
+
test_files: []
|
|
93
|
+
|