openplay 0.0.2

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.
@@ -0,0 +1,38 @@
1
+ ## OpenPlay
2
+ Screenshare to another machine painlessly, with basic glue for ffmpeg and vlc.
3
+
4
+ ### Prerequisites
5
+ On ubuntu:
6
+
7
+ sudo apt-get install libavahi-compat-libdnssd-dev
8
+
9
+ To throw:
10
+
11
+ sudo apt-get install ffmpeg libavcodec-extra-53
12
+
13
+ To catch:
14
+
15
+ sudo apt-get install vlc
16
+
17
+ ### Development
18
+ Run the tests with:
19
+
20
+ rake
21
+
22
+ ### For help
23
+ ./bin/openplay help
24
+
25
+ ### To receive
26
+ ./bin/openplay receive
27
+
28
+ ### To list available servers
29
+ ./bin/openplay list
30
+
31
+ ### To throw
32
+ #### by Hostname
33
+ ./bin/openplay --hostname=some-host
34
+
35
+ #### by IP
36
+ This needs a real ip, rather than just localhost
37
+
38
+ ./bin/openplay throw --host=127.0.0.1
@@ -0,0 +1,35 @@
1
+ #!/usr/bin/env ruby
2
+ require 'thor'
3
+ require './lib/openplay/client'
4
+ require './lib/openplay/server'
5
+
6
+ module Openplay
7
+ class CLI < Thor
8
+ desc "throw", "Throw video"
9
+ method_option :host, default: "127.0.0.1", banner: "Host IP"
10
+ method_option :hostname, banner: "Hostname returned from 'list'"
11
+ method_option :port, default: 5003, banner: "Port the host is receiving on."
12
+ method_option :resolution, default: nil
13
+ def throw
14
+ @client = ::Openplay::Client.new(options)
15
+ @client.throw
16
+ end
17
+
18
+ desc "list", "List available servers"
19
+ def list
20
+ @client = ::Openplay::Client.new
21
+ # Just list IPv4 records for now
22
+ @client.list.each do |server|
23
+ puts "#{server.hosttxt} on port #{server.port}"
24
+ end
25
+ end
26
+
27
+ desc "receive", "Receive video"
28
+ def receive
29
+ @server = ::Openplay::Server.new
30
+ @server.receive
31
+ end
32
+ end
33
+ end
34
+
35
+ Openplay::CLI.start
@@ -0,0 +1,2 @@
1
+ require_relative 'openplay/client'
2
+ require_relative 'openplay/server'
@@ -0,0 +1,52 @@
1
+ require_relative 'determines_resolution'
2
+ require_relative 'discovers_servers'
3
+
4
+ module Openplay
5
+ class Client
6
+ attr_reader :host, :port
7
+
8
+ def initialize(options={})
9
+ if options[:hostname]
10
+ server = get_server_by_hostname(options[:hostname])
11
+ raise "No server found with hostname #{options[:hostname]}" unless server
12
+ @host = server.ip
13
+ @port = server.port
14
+ else
15
+ @host = options[:host]
16
+ @port = options[:port]
17
+ end
18
+ @resolution = options[:resolution] || screen_resolution
19
+ end
20
+
21
+ # Throw video to a particular server
22
+ def throw
23
+ options = []
24
+ options << "-framerate ntsc"
25
+ options << "-video_size #{@resolution}"
26
+ options << "-f x11grab -i #{ENV['DISPLAY']}"
27
+ options << "-f alsa -i pulse"
28
+ options << "-vcodec libx264 -tune zerolatency -crf 26 -preset ultrafast"
29
+ options << "-f mpegts udp://#{host}:#{port}?pkt_size=#{packet_size}"
30
+ `ffmpeg #{options.join(' ')}`
31
+ end
32
+
33
+ # List available servers
34
+ def list
35
+ DiscoversServers.find_servers
36
+ end
37
+
38
+ private
39
+ def get_server_by_hostname(hostname)
40
+ list.detect{|s| s.hosttxt == hostname }
41
+ end
42
+
43
+ def screen_resolution
44
+ DeterminesResolution.new.get
45
+ end
46
+
47
+ def packet_size
48
+ # This is tuned for getting mpegts frames into udp packets nicely
49
+ 1316
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,6 @@
1
+ class DeterminesResolution
2
+ def get
3
+ x, y = `xrandr`.scan(/current (\d+) x (\d+)/).flatten
4
+ "#{x}x#{y}"
5
+ end
6
+ end
@@ -0,0 +1,9 @@
1
+ require 'findme'
2
+ class DiscoversServers
3
+ def self.find_servers
4
+ servers = Findme.discover.select{|s| s.service == "_openplay._tcp"}
5
+ # Only return IPv4 servers for now, there were issues with IPv6
6
+ # (unacceptable, but whatev)
7
+ servers.select{|s| s.ipv4 == "IPv4"}
8
+ end
9
+ end
@@ -0,0 +1,21 @@
1
+ require 'dnssd'
2
+
3
+ module Openplay
4
+ class Server
5
+ attr_reader :port
6
+
7
+ def initialize(port=5003)
8
+ @port = port
9
+ announce_availability
10
+ end
11
+
12
+ def receive
13
+ `cvlc udp://@:#{port} --network-caching=250`
14
+ end
15
+
16
+ private
17
+ def announce_availability
18
+ DNSSD.register `hostname`.chomp, "_openplay._tcp", nil, port
19
+ end
20
+ end
21
+ end
metadata ADDED
@@ -0,0 +1,189 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: openplay
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.2
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Josh Adams
9
+ - Adam Gamble
10
+ autorequire:
11
+ bindir: bin
12
+ cert_chain: []
13
+ date: 2013-01-09 00:00:00.000000000 Z
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: dnssd
17
+ requirement: !ruby/object:Gem::Requirement
18
+ none: false
19
+ requirements:
20
+ - - ~>
21
+ - !ruby/object:Gem::Version
22
+ version: '2.0'
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ none: false
27
+ requirements:
28
+ - - ~>
29
+ - !ruby/object:Gem::Version
30
+ version: '2.0'
31
+ - !ruby/object:Gem::Dependency
32
+ name: findme
33
+ requirement: !ruby/object:Gem::Requirement
34
+ none: false
35
+ requirements:
36
+ - - ! '>='
37
+ - !ruby/object:Gem::Version
38
+ version: '0'
39
+ type: :runtime
40
+ prerelease: false
41
+ version_requirements: !ruby/object:Gem::Requirement
42
+ none: false
43
+ requirements:
44
+ - - ! '>='
45
+ - !ruby/object:Gem::Version
46
+ version: '0'
47
+ - !ruby/object:Gem::Dependency
48
+ name: thor
49
+ requirement: !ruby/object:Gem::Requirement
50
+ none: false
51
+ requirements:
52
+ - - ! '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ type: :runtime
56
+ prerelease: false
57
+ version_requirements: !ruby/object:Gem::Requirement
58
+ none: false
59
+ requirements:
60
+ - - ! '>='
61
+ - !ruby/object:Gem::Version
62
+ version: '0'
63
+ - !ruby/object:Gem::Dependency
64
+ name: minitest
65
+ requirement: !ruby/object:Gem::Requirement
66
+ none: false
67
+ requirements:
68
+ - - ! '>='
69
+ - !ruby/object:Gem::Version
70
+ version: '0'
71
+ type: :development
72
+ prerelease: false
73
+ version_requirements: !ruby/object:Gem::Requirement
74
+ none: false
75
+ requirements:
76
+ - - ! '>='
77
+ - !ruby/object:Gem::Version
78
+ version: '0'
79
+ - !ruby/object:Gem::Dependency
80
+ name: minitest-matchers
81
+ requirement: !ruby/object:Gem::Requirement
82
+ none: false
83
+ requirements:
84
+ - - ! '>='
85
+ - !ruby/object:Gem::Version
86
+ version: '0'
87
+ type: :development
88
+ prerelease: false
89
+ version_requirements: !ruby/object:Gem::Requirement
90
+ none: false
91
+ requirements:
92
+ - - ! '>='
93
+ - !ruby/object:Gem::Version
94
+ version: '0'
95
+ - !ruby/object:Gem::Dependency
96
+ name: turn
97
+ requirement: !ruby/object:Gem::Requirement
98
+ none: false
99
+ requirements:
100
+ - - ! '>='
101
+ - !ruby/object:Gem::Version
102
+ version: '0'
103
+ type: :development
104
+ prerelease: false
105
+ version_requirements: !ruby/object:Gem::Requirement
106
+ none: false
107
+ requirements:
108
+ - - ! '>='
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ - !ruby/object:Gem::Dependency
112
+ name: pry
113
+ requirement: !ruby/object:Gem::Requirement
114
+ none: false
115
+ requirements:
116
+ - - ! '>='
117
+ - !ruby/object:Gem::Version
118
+ version: '0'
119
+ type: :development
120
+ prerelease: false
121
+ version_requirements: !ruby/object:Gem::Requirement
122
+ none: false
123
+ requirements:
124
+ - - ! '>='
125
+ - !ruby/object:Gem::Version
126
+ version: '0'
127
+ - !ruby/object:Gem::Dependency
128
+ name: mocha
129
+ requirement: !ruby/object:Gem::Requirement
130
+ none: false
131
+ requirements:
132
+ - - ! '>='
133
+ - !ruby/object:Gem::Version
134
+ version: '0'
135
+ type: :development
136
+ prerelease: false
137
+ version_requirements: !ruby/object:Gem::Requirement
138
+ none: false
139
+ requirements:
140
+ - - ! '>='
141
+ - !ruby/object:Gem::Version
142
+ version: '0'
143
+ description: Open source air play
144
+ email:
145
+ - josh@isotope11.com
146
+ - agamble@isotope11.com
147
+ executables:
148
+ - openplay
149
+ extensions: []
150
+ extra_rdoc_files: []
151
+ files:
152
+ - bin/openplay
153
+ - lib/openplay.rb
154
+ - lib/openplay/server.rb
155
+ - lib/openplay/client.rb
156
+ - lib/openplay/determines_resolution.rb
157
+ - lib/openplay/discovers_servers.rb
158
+ - README.md
159
+ homepage: http://www.isotope11.com
160
+ licenses: []
161
+ post_install_message:
162
+ rdoc_options: []
163
+ require_paths:
164
+ - lib
165
+ required_ruby_version: !ruby/object:Gem::Requirement
166
+ none: false
167
+ requirements:
168
+ - - ! '>='
169
+ - !ruby/object:Gem::Version
170
+ version: '0'
171
+ segments:
172
+ - 0
173
+ hash: 56586988126532875
174
+ required_rubygems_version: !ruby/object:Gem::Requirement
175
+ none: false
176
+ requirements:
177
+ - - ! '>='
178
+ - !ruby/object:Gem::Version
179
+ version: '0'
180
+ segments:
181
+ - 0
182
+ hash: 56586988126532875
183
+ requirements: []
184
+ rubyforge_project:
185
+ rubygems_version: 1.8.24
186
+ signing_key:
187
+ specification_version: 3
188
+ summary: Open source air play
189
+ test_files: []