airplay 1.0.0.beta2 → 1.0.0.beta3

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.
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- airplay (1.0.0.beta2)
4
+ airplay (1.0.0.beta3)
5
5
  CFPropertyList (~> 2.2.0)
6
6
  celluloid (~> 0.15.0)
7
7
  cuba (~> 3.1.0)
@@ -9,14 +9,14 @@ PATH
9
9
  log4r (~> 1.1.10)
10
10
  micromachine (~> 1.0.4)
11
11
  net-http-digest_auth (~> 1.2.1)
12
- net-ptth (= 0.0.12)
12
+ net-ptth (= 0.0.13)
13
13
  uuid (~> 2.3.6)
14
14
 
15
15
  GEM
16
16
  remote: http://rubygems.org/
17
17
  specs:
18
18
  CFPropertyList (2.2.3)
19
- celluloid (0.15.1)
19
+ celluloid (0.15.2)
20
20
  timers (~> 1.1.0)
21
21
  celluloid-io (0.15.0)
22
22
  celluloid (>= 0.15.0)
@@ -39,12 +39,12 @@ GEM
39
39
  micromachine (1.0.4)
40
40
  minitest (4.4.0)
41
41
  net-http-digest_auth (1.2.1)
42
- net-ptth (0.0.12)
42
+ net-ptth (0.0.13)
43
43
  celluloid-io (~> 0.15.0)
44
44
  http_parser.rb (~> 0.5.3)
45
- rack (~> 1.4.5)
45
+ rack (~> 1.5.2)
46
46
  nio4r (0.5.0)
47
- rack (1.4.5)
47
+ rack (1.5.2)
48
48
  rake (10.1.0)
49
49
  systemu (2.5.2)
50
50
  timers (1.1.0)
data/README.md CHANGED
@@ -1,19 +1,40 @@
1
1
  # Airplay
2
+
2
3
  [![Code Climate](https://codeclimate.com/github/elcuervo/airplay.png)](https://codeclimate.com/github/elcuervo/airplay)
3
4
 
4
- ![Airplay](test/fixtures/files/logo.png)
5
+ ![Airplay](doc/img/logo.png)
5
6
 
6
7
  Airplay attempts to be compatible with the latest AppleTV firmware but I'd like
7
8
  to add compatibility to other servers.
8
9
 
10
+ ## Contribute
11
+
12
+ You can contribute with code, bugs or feature requests.
13
+
14
+ The development of the gem takes time and there's a lot of research and hardware
15
+ tests to make all of this. If you want to contribute please consider donating as
16
+ much as you want in: https://gumroad.com/l/airplay
17
+
18
+ ## Help
19
+
20
+ * irc feenode: #airplay
21
+ * twitter: http://twitter.com/airplayrb
22
+
9
23
  ## Installation
10
24
 
25
+ ### Library
26
+
11
27
  `gem install airplay --pre`
12
- `gem install airplay-cli --pre`
13
28
 
14
29
  ## CLI
15
30
 
16
- ### View devices
31
+ `gem install airplay-cli --pre`
32
+
33
+ ## Usage
34
+
35
+ ### CLI
36
+
37
+ #### View devices
17
38
 
18
39
  `air list`
19
40
  ```text
@@ -22,9 +43,9 @@ to add compatibility to other servers.
22
43
  resolution: 1280x720
23
44
  ```
24
45
 
25
- ### Play a video
46
+ #### Play a video
26
47
 
27
- `air play [url to video]`
48
+ `air play [url to video or local file]`
28
49
  ```text
29
50
  Playing http://movietrailers.apple.com/movies/universal/rush/rush-tlr3_480p.mov?width=848&height=352
30
51
  Time: 00:00:13 [===== ] 7% Apple TV
@@ -34,9 +55,21 @@ Time: 00:00:13 [===== ] 7% Apple TV
34
55
 
35
56
  `air view [url to image or image folder]`
36
57
 
37
- ## Library
58
+ ### Library
59
+
60
+ #### Configuration
61
+
62
+ ```ruby
63
+ Airplay.configure do |config|
64
+ config.log_level # Log4r levels (Default: Log4r::ERROR)
65
+ config.autodiscover # Allows to search for nodes (Default: true)
66
+ config.host # In which host bind the server (Default: 0.0.0.0)
67
+ config.port # In which port bind the server (Default: 1337)
68
+ config.output # Where to log (Default: Log4r::Outputter.stdout)
69
+ end
70
+ ```
38
71
 
39
- ### Finding devices
72
+ #### Devices
40
73
 
41
74
  ```ruby
42
75
  require "airplay"
@@ -44,22 +77,39 @@ require "airplay"
44
77
  Airplay.devices.each do |device|
45
78
  puts device.name
46
79
  end
80
+
81
+ # You can access an know device easily
82
+ device = Airplay["Apple TV"]
83
+
84
+ # Or you can group known devices to have them do a given action toghether
85
+ Airplay.group["Backyard"] << Airplay["Apple TV"]
86
+ Airplay.group["Backyard"] << Airplay["Room TV"]
87
+
88
+ # The groups can later do some actions like:
89
+ Airplay.group["Backyard"].play("video")
47
90
  ```
48
91
 
49
- ### Sending images
92
+ #### Images
50
93
 
51
94
  ```ruby
52
95
  require "airplay"
53
96
 
54
97
  apple_tv = Airplay["Apple TV"]
98
+
99
+ # You can send local files
55
100
  apple_tv.view("my_image.png")
101
+
102
+ # Or use remote files
103
+ apple_tv.view("https://github.com/elcuervo/airplay/raw/master/doc/img/logo.png")
104
+
105
+ # And define a transition
56
106
  apple_tv.view("url_to_the_image", transition: "Dissolve")
57
107
 
58
108
  # View all transitions
59
109
  apple_tv.transitions
60
110
  ```
61
111
 
62
- ### Playing video
112
+ #### Video
63
113
 
64
114
  ```ruby
65
115
  require "airplay"
@@ -68,7 +118,38 @@ apple_tv = Airplay["Apple TV"]
68
118
  trailer = "http://movietrailers.apple.com/movies/dreamworks/needforspeed/needforspeed-tlr1xxzzs2_480p.mov"
69
119
 
70
120
  player = apple_tv.play(trailer)
121
+ ```
71
122
 
123
+ ##### Playlist
124
+
125
+ ```ruby
126
+ # You can also add videos to a playlist and let the library handle them
127
+ player.playlist << "video_url"
128
+ player.playlist << "video_path"
129
+ player.play
130
+
131
+ # Or control it yourself
132
+ player.next
133
+ player.previous
134
+
135
+ # Or if you prefer you can have several playlists
136
+ player = apple_tv.player
137
+ player.playlists["Star Wars Classic"] << "Star Wars Episode IV: A New Hope"
138
+ player.playlists["Star Wars Classic"] << "Star Wars Episode V: The Empire Strikes Back"
139
+ player.playlists["Star Wars Classic"] << "Star Wars Episode VI: Return of the Jedi"
140
+
141
+ player.playlists["Star Wars"] << "Star Wars Episode I: The Phantom Menace"
142
+ player.playlists["Star Wars"] << "Star Wars Episode II: Attack of the Clones"
143
+ player.playlists["Star Wars"] << "Star Wars Episode III: Revenge of the Sith"
144
+
145
+ player.use("Star Wars Classic")
146
+ player.play
147
+ player.wait
148
+ ```
149
+
150
+ ##### Player
151
+
152
+ ```ruby
72
153
  # Wait until the video is finished
73
154
  player.wait
74
155
 
@@ -80,7 +161,7 @@ player.scrub
80
161
 
81
162
  # Access the playback time per second
82
163
  player.progress -> progress {
83
- puts "I'm viewing #{progress["position"]} of #{progress["duration"]}"
164
+ puts "I'm viewing #{progress.position} of #{progress.duration}"
84
165
  }
85
166
  ```
86
167
 
@@ -88,3 +169,4 @@ player.progress -> progress {
88
169
 
89
170
  * [sodabrew](http://github.com/sodabrew)
90
171
  * [pote](http://github.com/pote)
172
+
data/Rakefile CHANGED
@@ -81,3 +81,13 @@ namespace :release, &builder.construct(:release)
81
81
 
82
82
  task :default => [:test]
83
83
  task :test => [:spec]
84
+
85
+ namespace :doc do
86
+ task :generate do
87
+ structure = %w(header installation usage contributors)
88
+
89
+ File.open("README.md", "w+") do |f|
90
+ structure.each { |part| f << File.read("doc/#{part}.md") + "\n" }
91
+ end
92
+ end
93
+ end
@@ -13,7 +13,7 @@ Gem::Specification.new do |s|
13
13
  s.homepage = "http://github.com/elcuervo/airplay"
14
14
  s.files = %w(bin/air lib/airplay/cli.rb)
15
15
 
16
- s.add_dependency("airplay", "~> 1.0.0.beta2")
16
+ s.add_dependency("airplay", "= 1.0.0.beta3")
17
17
  s.add_dependency("clap", "~> 1.0.0")
18
18
  s.add_dependency("ruby-progressbar", "~> 1.2.0")
19
19
  end
@@ -20,7 +20,7 @@ Gem::Specification.new do |s|
20
20
  s.add_dependency("cuba", "~> 3.1.0")
21
21
  s.add_dependency("micromachine", "~> 1.0.4")
22
22
  s.add_dependency("celluloid", "~> 0.15.0")
23
- s.add_dependency("net-ptth", "= 0.0.12")
23
+ s.add_dependency("net-ptth", "= 0.0.13")
24
24
  s.add_dependency("net-http-digest_auth", "~> 1.2.1")
25
25
 
26
26
  s.add_development_dependency("minitest", "~> 4.4.0")
@@ -0,0 +1,4 @@
1
+ ## Contributors
2
+
3
+ * [sodabrew](http://github.com/sodabrew)
4
+ * [pote](http://github.com/pote)
@@ -0,0 +1,21 @@
1
+ # Airplay
2
+
3
+ [![Code Climate](https://codeclimate.com/github/elcuervo/airplay.png)](https://codeclimate.com/github/elcuervo/airplay)
4
+
5
+ ![Airplay](doc/img/logo.png)
6
+
7
+ Airplay attempts to be compatible with the latest AppleTV firmware but I'd like
8
+ to add compatibility to other servers.
9
+
10
+ ## Contribute
11
+
12
+ You can contribute with code, bugs or feature requests.
13
+
14
+ The development of the gem takes time and there's a lot of research and hardware
15
+ tests to make all of this. If you want to contribute please consider donating as
16
+ much as you want in: https://gumroad.com/l/airplay
17
+
18
+ ## Help
19
+
20
+ * irc feenode: #airplay
21
+ * twitter: http://twitter.com/airplayrb
Binary file
@@ -0,0 +1,9 @@
1
+ ## Installation
2
+
3
+ ### Library
4
+
5
+ `gem install airplay --pre`
6
+
7
+ ## CLI
8
+
9
+ `gem install airplay-cli --pre`
@@ -0,0 +1,134 @@
1
+ ## Usage
2
+
3
+ ### CLI
4
+
5
+ #### View devices
6
+
7
+ `air list`
8
+ ```text
9
+ * Apple TV (AppleTV2,1 running 11A502)
10
+ ip: 192.168.1.12
11
+ resolution: 1280x720
12
+ ```
13
+
14
+ #### Play a video
15
+
16
+ `air play [url to video or local file]`
17
+ ```text
18
+ Playing http://movietrailers.apple.com/movies/universal/rush/rush-tlr3_480p.mov?width=848&height=352
19
+ Time: 00:00:13 [===== ] 7% Apple TV
20
+ ```
21
+
22
+ ### Show images
23
+
24
+ `air view [url to image or image folder]`
25
+
26
+ ### Library
27
+
28
+ #### Configuration
29
+
30
+ ```ruby
31
+ Airplay.configure do |config|
32
+ config.log_level # Log4r levels (Default: Log4r::ERROR)
33
+ config.autodiscover # Allows to search for nodes (Default: true)
34
+ config.host # In which host bind the server (Default: 0.0.0.0)
35
+ config.port # In which port bind the server (Default: 1337)
36
+ config.output # Where to log (Default: Log4r::Outputter.stdout)
37
+ end
38
+ ```
39
+
40
+ #### Devices
41
+
42
+ ```ruby
43
+ require "airplay"
44
+
45
+ Airplay.devices.each do |device|
46
+ puts device.name
47
+ end
48
+
49
+ # You can access an know device easily
50
+ device = Airplay["Apple TV"]
51
+
52
+ # Or you can group known devices to have them do a given action toghether
53
+ Airplay.group["Backyard"] << Airplay["Apple TV"]
54
+ Airplay.group["Backyard"] << Airplay["Room TV"]
55
+
56
+ # The groups can later do some actions like:
57
+ Airplay.group["Backyard"].play("video")
58
+ ```
59
+
60
+ #### Images
61
+
62
+ ```ruby
63
+ require "airplay"
64
+
65
+ apple_tv = Airplay["Apple TV"]
66
+
67
+ # You can send local files
68
+ apple_tv.view("my_image.png")
69
+
70
+ # Or use remote files
71
+ apple_tv.view("https://github.com/elcuervo/airplay/raw/master/doc/img/logo.png")
72
+
73
+ # And define a transition
74
+ apple_tv.view("url_to_the_image", transition: "Dissolve")
75
+
76
+ # View all transitions
77
+ apple_tv.transitions
78
+ ```
79
+
80
+ #### Video
81
+
82
+ ```ruby
83
+ require "airplay"
84
+
85
+ apple_tv = Airplay["Apple TV"]
86
+ trailer = "http://movietrailers.apple.com/movies/dreamworks/needforspeed/needforspeed-tlr1xxzzs2_480p.mov"
87
+
88
+ player = apple_tv.play(trailer)
89
+ ```
90
+
91
+ ##### Playlist
92
+
93
+ ```ruby
94
+ # You can also add videos to a playlist and let the library handle them
95
+ player.playlist << "video_url"
96
+ player.playlist << "video_path"
97
+ player.play
98
+
99
+ # Or control it yourself
100
+ player.next
101
+ player.previous
102
+
103
+ # Or if you prefer you can have several playlists
104
+ player = apple_tv.player
105
+ player.playlists["Star Wars Classic"] << "Star Wars Episode IV: A New Hope"
106
+ player.playlists["Star Wars Classic"] << "Star Wars Episode V: The Empire Strikes Back"
107
+ player.playlists["Star Wars Classic"] << "Star Wars Episode VI: Return of the Jedi"
108
+
109
+ player.playlists["Star Wars"] << "Star Wars Episode I: The Phantom Menace"
110
+ player.playlists["Star Wars"] << "Star Wars Episode II: Attack of the Clones"
111
+ player.playlists["Star Wars"] << "Star Wars Episode III: Revenge of the Sith"
112
+
113
+ player.use("Star Wars Classic")
114
+ player.play
115
+ player.wait
116
+ ```
117
+
118
+ ##### Player
119
+
120
+ ```ruby
121
+ # Wait until the video is finished
122
+ player.wait
123
+
124
+ # Actions
125
+ player.pause
126
+ player.resume
127
+ player.stop
128
+ player.scrub
129
+
130
+ # Access the playback time per second
131
+ player.progress -> progress {
132
+ puts "I'm viewing #{progress.position} of #{progress.duration}"
133
+ }
134
+ ```
@@ -25,7 +25,7 @@ module Airplay
25
25
  )
26
26
 
27
27
  player.progress -> playback {
28
- bar.progress = playback.percent
28
+ bar.progress = playback.percent if playback.percent
29
29
  }
30
30
 
31
31
  player.wait
@@ -1,5 +1,5 @@
1
1
  module Airplay
2
2
  class CLI
3
- VERSION = "0.1.0.beta2"
3
+ VERSION = "0.1.0.beta4"
4
4
  end
5
5
  end
@@ -19,7 +19,9 @@ module Airplay
19
19
  player.playlist
20
20
  end
21
21
 
22
- private
22
+ def playlists
23
+ player.playlists
24
+ end
23
25
 
24
26
  def player
25
27
  @_player ||= Airplay::Player.new(self)
@@ -26,8 +26,21 @@ module Airplay
26
26
  @device = device
27
27
  end
28
28
 
29
+ def playlists
30
+ @_playlists ||= Hash.new { |h,k| h[k] = Playlist.new(k) }
31
+ end
32
+
29
33
  def playlist
30
- @_playlist ||= Playlist.new
34
+ @_playlist ||= if playlists.any?
35
+ key, value = playlists.first
36
+ value
37
+ else
38
+ Playlist.new("Default")
39
+ end
40
+ end
41
+
42
+ def use(name)
43
+ @_playlist = playlists[name]
31
44
  end
32
45
 
33
46
  # Public: Plays a given url or file.
@@ -125,6 +138,7 @@ module Airplay
125
138
  connection.post("/stop")
126
139
  end
127
140
 
141
+ def loading?; state == :loading end
128
142
  def playing?; state == :playing end
129
143
  def paused?; state == :paused end
130
144
  def played?; state == :played end
@@ -133,7 +147,7 @@ module Airplay
133
147
  # Public: Locks the execution until the video gets fully played
134
148
  #
135
149
  def wait
136
- sleep 0.1 while !played? || stopped?
150
+ sleep 1 while wait_for_playback?
137
151
  cleanup
138
152
  end
139
153
 
@@ -144,6 +158,11 @@ module Airplay
144
158
 
145
159
  private
146
160
 
161
+ def wait_for_playback?
162
+ return true if playlist.next?
163
+ loading? || playing? || paused?
164
+ end
165
+
147
166
  def timers
148
167
  @_timers ||= Timers.new
149
168
  end
@@ -159,10 +178,10 @@ module Airplay
159
178
  def check_for_playback_status
160
179
  timers << every(1) do
161
180
  case true
162
- when info.stopped? then @machine.trigger(:stopped) if playing?
163
- when info.played? then @machine.trigger(:played) if playing?
164
- when info.playing? then @machine.trigger(:playing) if !playing?
165
- when info.paused? then @machine.trigger(:paused) if playing?
181
+ when info.stopped? && playing? then @machine.trigger(:stopped)
182
+ when info.played? && playing? then @machine.trigger(:played)
183
+ when info.playing? && !playing? then @machine.trigger(:playing)
184
+ when info.paused? && playing? then @machine.trigger(:paused)
166
185
  end
167
186
  end
168
187
  end
@@ -170,10 +189,13 @@ module Airplay
170
189
  # Private: Get ready the state machine
171
190
  #
172
191
  def start_the_machine
173
- @machine = MicroMachine.new(:stopped)
192
+ @machine = MicroMachine.new(:loading)
174
193
 
175
194
  @machine.on(:stopped) { cleanup }
176
- @machine.on(:played) { cleanup }
195
+ @machine.on(:played) do
196
+ cleanup
197
+ self.next if playlist.next?
198
+ end
177
199
 
178
200
  @machine.when(:loading, :stopped => :loading)
179
201
  @machine.when(:playing, {
@@ -7,9 +7,12 @@ module Airplay
7
7
  include Enumerable
8
8
  extend Forwardable
9
9
 
10
+ attr_reader :name
11
+
10
12
  def_delegators :@items, :each, :size, :empty?
11
13
 
12
- def initialize
14
+ def initialize(name)
15
+ @name = name
13
16
  @items = []
14
17
  @position = 0
15
18
  end
@@ -22,8 +25,11 @@ module Airplay
22
25
  @items << Media.new(file_or_url)
23
26
  end
24
27
 
28
+ def next?; @position + 1 <= @items.size end
29
+ def previous?; @position - 1 >= 0 end
30
+
25
31
  def next
26
- return nil if @position + 1 > @items.size
32
+ return nil if !next?
27
33
 
28
34
  item = @items[@position]
29
35
  @position += 1
@@ -31,7 +37,7 @@ module Airplay
31
37
  end
32
38
 
33
39
  def previous
34
- return nil if @position - 1 < 0
40
+ return nil if !previous?
35
41
 
36
42
  @position -= 1
37
43
  @items[@position]
@@ -1,3 +1,3 @@
1
1
  module Airplay
2
- VERSION = "1.0.0.beta2"
2
+ VERSION = "1.0.0.beta3"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: airplay
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0.beta2
4
+ version: 1.0.0.beta3
5
5
  prerelease: 6
6
6
  platform: ruby
7
7
  authors:
@@ -130,7 +130,7 @@ dependencies:
130
130
  requirements:
131
131
  - - '='
132
132
  - !ruby/object:Gem::Version
133
- version: 0.0.12
133
+ version: 0.0.13
134
134
  type: :runtime
135
135
  prerelease: false
136
136
  version_requirements: !ruby/object:Gem::Requirement
@@ -138,7 +138,7 @@ dependencies:
138
138
  requirements:
139
139
  - - '='
140
140
  - !ruby/object:Gem::Version
141
- version: 0.0.12
141
+ version: 0.0.13
142
142
  - !ruby/object:Gem::Dependency
143
143
  name: net-http-digest_auth
144
144
  requirement: !ruby/object:Gem::Requirement
@@ -222,6 +222,11 @@ files:
222
222
  - airplay-cli.gemspec
223
223
  - airplay.gemspec
224
224
  - bin/air
225
+ - doc/contributors.md
226
+ - doc/header.md
227
+ - doc/img/logo.png
228
+ - doc/installation.md
229
+ - doc/usage.md
225
230
  - examples/demo.rb
226
231
  - examples/image.rb
227
232
  - examples/video.rb
@@ -248,7 +253,6 @@ files:
248
253
  - lib/airplay/player/timers.rb
249
254
  - lib/airplay/server.rb
250
255
  - lib/airplay/server/app.rb
251
- - lib/airplay/structure.rb
252
256
  - lib/airplay/version.rb
253
257
  - lib/airplay/viewable.rb
254
258
  - lib/airplay/viewer.rb
@@ -1,7 +0,0 @@
1
- # Public: Stupid class to easily create and initialize a Struct from a hash
2
- #
3
- class Structure < Struct
4
- def self.create(hash)
5
- new(*members.map { |member| hash[member.to_sym] })
6
- end
7
- end