airplay 0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,10 @@
1
+ require 'dnssd'
2
+ require 'net/http'
3
+ require 'uri'
4
+
5
+ require 'airplay/version'
6
+ require 'airplay/protocol'
7
+ require 'airplay/protocol/image'
8
+ require 'airplay/protocol/video'
9
+ require 'airplay/node'
10
+ require 'airplay/client'
@@ -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;
@@ -0,0 +1,7 @@
1
+ class Airplay::Node
2
+ attr_reader :name, :domain, :ip
3
+
4
+ def initialize(name, domain, ip)
5
+ @name, @domain, @ip = name, domain, ip
6
+ end
7
+ end
@@ -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
@@ -0,0 +1,3 @@
1
+ module Airplay
2
+ VERSION = 0.1
3
+ 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
+