openplay 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -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: []