airplay 1.0.0.beta1 → 1.0.0.beta2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (47) hide show
  1. data/.gitignore +1 -0
  2. data/.travis.yml +9 -0
  3. data/Gemfile +1 -1
  4. data/Gemfile.lock +3 -7
  5. data/README.md +2 -1
  6. data/Rakefile +74 -0
  7. data/airplay-cli.gemspec +19 -0
  8. data/airplay.gemspec +5 -8
  9. data/examples/demo.rb +5 -8
  10. data/lib/airplay.rb +20 -2
  11. data/lib/airplay/cli/version.rb +5 -0
  12. data/lib/airplay/configuration.rb +8 -3
  13. data/lib/airplay/connection.rb +0 -7
  14. data/lib/airplay/devices.rb +4 -1
  15. data/lib/airplay/group.rb +33 -0
  16. data/lib/airplay/group/players.rb +31 -0
  17. data/lib/airplay/playable.rb +7 -3
  18. data/lib/airplay/{protocol/player.rb → player.rb} +37 -17
  19. data/lib/airplay/player/media.rb +22 -0
  20. data/lib/airplay/player/playback_info.rb +51 -0
  21. data/lib/airplay/player/playlist.rb +41 -0
  22. data/lib/airplay/player/timers.rb +27 -0
  23. data/lib/airplay/server.rb +56 -0
  24. data/lib/airplay/server/app.rb +17 -0
  25. data/lib/airplay/version.rb +3 -0
  26. data/lib/airplay/viewable.rb +2 -2
  27. data/lib/airplay/{protocol/viewer.rb → viewer.rb} +2 -2
  28. metadata +22 -73
  29. data/lib/airplay/protocol.rb +0 -12
  30. data/lib/airplay/protocol/app.rb +0 -52
  31. data/lib/airplay/protocol/message.rb +0 -8
  32. data/lib/airplay/protocol/playback_info.rb +0 -49
  33. data/lib/airplay/protocol/reverse.rb +0 -69
  34. data/lib/airplay/protocol/slideshow.rb +0 -66
  35. data/lib/airplay/protocol/timers.rb +0 -25
  36. data/test/fixtures/cassettes/airplay/listing_slideshow_features.yml +0 -201
  37. data/test/fixtures/cassettes/airplay/play_an_entire_video.yml +0 -100
  38. data/test/fixtures/cassettes/airplay/sending_a_video.yml +0 -71
  39. data/test/fixtures/cassettes/airplay/sending_an_image.yml +0 -26439
  40. data/test/fixtures/cassettes/airplay/stop_any_transmission.yml +0 -8851
  41. data/test/integration/discovery_test.rb +0 -13
  42. data/test/integration/features_test.rb +0 -14
  43. data/test/integration/send_media_test.rb +0 -37
  44. data/test/integration/slideshow_test.rb +0 -26
  45. data/test/test_helper.rb +0 -42
  46. data/test/unit/node_test.rb +0 -17
  47. data/test/unit/protocol_test.rb +0 -44
@@ -0,0 +1 @@
1
+ pkg
@@ -0,0 +1,9 @@
1
+ language: ruby
2
+ rvm:
3
+ - "1.9.3"
4
+ - "2.0.0"
5
+ - "rbx-19mode"
6
+ before_install:
7
+ - "sudo apt-get -qq update"
8
+ - "sudo apt-get -qq install rdnssd libavahi-compat-libdnssd-dev"
9
+ script: bundle exec rake spec
data/Gemfile CHANGED
@@ -1,6 +1,6 @@
1
1
  source "http://rubygems.org"
2
2
 
3
- gemspec
3
+ gemspec name: 'airplay'
4
4
 
5
5
  gem "rake"
6
6
 
@@ -1,17 +1,15 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- airplay (1.0.0.beta1)
4
+ airplay (1.0.0.beta2)
5
5
  CFPropertyList (~> 2.2.0)
6
6
  celluloid (~> 0.15.0)
7
- clap (~> 1.0.0)
8
7
  cuba (~> 3.1.0)
9
8
  dnssd (~> 2.0)
10
9
  log4r (~> 1.1.10)
11
10
  micromachine (~> 1.0.4)
12
11
  net-http-digest_auth (~> 1.2.1)
13
- net-ptth (~> 0.0.10)
14
- ruby-progressbar (~> 1.2.0)
12
+ net-ptth (= 0.0.12)
15
13
  uuid (~> 2.3.6)
16
14
 
17
15
  GEM
@@ -23,7 +21,6 @@ GEM
23
21
  celluloid-io (0.15.0)
24
22
  celluloid (>= 0.15.0)
25
23
  nio4r (>= 0.5.0)
26
- clap (1.0.0)
27
24
  columnize (0.3.6)
28
25
  cuba (3.1.0)
29
26
  rack
@@ -42,14 +39,13 @@ GEM
42
39
  micromachine (1.0.4)
43
40
  minitest (4.4.0)
44
41
  net-http-digest_auth (1.2.1)
45
- net-ptth (0.0.10)
42
+ net-ptth (0.0.12)
46
43
  celluloid-io (~> 0.15.0)
47
44
  http_parser.rb (~> 0.5.3)
48
45
  rack (~> 1.4.5)
49
46
  nio4r (0.5.0)
50
47
  rack (1.4.5)
51
48
  rake (10.1.0)
52
- ruby-progressbar (1.2.0)
53
49
  systemu (2.5.2)
54
50
  timers (1.1.0)
55
51
  uuid (2.3.7)
data/README.md CHANGED
@@ -8,7 +8,8 @@ to add compatibility to other servers.
8
8
 
9
9
  ## Installation
10
10
 
11
- `gem install airplay`
11
+ `gem install airplay --pre`
12
+ `gem install airplay-cli --pre`
12
13
 
13
14
  ## CLI
14
15
 
data/Rakefile CHANGED
@@ -1,9 +1,83 @@
1
+ $: << File.expand_path("../lib", __FILE__)
2
+
1
3
  require "rake/testtask"
4
+ require "fileutils"
5
+ require "airplay/version"
6
+ require "airplay/cli/version"
2
7
 
3
8
  Rake::TestTask.new("spec") do |t|
4
9
  t.libs << "test"
5
10
  t.pattern = "test/**/*_test.rb"
6
11
  end
7
12
 
13
+ class RuleBuilder
14
+ attr_reader :task, :info
15
+
16
+ TASKS = [:lib, :cli]
17
+
18
+ def initialize(options = {})
19
+ @task = options[:task]
20
+
21
+ @info = {
22
+ lib: { name: "airplay", version: Airplay::VERSION },
23
+ cli: { name: "airplay-cli", version: Airplay::CLI::VERSION }
24
+ }
25
+ end
26
+
27
+ def construct(action)
28
+ -> n {
29
+ task.call(:all) do
30
+ TASKS.each { |task| Rake::Task["#{action}:#{task}"].invoke }
31
+ end
32
+
33
+ TASKS.each do |task_name|
34
+ task.call(task_name) { action_method(action, task_name) }
35
+ end
36
+ }
37
+ end
38
+
39
+ private
40
+
41
+ def action_method(action, task_name)
42
+ method("#{action}_gem".to_sym).call(task_name)
43
+ end
44
+
45
+ def build_gem(type)
46
+ name = info[type][:name]
47
+ version = info[type][:version]
48
+
49
+ gem_name = "#{name}-#{version}.gem"
50
+
51
+ FileUtils.mkdir_p("pkg")
52
+ `gem build #{name}.gemspec`
53
+ FileUtils.mv(gem_name, "pkg")
54
+
55
+ puts "#{name} (v#{version}) builded!"
56
+
57
+ "./pkg/#{gem_name}"
58
+ end
59
+
60
+ def install_gem(type)
61
+ name = info[type][:name]
62
+ gem_path = build_gem(type)
63
+ `gem install --local #{gem_path}`
64
+
65
+ puts "#{gem_path} installed!"
66
+ end
67
+
68
+ def release_gem(type)
69
+ name = info[type][:name]
70
+ gem_path = build_gem(type)
71
+ `gem push #{gem_path}`
72
+
73
+ puts "#{gem_path} released!"
74
+ end
75
+ end
76
+
77
+ builder = RuleBuilder.new(task: method(:task))
78
+ namespace :build, &builder.construct(:build)
79
+ namespace :install, &builder.construct(:install)
80
+ namespace :release, &builder.construct(:release)
81
+
8
82
  task :default => [:test]
9
83
  task :test => [:spec]
@@ -0,0 +1,19 @@
1
+ $: << File.expand_path("../lib", __FILE__)
2
+ require "airplay/cli/version"
3
+
4
+ Gem::Specification.new do |s|
5
+ s.name = "airplay-cli"
6
+ s.version = Airplay::CLI::VERSION
7
+ s.summary = "Airplay client CLI"
8
+ s.description = "Send pics and videos using the terminal"
9
+ s.executables = "air"
10
+ s.licenses = ["MIT", "HUGWARE"]
11
+ s.authors = ["elcuervo"]
12
+ s.email = ["yo@brunoaguirre.com"]
13
+ s.homepage = "http://github.com/elcuervo/airplay"
14
+ s.files = %w(bin/air lib/airplay/cli.rb)
15
+
16
+ s.add_dependency("airplay", "~> 1.0.0.beta2")
17
+ s.add_dependency("clap", "~> 1.0.0")
18
+ s.add_dependency("ruby-progressbar", "~> 1.2.0")
19
+ end
@@ -1,9 +1,11 @@
1
+ $: << File.expand_path("../lib", __FILE__)
2
+ require "airplay/version"
3
+
1
4
  Gem::Specification.new do |s|
2
5
  s.name = "airplay"
3
- s.version = "1.0.0.beta1"
6
+ s.version = Airplay::VERSION
4
7
  s.summary = "Airplay client"
5
8
  s.description = "Send image/video to an airplay enabled device"
6
- s.executables = "air"
7
9
  s.licenses = ["MIT", "HUGWARE"]
8
10
  s.authors = ["elcuervo"]
9
11
  s.email = ["yo@brunoaguirre.com"]
@@ -11,7 +13,6 @@ Gem::Specification.new do |s|
11
13
  s.files = `git ls-files`.split("\n")
12
14
  s.test_files = `git ls-files test`.split("\n")
13
15
 
14
- # Lib
15
16
  s.add_dependency("dnssd", "~> 2.0")
16
17
  s.add_dependency("uuid", "~> 2.3.6")
17
18
  s.add_dependency("CFPropertyList", "~> 2.2.0")
@@ -19,13 +20,9 @@ Gem::Specification.new do |s|
19
20
  s.add_dependency("cuba", "~> 3.1.0")
20
21
  s.add_dependency("micromachine", "~> 1.0.4")
21
22
  s.add_dependency("celluloid", "~> 0.15.0")
22
- s.add_dependency("net-ptth", "~> 0.0.10")
23
+ s.add_dependency("net-ptth", "= 0.0.12")
23
24
  s.add_dependency("net-http-digest_auth", "~> 1.2.1")
24
25
 
25
- # CLI
26
- s.add_dependency("clap", "~> 1.0.0")
27
- s.add_dependency("ruby-progressbar", "~> 1.2.0")
28
-
29
26
  s.add_development_dependency("minitest", "~> 4.4.0")
30
27
  s.add_development_dependency("fakeweb", "~> 1.3.0")
31
28
  s.add_development_dependency("vcr", "~> 2.4.0")
@@ -11,21 +11,18 @@ videos = [
11
11
  ]
12
12
 
13
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
14
 
15
+ apple_tv.view("./test/fixtures/files/logo.png", transition: "SlideLeft")
16
+ sleep 2
17
+ puts apple_tv.view("./test/fixtures/files/a.png", transition: "SlideLeft")
18
+ sleep 20
21
19
  exit
22
20
 
23
21
  videos.each do |video|
24
22
  player = apple_tv.play(video)
23
+ sleep 10
25
24
  end
26
25
 
27
- apple_tv.stop
28
-
29
26
  Airplay.group["Backyard"] << Airplay["Pool TV"]
30
27
  Airplay.group["Backyard"] << Airplay.devices.add("BBQTV", "192.168.1.12")
31
28
 
@@ -1,5 +1,8 @@
1
1
  require "airplay/configuration"
2
2
  require "airplay/browser"
3
+ require "airplay/group"
4
+ require "airplay/server"
5
+ require "airplay/version"
3
6
 
4
7
  # Public: Airplay core module
5
8
  #
@@ -9,14 +12,30 @@ module Airplay
9
12
  yield(configuration) if block
10
13
  end
11
14
 
15
+ def server
16
+ @_server ||= Server.new
17
+ end
18
+
12
19
  def browse
13
20
  browser.browse
14
21
  end
15
22
 
23
+ def group
24
+ @_group ||= Hash.new { |h, k| h[k] = Group.new(k) }
25
+ end
26
+
27
+ def all
28
+ @_all ||= begin
29
+ group = Group.new(:all)
30
+ devices.each { |device| group << device }
31
+ group
32
+ end
33
+ end
34
+
16
35
  # Public: Lists found devices
17
36
  #
18
37
  def devices
19
- browse if browser.devices.empty?
38
+ browse if browser.devices.empty? && configuration.autodiscover
20
39
  browser.devices
21
40
  end
22
41
 
@@ -35,4 +54,3 @@ module Airplay
35
54
  end
36
55
  end
37
56
  end
38
-
@@ -0,0 +1,5 @@
1
+ module Airplay
2
+ class CLI
3
+ VERSION = "0.1.0.beta2"
4
+ end
5
+ end
@@ -1,15 +1,19 @@
1
- require 'log4r/config'
1
+ require "log4r/config"
2
+ require "airplay/logger"
2
3
 
3
4
  module Airplay
4
5
  # Public: Handles the Airplay configuration
5
6
  #
6
7
  class Configuration
7
- attr_accessor :log_level, :output
8
+ attr_accessor :log_level, :output, :autodiscover, :host, :port
8
9
 
9
10
  def initialize
10
11
  Log4r.define_levels(*Log4r::Log4rConfig::LogLevels)
11
12
 
12
- @log_level = Log4r::WARN
13
+ @log_level = Log4r::ERROR
14
+ @autodiscover = true
15
+ @host = "0.0.0.0"
16
+ @port = "1337"
13
17
  @output = Log4r::Outputter.stdout
14
18
  end
15
19
 
@@ -24,6 +28,7 @@ module Airplay
24
28
 
25
29
  Log4r::Logger.root.add @output
26
30
  Log4r::Logger.root.level = level
31
+ Celluloid.logger = Airplay::Logger.new("airplay::celluloid")
27
32
  end
28
33
  end
29
34
  end
@@ -8,8 +8,6 @@ module Airplay
8
8
  class Connection
9
9
  Response = Struct.new(:connection, :response)
10
10
 
11
- attr_accessor :reverse, :events, :persistent
12
-
13
11
  include Celluloid
14
12
 
15
13
  def initialize(device, options = {})
@@ -23,11 +21,6 @@ module Airplay
23
21
  @_persistent ||= Airplay::Connection::Persistent.new(address, @options)
24
22
  end
25
23
 
26
- def start_reverse_connection
27
- @reverse = Airplay::Protocol::Reverse.new(Airplay.active)
28
- @reverse.async.connect
29
- end
30
-
31
24
  def close
32
25
  persistent.close
33
26
  @_persistent = nil
@@ -28,6 +28,10 @@ module Airplay
28
28
  find_by_block { |device| device if device.ip == ip }
29
29
  end
30
30
 
31
+ def add(name, address)
32
+ self << Device.new(name: name, address: address)
33
+ end
34
+
31
35
  # Public: Adds a device to the list
32
36
  #
33
37
  # value - The Node
@@ -41,6 +45,5 @@ module Airplay
41
45
  def find_by_block(&block)
42
46
  @items.find(&block)
43
47
  end
44
-
45
48
  end
46
49
  end
@@ -0,0 +1,33 @@
1
+ require "forwardable"
2
+ require "airplay/group/players"
3
+
4
+ module Airplay
5
+ class Group
6
+ include Enumerable
7
+ extend Forwardable
8
+
9
+ def_delegators :@devices, :each, :size, :empty?
10
+
11
+ def initialize(name)
12
+ @devices = []
13
+ @players = []
14
+ @name = name
15
+ end
16
+
17
+ def <<(device)
18
+ @devices << device
19
+ end
20
+
21
+ def play(file_or_url, options = {})
22
+ @players = @devices.map { |device| device.play(file_or_url, options) }
23
+ Players.new(@players)
24
+ end
25
+
26
+ def view(media_or_io, options = {})
27
+ @devices.map do |device|
28
+ ok = device.view(media_or_io, options)
29
+ [device, ok]
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,31 @@
1
+ module Airplay
2
+ class Group
3
+ class Players
4
+ attr_reader :players
5
+
6
+ def initialize(players)
7
+ @players = players
8
+ end
9
+
10
+ def progress(callback)
11
+ players.each do |player|
12
+ player.progress -> info {
13
+ callback.call(player.device, info) if player.playing?
14
+ }
15
+ end
16
+ end
17
+
18
+ def wait
19
+ sleep 0.1 while still_playing?
20
+ players.map(&:cleanup)
21
+ end
22
+
23
+ private
24
+
25
+ def still_playing?
26
+ states = players.map { |player| !player.played? || player.stopped? }
27
+ states.uniq == [true]
28
+ end
29
+ end
30
+ end
31
+ end
@@ -1,4 +1,4 @@
1
- require "airplay/protocol/player"
1
+ require "airplay/player"
2
2
 
3
3
  module Airplay
4
4
  module Playable
@@ -10,15 +10,19 @@ module Airplay
10
10
  #
11
11
  # Returns a Player object to control the playback
12
12
  #
13
- def play(file_or_url, options = {})
13
+ def play(file_or_url = "playlist", options = {})
14
14
  player.async.play(file_or_url, options)
15
15
  player
16
16
  end
17
17
 
18
+ def playlist
19
+ player.playlist
20
+ end
21
+
18
22
  private
19
23
 
20
24
  def player
21
- @_player ||= Airplay::Protocol::Player.new(self)
25
+ @_player ||= Airplay::Player.new(self)
22
26
  end
23
27
  end
24
28
  end