airplay 0.2.9 → 1.0.0.beta1

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.
Files changed (82) hide show
  1. data/Gemfile +5 -0
  2. data/Gemfile.lock +68 -0
  3. data/HUGS +15 -0
  4. data/LICENSE +20 -0
  5. data/README.md +50 -72
  6. data/Rakefile +6 -9
  7. data/SPEC.md +34 -0
  8. data/airplay.gemspec +28 -16
  9. data/bin/air +27 -0
  10. data/examples/demo.rb +35 -0
  11. data/examples/image.rb +9 -0
  12. data/examples/video.rb +24 -0
  13. data/lib/airplay.rb +38 -17
  14. data/lib/airplay/browser.rb +68 -0
  15. data/lib/airplay/cli.rb +104 -0
  16. data/lib/airplay/configuration.rb +29 -0
  17. data/lib/airplay/connection.rb +114 -0
  18. data/lib/airplay/connection/authentication.rb +37 -0
  19. data/lib/airplay/connection/persistent.rb +44 -0
  20. data/lib/airplay/device.rb +81 -0
  21. data/lib/airplay/device/features.rb +43 -0
  22. data/lib/airplay/device/info.rb +22 -0
  23. data/lib/airplay/devices.rb +46 -0
  24. data/lib/airplay/logger.rb +20 -0
  25. data/lib/airplay/playable.rb +24 -0
  26. data/lib/airplay/protocol.rb +9 -72
  27. data/lib/airplay/protocol/app.rb +52 -0
  28. data/lib/airplay/protocol/message.rb +8 -0
  29. data/lib/airplay/protocol/playback_info.rb +49 -0
  30. data/lib/airplay/protocol/player.rb +170 -0
  31. data/lib/airplay/protocol/reverse.rb +69 -0
  32. data/lib/airplay/protocol/slideshow.rb +66 -0
  33. data/lib/airplay/protocol/timers.rb +25 -0
  34. data/lib/airplay/protocol/viewer.rb +56 -0
  35. data/lib/airplay/structure.rb +7 -0
  36. data/lib/airplay/viewable.rb +16 -0
  37. data/test/fixtures/cassettes/airplay/listing_slideshow_features.yml +201 -0
  38. data/test/fixtures/cassettes/airplay/play_an_entire_video.yml +100 -0
  39. data/test/fixtures/cassettes/airplay/sending_a_video.yml +71 -0
  40. data/test/fixtures/cassettes/airplay/sending_an_image.yml +26439 -0
  41. data/test/fixtures/cassettes/airplay/stop_any_transmission.yml +8851 -0
  42. data/test/fixtures/files/logo.png +0 -0
  43. data/test/fixtures/files/transition_0.png +0 -0
  44. data/test/fixtures/files/transition_1.png +0 -0
  45. data/test/fixtures/files/transition_2.png +0 -0
  46. data/test/fixtures/files/transition_3.png +0 -0
  47. data/test/integration/discovery_test.rb +13 -0
  48. data/test/integration/features_test.rb +14 -0
  49. data/test/integration/send_media_test.rb +37 -0
  50. data/test/integration/slideshow_test.rb +26 -0
  51. data/test/test_helper.rb +42 -0
  52. data/test/unit/node_test.rb +17 -0
  53. data/test/unit/protocol_test.rb +44 -0
  54. metadata +247 -77
  55. data/.gitignore +0 -2
  56. data/.travis.yml +0 -6
  57. data/examples/jobs.jpg +0 -0
  58. data/examples/send_image.rb +0 -5
  59. data/examples/send_video.rb +0 -7
  60. data/lib/airplay/client.rb +0 -60
  61. data/lib/airplay/protocol/image.rb +0 -41
  62. data/lib/airplay/protocol/media.rb +0 -64
  63. data/lib/airplay/protocol/scrub.rb +0 -37
  64. data/lib/airplay/server.rb +0 -2
  65. data/lib/airplay/server/browser.rb +0 -35
  66. data/lib/airplay/server/node.rb +0 -7
  67. data/test/authentication.rb +0 -13
  68. data/test/discovery.rb +0 -27
  69. data/test/fixtures/cassettes/airplay/authenticate_all_the_things_.yml +0 -139
  70. data/test/fixtures/cassettes/airplay/control_a_video_being_played_in_apple_tv.yml +0 -242
  71. data/test/fixtures/cassettes/airplay/get_current_scrub_from_apple_tv.yml +0 -69
  72. data/test/fixtures/cassettes/airplay/go_to_a_given_position_in_the_video.yml +0 -157
  73. data/test/fixtures/cassettes/airplay/send_audio_to_apple_tv.yml +0 -33
  74. data/test/fixtures/cassettes/airplay/send_image_to_apple_tv.yml +0 -661
  75. data/test/fixtures/cassettes/airplay/send_image_to_apple_tv_with_effects.yml +0 -591
  76. data/test/fixtures/cassettes/airplay/send_video_to_apple_tv.yml +0 -33
  77. data/test/fixtures/image.gif +0 -0
  78. data/test/fixtures/image2.gif +0 -0
  79. data/test/helper.rb +0 -31
  80. data/test/images.rb +0 -31
  81. data/test/media.rb +0 -47
  82. data/test/scrub.rb +0 -31
data/Gemfile CHANGED
@@ -1,4 +1,9 @@
1
1
  source "http://rubygems.org"
2
2
 
3
3
  gemspec
4
+
4
5
  gem "rake"
6
+
7
+ group :development do
8
+ gem "debugger"
9
+ end
data/Gemfile.lock ADDED
@@ -0,0 +1,68 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ airplay (1.0.0.beta1)
5
+ CFPropertyList (~> 2.2.0)
6
+ celluloid (~> 0.15.0)
7
+ clap (~> 1.0.0)
8
+ cuba (~> 3.1.0)
9
+ dnssd (~> 2.0)
10
+ log4r (~> 1.1.10)
11
+ micromachine (~> 1.0.4)
12
+ net-http-digest_auth (~> 1.2.1)
13
+ net-ptth (~> 0.0.10)
14
+ ruby-progressbar (~> 1.2.0)
15
+ uuid (~> 2.3.6)
16
+
17
+ GEM
18
+ remote: http://rubygems.org/
19
+ specs:
20
+ CFPropertyList (2.2.3)
21
+ celluloid (0.15.1)
22
+ timers (~> 1.1.0)
23
+ celluloid-io (0.15.0)
24
+ celluloid (>= 0.15.0)
25
+ nio4r (>= 0.5.0)
26
+ clap (1.0.0)
27
+ columnize (0.3.6)
28
+ cuba (3.1.0)
29
+ rack
30
+ debugger (1.6.2)
31
+ columnize (>= 0.3.1)
32
+ debugger-linecache (~> 1.2.0)
33
+ debugger-ruby_core_source (~> 1.2.3)
34
+ debugger-linecache (1.2.0)
35
+ debugger-ruby_core_source (1.2.3)
36
+ dnssd (2.0)
37
+ fakeweb (1.3.0)
38
+ http_parser.rb (0.5.3)
39
+ log4r (1.1.10)
40
+ macaddr (1.6.1)
41
+ systemu (~> 2.5.0)
42
+ micromachine (1.0.4)
43
+ minitest (4.4.0)
44
+ net-http-digest_auth (1.2.1)
45
+ net-ptth (0.0.10)
46
+ celluloid-io (~> 0.15.0)
47
+ http_parser.rb (~> 0.5.3)
48
+ rack (~> 1.4.5)
49
+ nio4r (0.5.0)
50
+ rack (1.4.5)
51
+ rake (10.1.0)
52
+ ruby-progressbar (1.2.0)
53
+ systemu (2.5.2)
54
+ timers (1.1.0)
55
+ uuid (2.3.7)
56
+ macaddr (~> 1.0)
57
+ vcr (2.4.0)
58
+
59
+ PLATFORMS
60
+ ruby
61
+
62
+ DEPENDENCIES
63
+ airplay!
64
+ debugger
65
+ fakeweb (~> 1.3.0)
66
+ minitest (~> 4.4.0)
67
+ rake
68
+ vcr (~> 2.4.0)
data/HUGS ADDED
@@ -0,0 +1,15 @@
1
+ THE HUGWARE LICENSE
2
+
3
+ LICENSE
4
+
5
+ If there is no other license you can do whatever you want with this while you
6
+ retain the attribution to the author.
7
+
8
+ HUGS
9
+
10
+ The author spent time to make this software so please show some gratitude,
11
+ in any
12
+ form. A hug, a tweet, a beer on a conference or just a plain old email. Your
13
+ choice.
14
+
15
+ Less hate, more hugs.
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2013 Bruno Aguirre
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md CHANGED
@@ -1,111 +1,89 @@
1
1
  # Airplay
2
+ [![Code Climate](https://codeclimate.com/github/elcuervo/airplay.png)](https://codeclimate.com/github/elcuervo/airplay)
2
3
 
3
- ![Travis](https://secure.travis-ci.org/elcuervo/airplay.png)
4
+ ![Airplay](test/fixtures/files/logo.png)
4
5
 
5
- ![Ruby Airplay](http://elcuervo.co/images/posts/airplay/ruby_airplay.png?1)
6
+ Airplay attempts to be compatible with the latest AppleTV firmware but I'd like
7
+ to add compatibility to other servers.
6
8
 
7
- A client (and someday a server) of the superfancy http content stream technique
8
- that Apple uses in its products.
9
+ ## Installation
9
10
 
10
- Now supports any Airplay-compatible device, like [Airserver](http://www.airserverapp.com/)
11
+ `gem install airplay`
11
12
 
12
- You can try this in an AppleTV for instance.
13
+ ## CLI
13
14
 
14
- ## IMPORTANT!
15
+ ### View devices
15
16
 
16
- Since iOS 5 there are some changes in the API so to keep playing something (like
17
- a video) you must keep the client alive!
18
-
19
- ## Basic Usage
20
-
21
- ```ruby
22
- require 'airplay'
17
+ `air list`
18
+ ```text
19
+ * Apple TV (AppleTV2,1 running 11A502)
20
+ ip: 192.168.1.12
21
+ resolution: 1280x720
22
+ ```
23
23
 
24
- airplay = Airplay::Client.new
25
- # To send an image
26
- airplay.send_image("fancy_pants.jpg")
24
+ ### Play a video
27
25
 
28
- # To stream a video
29
- airplay.send_video("http://www.yo-yo.org/mp4/yu2.mp4")
26
+ `air play [url to video]`
27
+ ```text
28
+ Playing http://movietrailers.apple.com/movies/universal/rush/rush-tlr3_480p.mov?width=848&height=352
29
+ Time: 00:00:13 [===== ] 7% Apple TV
30
30
  ```
31
31
 
32
- ## Sending images
33
-
34
- ```ruby
35
- require 'airplay'
32
+ ### Show images
36
33
 
37
- airplay = Airplay::Client.new
34
+ `air view [url to image or image folder]`
38
35
 
39
- airplay.send_image("fancy_pants.jpg")
40
- airplay.send_image(File.open("/home/userman/Pictures/fancy_pants.jpg"))
41
- airplay.send_image("http://mine.icanhascheezburger.com/completestore/Wezinyercupz128401525895963750.jpg")
42
- ```
36
+ ## Library
43
37
 
44
- ### Transitions
38
+ ### Finding devices
45
39
 
46
40
  ```ruby
47
- require 'airplay'
48
-
49
- airplay = Airplay::Client.new
41
+ require "airplay"
50
42
 
51
- airplay.send_image("fancy_pants.jpg", :dissolve)
52
- airplay.send_image("fancy_pants.jpg", :slide_left)
53
- airplay.send_image("fancy_pants.jpg", :slide_right)
43
+ Airplay.devices.each do |device|
44
+ puts device.name
45
+ end
54
46
  ```
55
47
 
56
- ## Scrub
48
+ ### Sending images
57
49
 
58
50
  ```ruby
59
- require 'airplay'
51
+ require "airplay"
60
52
 
61
- airplay = Airplay::Client.new
62
- airplay.scrub
63
- # {:duration => 189, :position => 50}
64
- airplay.scrub(30) # Media goes to 30s
65
- airplay.scrub("10%") # Media goes to the 10% of its duration
53
+ apple_tv = Airplay["Apple TV"]
54
+ apple_tv.view("my_image.png")
55
+ apple_tv.view("url_to_the_image", transition: "Dissolve")
56
+
57
+ # View all transitions
58
+ apple_tv.transitions
66
59
  ```
67
60
 
68
- ## Password Authentication
61
+ ### Playing video
69
62
 
70
63
  ```ruby
71
- require 'airplay'
64
+ require "airplay"
72
65
 
73
- airplay = Airplay::Client.new
74
- airplay.use "Apple TV"
75
- airplay.password "password"
66
+ apple_tv = Airplay["Apple TV"]
67
+ trailer = "http://movietrailers.apple.com/movies/dreamworks/needforspeed/needforspeed-tlr1xxzzs2_480p.mov"
76
68
 
77
- airplay.send_image("lolcatz.jpg")
78
- ```
69
+ player = apple_tv.play(trailer)
79
70
 
80
- ## Player
71
+ # Wait until the video is finished
72
+ player.wait
81
73
 
82
- ```ruby
83
- require 'airplay'
84
-
85
- airplay = Airplay::Client.new
86
- player = airplay.send_video("http://www.yo-yo.org/mp4/yu2.mp4")
74
+ # Actions
87
75
  player.pause
88
76
  player.resume
89
- player.scrub
90
- # {:duration => 189, :position => 50}
91
- player.scrub("50%") # Go to the half of the media
92
77
  player.stop
93
- ```
94
-
95
- ## Useful methods
96
-
97
- ```ruby
98
- require 'airplay'
78
+ player.scrub
99
79
 
100
- airplay = Airplay::Client.new
101
- airplay.browse
102
- #=> [#<Airplay::Node:0x007fbb5a83eb28 @name="elCuervo", @domain="local.", @ip="10.1.0.63">, #<Airplay::Node:0x007fbb5a83b0b8 @name="Apple TV", @domain="local.", @ip="10.1.0.220">]
103
- airplay.use "elCuervo"
104
- airplay.use "Apple TV"
80
+ # Access the playback time per second
81
+ player.progress -> progress {
82
+ puts "I'm viewing #{progress["position"]} of #{progress["duration"]}"
83
+ }
105
84
  ```
106
85
 
107
86
  ## Contributors
108
87
 
109
- Thanks to all the contributors:
110
-
111
- * File handler support when sending an image. By [pote](http://github.com/pote)
88
+ * [sodabrew](http://github.com/sodabrew)
89
+ * [pote](http://github.com/pote)
data/Rakefile CHANGED
@@ -1,12 +1,9 @@
1
- task :test do
2
- require "cutest"
3
- require "capybara/dsl"
1
+ require "rake/testtask"
4
2
 
5
- Cutest.run(Dir["test/*.rb"])
6
-
7
- class Cutest::Scope
8
- include Capybara::DSL
9
- end
3
+ Rake::TestTask.new("spec") do |t|
4
+ t.libs << "test"
5
+ t.pattern = "test/**/*_test.rb"
10
6
  end
11
7
 
12
- task :default => :test
8
+ task :default => [:test]
9
+ task :test => [:spec]
data/SPEC.md ADDED
@@ -0,0 +1,34 @@
1
+ # Airplay Spec
2
+
3
+ ## CLI
4
+
5
+ ### Commands
6
+
7
+ **play**
8
+ **stop**
9
+ **pause**
10
+
11
+ ```bash
12
+ airplay image.jpg
13
+ airplay image.jpg --transition slide_left
14
+
15
+ airplay video.mp4
16
+ airplay> pause
17
+ ```
18
+
19
+ ## Library
20
+
21
+ ```ruby
22
+ Airplay.send("image.png", transition: :slide_left)
23
+
24
+ player = Airplay.send("video.mp4")
25
+ player.pause
26
+ player.rewind("10s")
27
+
28
+ Airplay.player
29
+ ```
30
+
31
+ ## Documentation
32
+
33
+ * http://nto.github.com/AirPlay.html
34
+ * http://elcuervo.co/protocol/airplay/apple/2012/01/05/airplay-protocol.html
data/airplay.gemspec CHANGED
@@ -1,20 +1,32 @@
1
1
  Gem::Specification.new do |s|
2
- s.name = "airplay"
3
- s.version = "0.2.9"
4
- s.summary = "Airplay client"
5
- s.description = "Send image/video to an airplay enabled device"
6
- s.authors = ["elcuervo"]
7
- s.email = ["yo@brunoaguirre.com"]
8
- s.homepage = "http://github.com/elcuervo/airplay"
9
- s.files = `git ls-files`.split("\n")
10
- s.test_files = `git ls-files test`.split("\n")
2
+ s.name = "airplay"
3
+ s.version = "1.0.0.beta1"
4
+ s.summary = "Airplay client"
5
+ s.description = "Send image/video to an airplay enabled device"
6
+ s.executables = "air"
7
+ s.licenses = ["MIT", "HUGWARE"]
8
+ s.authors = ["elcuervo"]
9
+ s.email = ["yo@brunoaguirre.com"]
10
+ s.homepage = "http://github.com/elcuervo/airplay"
11
+ s.files = `git ls-files`.split("\n")
12
+ s.test_files = `git ls-files test`.split("\n")
11
13
 
12
- s.add_dependency("dnssd", "~> 2.0")
13
- s.add_dependency("net-http-persistent", ">= 2.6")
14
- s.add_dependency("net-http-digest_auth", "~> 1.2")
14
+ # Lib
15
+ s.add_dependency("dnssd", "~> 2.0")
16
+ s.add_dependency("uuid", "~> 2.3.6")
17
+ s.add_dependency("CFPropertyList", "~> 2.2.0")
18
+ s.add_dependency("log4r", "~> 1.1.10")
19
+ s.add_dependency("cuba", "~> 3.1.0")
20
+ s.add_dependency("micromachine", "~> 1.0.4")
21
+ s.add_dependency("celluloid", "~> 0.15.0")
22
+ s.add_dependency("net-ptth", "~> 0.0.10")
23
+ s.add_dependency("net-http-digest_auth", "~> 1.2.1")
15
24
 
16
- s.add_development_dependency("cutest", "~> 1.1")
17
- s.add_development_dependency("capybara", "~> 1.0")
18
- s.add_development_dependency("fakeweb", "~> 1.3")
19
- s.add_development_dependency("vcr", "~> 2.0")
25
+ # CLI
26
+ s.add_dependency("clap", "~> 1.0.0")
27
+ s.add_dependency("ruby-progressbar", "~> 1.2.0")
28
+
29
+ s.add_development_dependency("minitest", "~> 4.4.0")
30
+ s.add_development_dependency("fakeweb", "~> 1.3.0")
31
+ s.add_development_dependency("vcr", "~> 2.4.0")
20
32
  end
data/bin/air ADDED
@@ -0,0 +1,27 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "clap"
4
+ require "airplay/cli"
5
+
6
+ Clap.run ARGV,
7
+ "--device" => lambda { |device_name| @device = Airplay[device_name] },
8
+ "--wait" => lambda { |sec| @wait = sec.to_i },
9
+ "--interactive" => lambda { @interactive = true },
10
+
11
+ "list" => Airplay::CLI.method(:list),
12
+
13
+ "play" => lambda { |video|
14
+ options = { device: @device || Airplay.devices.first }
15
+ Airplay::CLI.play(video, options)
16
+ },
17
+
18
+ "view" => lambda { |file|
19
+ options = {
20
+ device: @device || Airplay.devices.first,
21
+ interactive: @interactive || false,
22
+ wait: @wait || 3
23
+ }
24
+ Airplay::CLI.view(file, options)
25
+ }
26
+
27
+ # vim: ft=ruby
data/examples/demo.rb ADDED
@@ -0,0 +1,35 @@
1
+ require "airplay"
2
+
3
+ puts Airplay.devices.count
4
+ Airplay.devices.each do |device|
5
+ puts device.name
6
+ end
7
+
8
+ videos = [
9
+ "http://trailers.apple.com/movies/marvel/ironman3/ironman3-tlr1-m4mb0_h1080p.mov",
10
+ "http://movietrailers.apple.com/movies/dreamworks/needforspeed/needforspeed-tlr1xxzzs2_480p.mov"
11
+ ]
12
+
13
+ apple_tv = Airplay["Apple TV"]
14
+ player = apple_tv.play(videos.last)
15
+ sleep 4
16
+ player.stop
17
+ sleep 5
18
+
19
+
20
+
21
+ exit
22
+
23
+ videos.each do |video|
24
+ player = apple_tv.play(video)
25
+ end
26
+
27
+ apple_tv.stop
28
+
29
+ Airplay.group["Backyard"] << Airplay["Pool TV"]
30
+ Airplay.group["Backyard"] << Airplay.devices.add("BBQTV", "192.168.1.12")
31
+
32
+ player = Airplay.group["Backyard"].play("video")
33
+ player.wait
34
+
35
+ Airplay.all # => Alias for a global group of all the available devices