rbsrt 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/README.md +752 -0
- data/Rakefile +29 -0
- data/bin/rbsrt-client +113 -0
- data/bin/rbsrt-server +68 -0
- data/bin/rbsrt-sockets +82 -0
- data/ext/rbsrt/extconf.rb +37 -0
- data/ext/rbsrt/rbsrt.c +2270 -0
- data/ext/rbsrt/rbsrt.h +265 -0
- data/ext/rbsrt/rbstats.c +960 -0
- data/ext/rbsrt/rbstats.h +24 -0
- data/lib/rbsrt/rbsrt.bundle +0 -0
- data/lib/rbsrt/streamid_components.rb +113 -0
- data/lib/rbsrt/version.rb +3 -0
- data/lib/rbsrt.rb +5 -0
- data/rbsrt.gemspec +22 -0
- data/test/rbsrt/poll_test.rb +153 -0
- data/test/rbsrt/stats_test.rb +546 -0
- data/test/rbsrt/streamid_components_test.rb +281 -0
- metadata +83 -0
data/Rakefile
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'bundler'
|
2
|
+
require 'rake/extensiontask'
|
3
|
+
|
4
|
+
Bundler::GemHelper.install_tasks
|
5
|
+
|
6
|
+
task :default => :test
|
7
|
+
|
8
|
+
# desc "Generate Makefile"
|
9
|
+
# file "Makefile" do
|
10
|
+
# cd File.expand_path("../ext/rbsrt/extconf", __FILE__)
|
11
|
+
# require File.expand_path("../ext/rbsrt/extconf", __FILE__)
|
12
|
+
# end
|
13
|
+
#
|
14
|
+
# desc "Compile extension"
|
15
|
+
# task :compile => ["Makefile"] do
|
16
|
+
# sh "make"
|
17
|
+
# end
|
18
|
+
|
19
|
+
require 'rake/extensiontask'
|
20
|
+
|
21
|
+
Rake::ExtensionTask.new 'rbsrt' do |ext|
|
22
|
+
ext.lib_dir = "lib/rbsrt"
|
23
|
+
end
|
24
|
+
|
25
|
+
desc "Run tests"
|
26
|
+
task :test => [ :compile ] do
|
27
|
+
require './test/test_helper'
|
28
|
+
Dir.glob( './test/**/*_test.rb').each { |file| require file }
|
29
|
+
end
|
data/bin/rbsrt-client
ADDED
@@ -0,0 +1,113 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
$:.push File.expand_path("../../lib", __FILE__)
|
4
|
+
|
5
|
+
# parse options
|
6
|
+
|
7
|
+
require 'optparse'
|
8
|
+
|
9
|
+
options = {
|
10
|
+
:direction => "out",
|
11
|
+
:exec => nil,
|
12
|
+
:file => nil,
|
13
|
+
:url => ARGV.last,
|
14
|
+
:passphrase => nil,
|
15
|
+
:streamid => {
|
16
|
+
:mode => :request,
|
17
|
+
:type => :stream
|
18
|
+
}
|
19
|
+
}
|
20
|
+
|
21
|
+
OptionParser.new do |opts|
|
22
|
+
opts.banner = "Usage: rbsrt-client [options] srt://host:port"
|
23
|
+
|
24
|
+
opts.on("-e CMD", "--exec=CMD", "command to execute an use as input or output") do |cmd|
|
25
|
+
options[:exec] = cmd
|
26
|
+
end
|
27
|
+
|
28
|
+
opts.on("-f PATH", "--file=PATH", "file to send to the server") do |path|
|
29
|
+
options[:path] = path
|
30
|
+
options[:type] = :file
|
31
|
+
end
|
32
|
+
|
33
|
+
opts.on("-r NAME", "--resource-name=NAME", "name of the resource to transmit or receive") do |resource_name|
|
34
|
+
options[:streamid][:resource_name] = resource_name
|
35
|
+
end
|
36
|
+
|
37
|
+
opts.on("-u USER_NAME", "--user-name=USER_NAME", "user name") do |user_name|
|
38
|
+
options[:streamid][:user_name] = user_name
|
39
|
+
end
|
40
|
+
|
41
|
+
opts.on("-m MODE", "--mode=MODE", "connection mode. Can be one of 'request', 'publish' or 'bidirectional'") do |mode|
|
42
|
+
options[:streamid][:mode] = mode
|
43
|
+
end
|
44
|
+
|
45
|
+
opts.on("-t TYPE", "--type=TYPE", "connection type. Can be one of 'stream', 'file' or 'auth'") do |type|
|
46
|
+
options[:streamid][:type] = type
|
47
|
+
end
|
48
|
+
|
49
|
+
opts.on("-s SESSIONID", "--sessionid=SESSIONID", "a sessionid") do |sessionid|
|
50
|
+
options[:streamid][:sessionid] = sessionid
|
51
|
+
end
|
52
|
+
|
53
|
+
opts.on("-S PASSPHRASE", "--passphrase=PASSPHRASE", "passphrase used to derive key for encryption") do |passphrase|
|
54
|
+
options[:passphrase] = passphrase
|
55
|
+
end
|
56
|
+
end.parse!
|
57
|
+
|
58
|
+
|
59
|
+
# start server
|
60
|
+
|
61
|
+
require 'rbsrt'
|
62
|
+
require 'uri'
|
63
|
+
|
64
|
+
puts "create srt client"
|
65
|
+
|
66
|
+
streamid_info = SRT::StreamIDComponents.new options[:streamid]
|
67
|
+
|
68
|
+
puts streamid_info
|
69
|
+
|
70
|
+
client = SRT::Client.new
|
71
|
+
|
72
|
+
client.transmission_mode = streamid_info.type == :file ? :file : :live
|
73
|
+
client.streamid = streamid_info.to_s
|
74
|
+
client.passphrase = options[:passphrase]
|
75
|
+
|
76
|
+
puts "connect srt client"
|
77
|
+
|
78
|
+
puts "before connect: #{client.connected?}"
|
79
|
+
|
80
|
+
at_exit { client.close }
|
81
|
+
|
82
|
+
begin
|
83
|
+
uri = URI.parse(options[:url])
|
84
|
+
puts "connect to #{uri.host.to_s} on port #{uri.port.to_s}"
|
85
|
+
client.connect uri.host.to_s, uri.port.to_s
|
86
|
+
rescue StandardError => e
|
87
|
+
puts "Connection failed. #{e.message}"
|
88
|
+
exit 1
|
89
|
+
end
|
90
|
+
|
91
|
+
|
92
|
+
if streamid_info.mode == :request
|
93
|
+
while chunk = client.read
|
94
|
+
print chunk
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
# transmit file contents
|
99
|
+
if file = options[:file]
|
100
|
+
puts "file transport is not implemented yet"
|
101
|
+
# transmist cmd stdout
|
102
|
+
elsif cmd = options[:exec]
|
103
|
+
require 'open3'
|
104
|
+
Open3.popen3(cmd) do |stdin, stdout, stderr, wait_thr|
|
105
|
+
stdout.each do |buf|
|
106
|
+
puts "data: #{buf.length}"
|
107
|
+
client.sendmsg buf
|
108
|
+
end
|
109
|
+
end
|
110
|
+
else
|
111
|
+
|
112
|
+
end
|
113
|
+
|
data/bin/rbsrt-server
ADDED
@@ -0,0 +1,68 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
$:.push File.expand_path("../../lib", __FILE__)
|
4
|
+
|
5
|
+
# parse options
|
6
|
+
|
7
|
+
require 'optparse'
|
8
|
+
|
9
|
+
options = {
|
10
|
+
:port => "5554",
|
11
|
+
:address => "0.0.0.0",
|
12
|
+
:recording_path => Dir.pwd,
|
13
|
+
:passphrase => nil
|
14
|
+
}
|
15
|
+
|
16
|
+
OptionParser.new do |opts|
|
17
|
+
opts.banner = "Usage: rbsrt-server [options]"
|
18
|
+
|
19
|
+
opts.on("-p PORT", "--port=PORT", "server port (default: #{options[:port]})") do |port|
|
20
|
+
options[:port] = port.to_s
|
21
|
+
end
|
22
|
+
|
23
|
+
opts.on("-a ADDRESS", "--address=ADDRESS", "server address (default: #{options[:address]})") do |address|
|
24
|
+
options[:address] = address.to_s
|
25
|
+
end
|
26
|
+
|
27
|
+
opts.on("-r PATH", "--recording-path=PATH", "directory to save recordings (default: #{options[:recording_path]})") do |path|
|
28
|
+
options[:recording_path] = File.expand_path(path, Dir.pwd)
|
29
|
+
end
|
30
|
+
|
31
|
+
opts.on("-S PASSPHRASE", "--passphrase=PASSPHRASE", "passphrase use to derive key for encryption") do |passphrase|
|
32
|
+
options[:passphrase] = passphrase
|
33
|
+
end
|
34
|
+
end.parse!
|
35
|
+
|
36
|
+
|
37
|
+
|
38
|
+
|
39
|
+
# start the server
|
40
|
+
|
41
|
+
require 'rbsrt'
|
42
|
+
|
43
|
+
puts "start srt server on port #{options[:port]}, address #{options[:address]}"
|
44
|
+
|
45
|
+
server = SRT::Server.new options[:address], options[:port]
|
46
|
+
|
47
|
+
# currently we can only set one passphrase for every connection
|
48
|
+
# this will change in the future.
|
49
|
+
server.passphrase = options[:passphrase] if options[:passphrase]
|
50
|
+
|
51
|
+
puts "starting server"
|
52
|
+
|
53
|
+
server.start do |connection|
|
54
|
+
puts "new connection: connections=#{connection_count}, id=#{connection.id}, streamid=#{connection.streamid}"
|
55
|
+
|
56
|
+
output_file = File.new "recording-#{Process.pid}-#{connection.id}.ts", "w+"
|
57
|
+
output_file.close_on_exec = true
|
58
|
+
|
59
|
+
connection.at_data do |chunk|
|
60
|
+
puts "data"
|
61
|
+
output_file.write(chunk)
|
62
|
+
end
|
63
|
+
|
64
|
+
connection.at_close do
|
65
|
+
puts "closed connection"
|
66
|
+
output_file.close
|
67
|
+
end
|
68
|
+
end
|
data/bin/rbsrt-sockets
ADDED
@@ -0,0 +1,82 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
$:.push File.expand_path("../../lib", __FILE__)
|
4
|
+
|
5
|
+
require "rbsrt"
|
6
|
+
|
7
|
+
pids = []
|
8
|
+
|
9
|
+
puts "Running rbsrt Sockets examples"
|
10
|
+
puts "SRT version: #{SRT::SRT_VERSION}"
|
11
|
+
|
12
|
+
|
13
|
+
# server
|
14
|
+
|
15
|
+
pids << fork do
|
16
|
+
server = SRT::Socket.new
|
17
|
+
server.transmission_mode = :file
|
18
|
+
|
19
|
+
puts "server state=#{server.state}, id=#{server.id}"
|
20
|
+
|
21
|
+
server.bind "127.0.0.1", "5556"
|
22
|
+
|
23
|
+
puts "server #{server.state}"
|
24
|
+
|
25
|
+
server.listen 3
|
26
|
+
|
27
|
+
puts "server #{server.state}"
|
28
|
+
|
29
|
+
client = server.accept
|
30
|
+
|
31
|
+
puts "server accepted: streamid=\"#{client.streamid}\", id=#{client.id}, tsbpdmode=#{client.tsbpdmode?}"
|
32
|
+
|
33
|
+
loop do
|
34
|
+
break unless client.connected?
|
35
|
+
break unless data = client.recvmsg
|
36
|
+
puts "server received: #{data}"
|
37
|
+
rescue SRT::Error::CONNLOST => e
|
38
|
+
puts "connection lost: #{e}"
|
39
|
+
break
|
40
|
+
rescue SRT::Error => e
|
41
|
+
puts "server error: #{e.class}"
|
42
|
+
end
|
43
|
+
|
44
|
+
puts "client closed #{client.closed?}"
|
45
|
+
|
46
|
+
server.close
|
47
|
+
|
48
|
+
puts "server done"
|
49
|
+
end
|
50
|
+
|
51
|
+
# client
|
52
|
+
|
53
|
+
pids << fork do
|
54
|
+
|
55
|
+
client = SRT::Socket.new
|
56
|
+
|
57
|
+
client.streamid = "a ruby srt socket"
|
58
|
+
client.transmission_mode = :file
|
59
|
+
|
60
|
+
client.connect "127.0.0.1", "5556"
|
61
|
+
|
62
|
+
10.times do |i|
|
63
|
+
payload = "Hello from ruby client #{i}"
|
64
|
+
puts "will send: \"#{payload}\""
|
65
|
+
client.sendmsg "Hello from ruby client #{i}"
|
66
|
+
puts "did send: \"#{payload}\""
|
67
|
+
# sleep 0.1
|
68
|
+
rescue SRT::Error => e
|
69
|
+
puts "client error: #{e}"
|
70
|
+
end
|
71
|
+
|
72
|
+
sleep 0.1
|
73
|
+
|
74
|
+
client.close
|
75
|
+
|
76
|
+
puts "client done"
|
77
|
+
end
|
78
|
+
|
79
|
+
|
80
|
+
# wait for completion
|
81
|
+
|
82
|
+
pids.each { |pid| Process.wait pid }
|
@@ -0,0 +1,37 @@
|
|
1
|
+
require 'mkmf'
|
2
|
+
|
3
|
+
extension_name = 'rbsrt'
|
4
|
+
|
5
|
+
RbConfig::MAKEFILE_CONFIG['CC'] = ENV['CC'] if ENV['CC']
|
6
|
+
|
7
|
+
LIBDIR = CONFIG['libdir']
|
8
|
+
INCLUDEDIR = CONFIG['includedir']
|
9
|
+
|
10
|
+
HEADER_DIRS = []
|
11
|
+
HEADER_DIRS << 'opt/local/include' if File.directory?('opt/local/include')
|
12
|
+
HEADER_DIRS << '/usr/local/include' if File.directory?('/usr/local/include')
|
13
|
+
HEADER_DIRS << INCLUDEDIR
|
14
|
+
HEADER_DIRS << '/usr/include' if File.directory?('/usr/include')
|
15
|
+
|
16
|
+
LIB_DIRS = []
|
17
|
+
LIB_DIRS << '/opt/local/lib' if File.directory?('/opt/local/lib')
|
18
|
+
LIB_DIRS << '/usr/local/lib' if File.directory?('/usr/local/lib')
|
19
|
+
LIB_DIRS << LIBDIR
|
20
|
+
LIB_DIRS << '/usr/lib' if File.directory?('/usr/lib')
|
21
|
+
|
22
|
+
dir_config('srt', HEADER_DIRS, LIB_DIRS)
|
23
|
+
# dir_config('c++', HEADER_DIRS, LIB_DIRS)
|
24
|
+
|
25
|
+
# srt dependencies
|
26
|
+
|
27
|
+
unless find_header('srt/srt.h')
|
28
|
+
abort "libsrt is missing. please install libsrt: https://github.com/Haivision/srt"
|
29
|
+
end
|
30
|
+
|
31
|
+
unless find_library('srt', 'srt_create_socket')
|
32
|
+
abort "libsrt is missing. please install libsrt: https://github.com/Haivision/srt"
|
33
|
+
end
|
34
|
+
|
35
|
+
dir_config(extension_name)
|
36
|
+
|
37
|
+
create_makefile(extension_name)
|