rtsp 0.2.1 → 0.2.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,3 +1,9 @@
1
+ === 0.2.2 / 2011-11-02
2
+
3
+ * Added a queue for listening and building the RTP file from the received data.
4
+ * Fixed bugs:
5
+ * gh-6: .gemspec was missing +parslet+ dependency. Thanks [tindron[http://github.com/tindron]].
6
+
1
7
  === 0.2.1 / 2011-09-20
2
8
 
3
9
  * `gem test rtsp` is failing; added rtsp.gemspec to list of files in the spec.
data/Rakefile CHANGED
@@ -1,34 +1,23 @@
1
- require 'rake'
2
-
3
- begin
4
- require 'bundler'
5
- rescue LoadError => e
6
- STDERR.puts e.message
7
- STDERR.puts "Run `gem install bundler` to install Bundler."
8
- exit e.status_code
9
- end
10
-
11
- begin
12
- Bundler.setup(:development)
13
- rescue Bundler::BundlerError => e
14
- STDERR.puts e.message
15
- STDERR.puts "Run `bundle install` to install missing gems."
16
- exit e.status_code
17
- end
18
-
1
+ require 'bundler/gem_tasks'
19
2
  require 'rspec/core/rake_task'
3
+ require 'yard'
4
+
20
5
  RSpec::Core::RakeTask.new(:spec) do |t|
21
- t.ruby_opts = "-w"
22
6
  t.rspec_opts = ['--format', 'documentation', '--color']
23
7
  end
8
+
9
+ namespace :spec do
10
+ RSpec::Core::RakeTask.new(:warnings) do |t|
11
+ t.ruby_opts = "-w"
12
+ t.rspec_opts = ['--format', 'documentation', '--color']
13
+ end
14
+ end
24
15
  task :default => :spec
25
16
  task :test => :spec # for `gem test`
26
17
 
27
- require 'yard'
28
18
  YARD::Rake::YardocTask.new do |t|
29
19
  t.options = ['--verbose']
30
20
  end
31
21
 
32
22
  # Load all extra rake tasks
33
23
  Dir["#{File.dirname(__FILE__)}/tasks/*.rake"].each { |ext| load ext }
34
-
@@ -12,9 +12,9 @@ module RTSP
12
12
  # In this version, objects of this type don't do much other than just capture
13
13
  # the data to a file; in later versions, objects of this type will be able
14
14
  # to provide a "sink" and allow for ensuring that the received RTP packets
15
- # will be reassembled in the correct order, as they're written to file
16
- # (objects of this type don't don't currently check RTP sequence numbers
17
- # on the data that's been received).
15
+ # will be reassembled in the correct order, as they're written to file
16
+ # (objects of this type don't don't currently allow for checking RTP sequence
17
+ # numbers on the data that's been received).
18
18
  class Capturer
19
19
 
20
20
  # Name of the file the data will be captured to unless #rtp_file is set.
@@ -50,7 +50,9 @@ module RTSP
50
50
  @transport_protocol = transport_protocol
51
51
  @rtp_port = rtp_port
52
52
  @rtp_file = rtp_capture_file || Tempfile.new(DEFAULT_CAPFILE_NAME)
53
- @run = false
53
+ @listener = nil
54
+ @file_builder = nil
55
+ @queue = Queue.new
54
56
  end
55
57
 
56
58
  # Initializes a server of the correct socket type.
@@ -70,38 +72,91 @@ module RTSP
70
72
  server
71
73
  end
72
74
 
73
- # Starts capturing data on +@rtp_port+ and writes it to +@rtp_file+.
74
- # @todo Allow to yield received data.
75
+ # Simply calls #start_file_builder and #start_listener.
75
76
  def run
76
- @server = init_server(@transport_protocol, @rtp_port)
77
- @run = true
78
77
  log "Starting #{self.class} on port #{@rtp_port}..."
79
78
 
80
- while @run
81
- data = @server.recvfrom(MAX_BYTES_TO_RECEIVE).first
82
- log "received data with size: #{data.size}"
83
- @rtp_file.write data
79
+ start_file_builder
80
+ start_listener
81
+ end
82
+
83
+ # Starts the +@file_builder+ thread that pops data off of the Queue that
84
+ # #start_listener pushed data on to. It then takes that data and writes it
85
+ # to +@rtp_file+.
86
+ #
87
+ # @return [Thread] The file_builder thread (+@file_builder+)
88
+ def start_file_builder
89
+ return @file_builder if @file_builder and @file_builder.alive?
90
+
91
+ @file_builder = Thread.start(@rtp_file) do |rtp_file|
92
+ loop do
93
+ rtp_file.write @queue.pop until @queue.empty?
94
+ end
95
+ end
96
+
97
+ @file_builder.abort_on_exception = true
98
+ end
99
+
100
+ # Starts the +@listener+ thread that starts up the server, then takes the
101
+ # data received from the server and pushes it on to the +@queue+ so
102
+ # the +@file_builder+ thread can deal with it.
103
+ #
104
+ # @return [Thread] The listener thread (+@listener+).
105
+ def start_listener
106
+ return @listener if @listener and @listener.alive?
107
+
108
+ @listener = Thread.start do
109
+ server = init_server(@transport_protocol, @rtp_port)
110
+
111
+ loop do
112
+ data = server.recvfrom(MAX_BYTES_TO_RECEIVE).first
113
+ log "received data with size: #{data.size}"
114
+ @queue << data
115
+ end
84
116
  end
85
117
 
86
- ensure
87
- @server.close unless @server.nil?
118
+ @listener.abort_on_exception = true
88
119
  end
89
120
 
90
- # Returns if the run loop is in action.
121
+ # @return [Boolean] true if the +@listener+ thread is running; false if not.
122
+ def listening?
123
+ if @listener then @listener.alive? else false end
124
+ end
125
+
126
+ # @return [Boolean] true if the +@file_builder+ thread is running; false if
127
+ # not.
128
+ def file_building?
129
+ if @file_builder then @file_builder.alive? else false end
130
+ end
131
+
132
+ # Returns if the #run loop is in action.
91
133
  #
92
134
  # @return [Boolean] true if the run loop is running.
93
135
  def running?
94
- @server.nil? ? @run : (@run || @server.closed?)
136
+ listening? || file_building?
95
137
  end
96
138
 
97
139
  # Breaks out of the run loop.
98
140
  def stop
99
141
  log "Stopping #{self.class} on port #{@rtp_port}..."
100
- @run = false
142
+ stop_listener
143
+ log "listening? #{listening?}"
144
+ stop_file_builder
145
+ log "file building? #{file_building?}"
146
+ log "running? #{running?}"
147
+ @queue = Queue.new
148
+ end
101
149
 
102
- until !running?
103
- sleep 0.01
104
- end
150
+ # Kills the +@listener+ thread and sets the variable to nil.
151
+ def stop_listener
152
+ @listener.kill if @listener
153
+ @listener = nil
154
+ end
155
+
156
+ # Kills the +@file_builder+ thread and sets the variable to nil.
157
+ def stop_file_builder
158
+ @file_builder.kill if @file_builder
159
+ @file_builder = nil
105
160
  end
106
161
 
107
162
  # Sets up to receive data on a UDP socket, using +@rtp_port+.
@@ -132,7 +187,7 @@ module RTSP
132
187
  # Sets up to receive data on a TCP socket, using +@rtp_port+.
133
188
  #
134
189
  # @param [Fixnum] port Port number to listen for RTP data on.
135
- # @return [TCPSocket]
190
+ # @return [TCPServer]
136
191
  def init_tcp_server(port)
137
192
  port_retries = 0
138
193
 
@@ -1,4 +1,4 @@
1
1
  module RTSP
2
2
  # rtsp version
3
- VERSION = "0.2.1"
3
+ VERSION = "0.2.2"
4
4
  end
@@ -33,6 +33,7 @@ For more information see: http://www.ietf.org/rfc/rfc2326.txt}
33
33
  s.summary = %q{Library to allow RTSP streaming from RTSP-enabled devices.}
34
34
  s.test_files = Dir.glob("{spec,features}/**/*")
35
35
 
36
+ s.add_runtime_dependency(%q<parslet>, ["~> 1.1.0"])
36
37
  s.add_runtime_dependency(%q<sdp>, ["~> 0.2.2"])
37
38
 
38
39
  s.add_development_dependency(%q<bundler>, ["~> 1.0.0"])
@@ -28,18 +28,16 @@ describe RTSP::Capturer do
28
28
 
29
29
  describe "#initialize" do
30
30
  context "with default parameters" do
31
- before { @capturer = RTSP::Capturer.new }
32
-
33
31
  it "uses UDP" do
34
- @capturer.instance_variable_get(:@transport_protocol).should == :UDP
32
+ subject.instance_variable_get(:@transport_protocol).should == :UDP
35
33
  end
36
34
 
37
35
  it "uses port 9000" do
38
- @capturer.instance_variable_get(:@rtp_port).should == 9000
36
+ subject.instance_variable_get(:@rtp_port).should == 9000
39
37
  end
40
38
 
41
39
  it "creates a new Tempfile" do
42
- @capturer.instance_variable_get(:@rtp_file).should be_a Tempfile
40
+ subject.instance_variable_get(:@rtp_file).should be_a Tempfile
43
41
  end
44
42
  end
45
43
 
@@ -68,165 +66,193 @@ describe RTSP::Capturer do
68
66
  end
69
67
 
70
68
  describe "#init_server" do
71
- before { @capturer = RTSP::Capturer.new }
69
+ context "UDP" do
70
+ it "calls #init_udp_server with port 9000" do
71
+ subject.should_receive(:init_udp_server).with(9000)
72
+ subject.init_server(:UDP)
73
+ end
72
74
 
73
- after :each do
74
- @capturer.stop
75
+ it "returns a UDPSocket" do
76
+ subject.init_server(:UDP).should be_a(UDPSocket)
77
+ end
75
78
  end
76
79
 
77
- it "creates a UDPSocket when initialized with :UDP" do
78
- @capturer.init_server(:UDP).should be_a UDPSocket
79
- end
80
+ context "TCP" do
81
+ it "calls #init_tcp_server with port 9000" do
82
+ subject.should_receive(:init_tcp_server).with(9000)
83
+ subject.init_server(:TCP)
84
+ end
80
85
 
81
- it "creates a TCPSocket when initialized with :TCP" do
82
- TCPServer.new('0.0.0.0', 9000)
83
- @capturer.init_server(:TCP).should be_a TCPSocket
86
+ it "returns a TCPServer" do
87
+ subject.init_server(:TCP).should be_a(TCPServer)
88
+ end
84
89
  end
85
90
 
86
91
  it "raises an RTSP::Error when some other protocol is given" do
87
- expect { @capturer.init_server(:BOBO) }.to raise_error RTSP::Error
92
+ expect { subject.init_server(:BOBO) }.to raise_error RTSP::Error
88
93
  end
89
94
  end
90
95
 
91
- describe "#run" do
92
- context "default capturer settings" do
93
- before do
94
- @capturer = RTSP::Capturer.new
95
- @receiver_thread = Thread.start(@capturer) { |capturer| capturer.run }
96
-
97
- @client = UDPSocket.open
98
- @sender_thread = Thread.start(@client) do |client|
99
- loop do
100
- client.send "x", 0, 'localhost', @capturer.rtp_port
101
- end
102
- end
103
-
104
- sleep 0.1
96
+ describe "#init_udp_server" do
97
+ after :each do
98
+ unless @sockets.nil?
99
+ @sockets.each { |s| s.close }
105
100
  end
101
+ end
106
102
 
107
- after do
108
- @sender_thread.exit
109
- @receiver_thread.exit
110
- end
103
+ it "returns a UDPSocket" do
104
+ server = subject.init_udp_server(subject.rtp_port)
105
+ server.should be_a UDPSocket
106
+ end
111
107
 
112
- it "gets access to a UDPSocket via @server" do
113
- @capturer.instance_variable_get(:@server).should be_a UDPSocket
114
- end
108
+ it "retries MAX_PORT_NUMBER_RETRIES to get a port" do
109
+ @sockets = use_udp_ports 9000...(9000 + RTSP::Capturer::MAX_PORT_NUMBER_RETRIES)
110
+ subject.init_udp_server(subject.rtp_port)
111
+
112
+ subject.rtp_port.should == 9000 + RTSP::Capturer::MAX_PORT_NUMBER_RETRIES
113
+ end
115
114
 
116
- it "sets @run to true" do
117
- @capturer.instance_variable_get(:@run).should be_true
115
+ context "when no available ports, it retries MAX_PORT_NUMBER_RETRIES times, then" do
116
+ before do
117
+ @sockets = use_udp_ports 9000..(9000 + RTSP::Capturer::MAX_PORT_NUMBER_RETRIES)
118
118
  end
119
119
 
120
- it "receives data and writes to @rtp_file" do
121
- @capturer.rtp_file.size.should > 0
120
+ it "retries MAX_PORT_NUMBER_RETRIES times then raises" do
121
+ expect { subject.init_udp_server(subject.rtp_port) }.to raise_error Errno::EADDRINUSE
122
122
  end
123
123
 
124
- it "closes the @server after issuing a #stop" do
125
- @capturer.instance_variable_get(:@server).should_not be_closed
126
- @capturer.stop
127
- sleep 0.1
128
- @capturer.instance_variable_get(:@server).should be_closed
124
+ it "sets @rtp_port back to 9000 after trying all" do
125
+ expect { subject.init_udp_server(subject.rtp_port) }.to raise_error Errno::EADDRINUSE
126
+ subject.rtp_port.should == 9000
129
127
  end
130
128
  end
131
129
  end
132
130
 
131
+ describe "#init_tcp_server" do
132
+ it "returns a TCPSocket" do
133
+ subject.init_tcp_server(3456).should be_a TCPSocket
134
+ end
135
+
136
+ it "uses port a port between 9000 and 9000 + MAX_PORT_NUMBER_RETRIES" do
137
+ subject.init_tcp_server(9000)
138
+ subject.rtp_port.should >= 9000
139
+ subject.rtp_port.should <= 9000 + RTSP::Capturer::MAX_PORT_NUMBER_RETRIES
140
+ end
141
+ end
142
+
143
+ describe "#run" do
144
+ after(:each) { subject.stop }
145
+
146
+ it "calls #start_file_builder and #start_listener" do
147
+ subject.should_receive(:start_listener)
148
+ subject.should_receive(:start_file_builder)
149
+ subject.run
150
+ end
151
+ end
152
+
133
153
  describe "#running?" do
134
- before { @capturer = RTSP::Capturer.new }
154
+ after(:each) { subject.stop }
135
155
 
136
156
  it "returns false before issuing #run" do
137
- @capturer.running?.should be_false
157
+ subject.running?.should be_false
138
158
  end
139
159
 
140
160
  it "returns true after running" do
141
- cap_thread = Thread.new(@capturer) { |capturer| capturer.run }
142
- sleep 0.1
143
- @capturer.running?.should be_true
144
- cap_thread.exit
161
+ subject.run
162
+ subject.running?.should be_true
145
163
  end
146
164
 
147
- it "returns false after running, then stopping" do
148
- cap_thread = Thread.new(@capturer) { |capturer| capturer.run }
149
- sleep 0.1
150
- @capturer.running?.should be_true
151
- @capturer.stop
152
- @capturer.running?.should be_false
153
- cap_thread.exit
165
+ it "returns false after running then stopping" do
166
+ subject.run
167
+ subject.running?.should be_true
168
+ subject.stop
169
+ subject.running?.should be_false
154
170
  end
155
171
  end
156
172
 
157
173
  describe "#stop" do
158
- before { @capturer = RTSP::Capturer.new }
174
+ it "calls #stop_listener" do
175
+ subject.should_receive(:stop_listener)
176
+ subject.stop
177
+ end
159
178
 
160
- context "not running yet" do
161
- it "sets @run to false" do
162
- @capturer.stop
163
- @capturer.instance_variable_get(:@run).should == false
164
- end
179
+ it "calls #stop_file_builder" do
180
+ subject.should_receive(:stop_file_builder)
181
+ subject.stop
165
182
  end
166
183
 
167
- context "running" do
168
- it "sets @run to false" do
169
- Thread.new(@capturer) { |c| c.run }
170
- sleep 0.1
171
- @capturer.stop
172
- @capturer.instance_variable_get(:@run).should == false
173
- end
184
+ it "sets @queue back to a new Queue" do
185
+ queue = subject.instance_variable_get(:@queue)
186
+ subject.stop
187
+ subject.instance_variable_get(:@queue).should_not equal queue
188
+ subject.instance_variable_get(:@queue).should_not be_nil
174
189
  end
175
190
  end
176
191
 
177
- describe "#init_udp_server" do
178
- after :each do
179
- unless @sockets.nil?
180
- @sockets.each { |s| s.close }
192
+ [
193
+ {
194
+ start_method: "start_file_builder",
195
+ stop_method: "stop_file_builder",
196
+ ivar: "@file_builder"
197
+ },
198
+ {
199
+ start_method: "start_listener",
200
+ stop_method: "stop_listener",
201
+ ivar: "@listener"
202
+ }
203
+ ].each do |method_set|
204
+ describe "##{method_set[:start_method]}" do
205
+ before(:each) do
206
+ rtp_file = double "rtp_file"
207
+ rtp_file.stub(:write)
208
+ subject.rtp_file = rtp_file
209
+
210
+ server = double "A Server"
211
+ server.stub_chain(:recvfrom, :first).and_return("not nil")
212
+ subject.stub(:init_server).and_return(server)
181
213
  end
182
- end
183
-
184
- it "returns a UDPSocket" do
185
- capturer = RTSP::Capturer.new
186
- server = capturer.init_udp_server(capturer.rtp_port)
187
- server.should be_a UDPSocket
188
- end
189
-
190
- it "retries MAX_PORT_NUMBER_RETRIES to get a port" do
191
- @sockets = use_udp_ports 9000...(9000 + RTSP::Capturer::MAX_PORT_NUMBER_RETRIES)
192
- #@sockets.each { |s| puts "meow: #{s.addr[1]}" }
193
-
194
- capturer = RTSP::Capturer.new
195
- capturer.init_udp_server(capturer.rtp_port)
196
- capturer.rtp_port.should == 9000 + RTSP::Capturer::MAX_PORT_NUMBER_RETRIES
197
- end
198
214
 
199
- context "when no available ports, it retries MAX_PORT_NUMBER_RETRIES times, then" do
200
- before do
201
- @sockets = use_udp_ports 9000..(9000 + RTSP::Capturer::MAX_PORT_NUMBER_RETRIES)
215
+ after(:each) { subject.send(method_set[:stop_method].to_sym) }
202
216
 
203
- @capturer = RTSP::Capturer.new
217
+ it "starts the #{method_set[:ivar]} thread" do
218
+ subject.send(method_set[:start_method])
219
+ subject.instance_variable_get(method_set[:ivar].to_sym).should be_a Thread
204
220
  end
205
221
 
206
- it "retries MAX_PORT_NUMBER_RETRIES times then raises" do
207
- expect { @capturer.init_udp_server(@capturer.rtp_port) }.to raise_error Errno::EADDRINUSE
222
+ it "returns the same #{method_set[:ivar]} if already started" do
223
+ subject.send(method_set[:start_method])
224
+ original_ivar = subject.instance_variable_get(method_set[:ivar].to_sym)
225
+ new_ivar = subject.send method_set[:start_method].to_sym
226
+ original_ivar.should equal new_ivar
208
227
  end
209
228
 
210
- it "sets @rtp_port back to 9000 after trying all" do
211
- expect { @capturer.init_udp_server(@capturer.rtp_port) }.to raise_error Errno::EADDRINUSE
212
- @capturer.rtp_port.should == 9000
229
+ if method_set[:start_method] == "start_listener"
230
+ it "pushes data on to the @queue" do
231
+ subject.start_listener
232
+ subject.instance_variable_get(:@queue).pop.should == "not nil"
233
+ end
213
234
  end
214
235
  end
215
- end
216
236
 
217
- describe "#init_tcp_server" do
218
- before do
219
- @capturer = RTSP::Capturer.new(:TCP)
220
- @server = @capturer.init_tcp_server(@capturer.rtp_port)
221
- end
237
+ describe "##{method_set[:stop_method]}" do
238
+ context "#{method_set[:ivar]} thread is running" do
239
+ before { subject.send(method_set[:start_method]) }
222
240
 
223
- it "returns a TCPSocket" do
224
- @server.should be_a TCPSocket
225
- end
241
+ it "kills the thread" do
242
+ original_ivar = subject.instance_variable_get(method_set[:ivar].to_sym)
243
+ original_ivar.should_receive(:kill)
244
+ subject.send(method_set[:stop_method])
245
+ end
246
+ end
226
247
 
227
- it "uses port a port between 9000 and 9000 + MAX_PORT_NUMBER_RETRIES" do
228
- @capturer.rtp_port.should >= 9000
229
- @capturer.rtp_port.should <= 9000 + RTSP::Capturer::MAX_PORT_NUMBER_RETRIES
248
+ context "#{method_set[:ivar]} thread isn't running" do
249
+ it "doesn't try to kill the thread" do
250
+ allow_message_expectations_on_nil
251
+ original_ivar = subject.instance_variable_get(method_set[:ivar].to_sym)
252
+ original_ivar.should_not_receive(:kill)
253
+ subject.send(method_set[:stop_method])
254
+ end
255
+ end
230
256
  end
231
257
  end
232
258
  end
@@ -36,21 +36,21 @@ describe "RTSP::Message" do
36
36
  context "builds a DESCRIBE string" do
37
37
  it "with default sequence and accept values" do
38
38
  message = RTSP::Message.describe(@stream)
39
- message.to_s.should match /^DESCRIBE rtsp:/
39
+ message.to_s.should match(/^DESCRIBE rtsp:/)
40
40
  message.to_s.should include "DESCRIBE rtsp://1.2.3.4:554/stream1 RTSP/1.0\r\n"
41
41
  message.to_s.should include "CSeq: 1\r\n"
42
42
  message.to_s.should include "Accept: application/sdp\r\n"
43
- message.to_s.should match /\r\n\r\n$/
43
+ message.to_s.should match(/\r\n\r\n$/)
44
44
  end
45
45
 
46
46
  it "with default sequence value" do
47
47
  message = RTSP::Message.describe(@stream).with_headers({
48
48
  accept: 'application/sdp, application/rtsl' })
49
- message.to_s.should match /^DESCRIBE rtsp:/
49
+ message.to_s.should match(/^DESCRIBE rtsp:/)
50
50
  message.to_s.should include "DESCRIBE rtsp://1.2.3.4:554/stream1 RTSP/1.0\r\n"
51
51
  message.to_s.should include "CSeq: 1\r\n"
52
52
  message.to_s.should include "Accept: application/sdp, application/rtsl\r\n"
53
- message.to_s.should match /\r\n\r\n$/
53
+ message.to_s.should match(/\r\n\r\n$/)
54
54
  end
55
55
 
56
56
  it "with new sequence and accept values" do
@@ -58,11 +58,11 @@ describe "RTSP::Message" do
58
58
  accept: 'application/sdp, application/rtsl',
59
59
  cseq: 2345 })
60
60
 
61
- message.to_s.should match /^DESCRIBE rtsp:/
61
+ message.to_s.should match(/^DESCRIBE rtsp:/)
62
62
  message.to_s.should include "DESCRIBE rtsp://1.2.3.4:554/stream1 RTSP/1.0\r\n"
63
63
  message.to_s.should include "CSeq: 2345\r\n"
64
64
  message.to_s.should include "Accept: application/sdp, application/rtsl\r\n"
65
- message.to_s.should match /\r\n\r\n$/
65
+ message.to_s.should match(/\r\n\r\n$/)
66
66
  end
67
67
  end
68
68
 
@@ -70,12 +70,12 @@ describe "RTSP::Message" do
70
70
  it "with default sequence, content type, but no body" do
71
71
  message = RTSP::Message.announce(@stream).with_headers({ session: 123456789 })
72
72
 
73
- message.to_s.should match /^ANNOUNCE rtsp:/
73
+ message.to_s.should match(/^ANNOUNCE rtsp:/)
74
74
  message.to_s.should include "ANNOUNCE rtsp://1.2.3.4:554/stream1 RTSP/1.0\r\n"
75
75
  message.to_s.should include "CSeq: 1\r\n"
76
76
  message.to_s.should include "Session: 123456789\r\n"
77
77
  message.to_s.should include "Content-Type: application/sdp\r\n"
78
- message.to_s.should match /\r\n\r\n$/
78
+ message.to_s.should match(/\r\n\r\n$/)
79
79
  end
80
80
 
81
81
  it "with passed-in session and content type but no body" do
@@ -83,12 +83,12 @@ describe "RTSP::Message" do
83
83
  session: 123456789,
84
84
  content_type: 'application/sdp, application/rtsl' })
85
85
 
86
- message.to_s.should match /^ANNOUNCE rtsp:/
86
+ message.to_s.should match(/^ANNOUNCE rtsp:/)
87
87
  message.to_s.should include "ANNOUNCE rtsp://1.2.3.4:554/stream1 RTSP/1.0\r\n"
88
88
  message.to_s.should include "CSeq: 1\r\n"
89
89
  message.to_s.should include "Session: 123456789\r\n"
90
90
  message.to_s.should include "Content-Type: application/sdp, application/rtsl\r\n"
91
- message.to_s.should match /\r\n\r\n$/
91
+ message.to_s.should match(/\r\n\r\n$/)
92
92
  end
93
93
 
94
94
  it "with passed-in sequence, session, content-type, but no body " do
@@ -97,12 +97,12 @@ describe "RTSP::Message" do
97
97
  content_type: 'application/sdp, application/rtsl',
98
98
  cseq: 2345 })
99
99
 
100
- message.to_s.should match /^ANNOUNCE rtsp:/
100
+ message.to_s.should match(/^ANNOUNCE rtsp:/)
101
101
  message.to_s.should include "ANNOUNCE rtsp://1.2.3.4:554/stream1 RTSP/1.0\r\n"
102
102
  message.to_s.should include "CSeq: 2345\r\n"
103
103
  message.to_s.should include "Session: 123456789\r\n"
104
104
  message.to_s.should include "Content-Type: application/sdp, application/rtsl\r\n"
105
- message.to_s.should match /\r\n\r\n$/
105
+ message.to_s.should match(/\r\n\r\n$/)
106
106
  end
107
107
 
108
108
  it "with passed-in sequence, session, content-type, and SDP body" do
@@ -116,13 +116,13 @@ describe "RTSP::Message" do
116
116
  cseq: 2345 })
117
117
  message.body = sdp.to_s
118
118
 
119
- message.to_s.should match /^ANNOUNCE rtsp/
119
+ message.to_s.should match(/^ANNOUNCE rtsp/)
120
120
  message.to_s.should include "ANNOUNCE rtsp://1.2.3.4:554/stream1 RTSP/1.0\r\n"
121
121
  message.to_s.should include "CSeq: 2345\r\n"
122
122
  message.to_s.should include "Session: 123456789\r\n"
123
123
  message.to_s.should include "Content-Type: application/sdp\r\n"
124
124
  message.to_s.should include "Content-Length: 29\r\n"
125
- message.to_s.should match /\r\n\r\nv=1\r\no=bobo \r\ns=\r\nt= \r\n\r\n$/
125
+ message.to_s.should match(/\r\n\r\nv=1\r\no=bobo \r\ns=\r\nt= \r\n\r\n$/)
126
126
  end
127
127
  end
128
128
 
@@ -130,21 +130,21 @@ describe "RTSP::Message" do
130
130
  it "with default sequence, client_port, and routing values" do
131
131
  message = RTSP::Message.setup(@stream)
132
132
 
133
- message.to_s.should match /^SETUP rtsp/
133
+ message.to_s.should match(/^SETUP rtsp/)
134
134
  message.to_s.should include "SETUP rtsp://1.2.3.4:554/stream1 RTSP/1.0\r\n"
135
135
  message.to_s.should include "CSeq: 1\r\n"
136
- message.to_s.should match /\r\n\r\n$/
136
+ message.to_s.should match(/\r\n\r\n$/)
137
137
  end
138
138
 
139
139
  it "with default sequence, transport, and client_port values" do
140
140
  message = RTSP::Message.setup(@stream).with_headers({
141
141
  transport: ["RTP/AVP", "multicast", { :client_port => "9000-9001" }] })
142
142
 
143
- message.to_s.should match /^SETUP rtsp/
143
+ message.to_s.should match(/^SETUP rtsp/)
144
144
  message.to_s.should include "SETUP rtsp://1.2.3.4:554/stream1 RTSP/1.0\r\n"
145
145
  message.to_s.should include "CSeq: 1\r\n"
146
146
  message.to_s.should include "Transport: RTP/AVP;multicast;client_port=9000-9001\r\n"
147
- message.to_s.should match /\r\n\r\n$/
147
+ message.to_s.should match(/\r\n\r\n$/)
148
148
  end
149
149
 
150
150
  it "with default transport, client_port, and routing values" do
@@ -152,11 +152,11 @@ describe "RTSP::Message" do
152
152
  transport: ["RTP/AVP", "multicast", { :client_port => "9000-9001" }],
153
153
  cseq: 2345 })
154
154
 
155
- message.to_s.should match /^SETUP rtsp/
155
+ message.to_s.should match(/^SETUP rtsp/)
156
156
  message.to_s.should include "SETUP rtsp://1.2.3.4:554/stream1 RTSP/1.0\r\n"
157
157
  message.to_s.should include "CSeq: 2345\r\n"
158
158
  message.to_s.should include "Transport: RTP/AVP;multicast;client_port=9000-9001\r\n"
159
- message.to_s.should match /\r\n\r\n$/
159
+ message.to_s.should match(/\r\n\r\n$/)
160
160
  end
161
161
  end
162
162
 
@@ -165,12 +165,12 @@ describe "RTSP::Message" do
165
165
  message = RTSP::Message.play(@stream).with_headers({
166
166
  session: 123456789 })
167
167
 
168
- message.to_s.should match /^PLAY rtsp/
168
+ message.to_s.should match(/^PLAY rtsp/)
169
169
  message.to_s.should include "PLAY rtsp://1.2.3.4:554/stream1 RTSP/1.0\r\n"
170
170
  message.to_s.should include "CSeq: 1\r\n"
171
171
  message.to_s.should include "Session: 123456789\r\n"
172
172
  message.to_s.should include "Range: npt=0.000-\r\n"
173
- message.to_s.should match /\r\n\r\n/
173
+ message.to_s.should match(/\r\n\r\n/)
174
174
  end
175
175
 
176
176
  it "with default sequence value" do
@@ -178,12 +178,12 @@ describe "RTSP::Message" do
178
178
  session: 123456789,
179
179
  range: { :npt => "0.000-1.234" } })
180
180
 
181
- message.to_s.should match /^PLAY rtsp/
181
+ message.to_s.should match(/^PLAY rtsp/)
182
182
  message.to_s.should include "PLAY rtsp://1.2.3.4:554/stream1 RTSP/1.0\r\n"
183
183
  message.to_s.should include "CSeq: 1\r\n"
184
184
  message.to_s.should include "Session: 123456789\r\n"
185
185
  message.to_s.should include "Range: npt=0.000-1.234\r\n"
186
- message.to_s.should match /\r\n\r\n/
186
+ message.to_s.should match(/\r\n\r\n/)
187
187
  end
188
188
  end
189
189
 
@@ -191,10 +191,10 @@ describe "RTSP::Message" do
191
191
  it "with required Request values" do
192
192
  message = RTSP::Message.pause(@stream)
193
193
 
194
- message.to_s.should match /^PAUSE rtsp/
194
+ message.to_s.should match(/^PAUSE rtsp/)
195
195
  message.to_s.should include "PAUSE rtsp://1.2.3.4:554/stream1 RTSP/1.0\r\n"
196
196
  message.to_s.should include "CSeq: 1\r\n"
197
- message.to_s.should match /\r\n\r\n/
197
+ message.to_s.should match(/\r\n\r\n/)
198
198
  end
199
199
 
200
200
  it "with session and range headers" do
@@ -202,12 +202,12 @@ describe "RTSP::Message" do
202
202
  session: 123456789,
203
203
  range: { :npt => "0.000" } })
204
204
 
205
- message.to_s.should match /^PAUSE rtsp/
205
+ message.to_s.should match(/^PAUSE rtsp/)
206
206
  message.to_s.should include "PAUSE rtsp://1.2.3.4:554/stream1 RTSP/1.0\r\n"
207
207
  message.to_s.should include "CSeq: 1\r\n"
208
208
  message.to_s.should include "Session: 123456789\r\n"
209
209
  message.to_s.should include "Range: npt=0.000\r\n"
210
- message.to_s.should match /\r\n\r\n/
210
+ message.to_s.should match(/\r\n\r\n/)
211
211
  end
212
212
  end
213
213
 
@@ -215,21 +215,21 @@ describe "RTSP::Message" do
215
215
  it "with required Request values" do
216
216
  message = RTSP::Message.teardown(@stream)
217
217
 
218
- message.to_s.should match /^TEARDOWN rtsp/
218
+ message.to_s.should match(/^TEARDOWN rtsp/)
219
219
  message.to_s.should include "TEARDOWN rtsp://1.2.3.4:554/stream1 RTSP/1.0\r\n"
220
220
  message.to_s.should include "CSeq: 1\r\n"
221
- message.to_s.should match /\r\n\r\n/
221
+ message.to_s.should match(/\r\n\r\n/)
222
222
  end
223
223
 
224
224
  it "with session and range headers" do
225
225
  message = RTSP::Message.teardown(@stream).with_headers({
226
226
  session: 123456789 })
227
227
 
228
- message.to_s.should match /^TEARDOWN rtsp/
228
+ message.to_s.should match(/^TEARDOWN rtsp/)
229
229
  message.to_s.should include "TEARDOWN rtsp://1.2.3.4:554/stream1 RTSP/1.0\r\n"
230
230
  message.to_s.should include "CSeq: 1\r\n"
231
231
  message.to_s.should include "Session: 123456789\r\n"
232
- message.to_s.should match /\r\n\r\n/
232
+ message.to_s.should match(/\r\n\r\n/)
233
233
  end
234
234
  end
235
235
 
@@ -237,10 +237,10 @@ describe "RTSP::Message" do
237
237
  it "with required Request values" do
238
238
  message = RTSP::Message.get_parameter(@stream)
239
239
 
240
- message.to_s.should match /^GET_PARAMETER rtsp/
240
+ message.to_s.should match(/^GET_PARAMETER rtsp/)
241
241
  message.to_s.should include "GET_PARAMETER rtsp://1.2.3.4:554/stream1 RTSP/1.0\r\n"
242
242
  message.to_s.should include "CSeq: 1\r\n"
243
- message.to_s.should match /\r\n\r\n/
243
+ message.to_s.should match(/\r\n\r\n/)
244
244
  end
245
245
 
246
246
  it "with cseq, content type, session headers, and text body" do
@@ -253,14 +253,14 @@ describe "RTSP::Message" do
253
253
 
254
254
  message.body = the_body
255
255
 
256
- message.to_s.should match /^GET_PARAMETER rtsp/
256
+ message.to_s.should match(/^GET_PARAMETER rtsp/)
257
257
  message.to_s.should include "GET_PARAMETER rtsp://1.2.3.4:554/stream1 RTSP/1.0\r\n"
258
258
  message.to_s.should include "CSeq: 431\r\n"
259
259
  message.to_s.should include "Session: 123456789\r\n"
260
260
  message.to_s.should include "Content-Type: text/parameters\r\n"
261
261
  message.to_s.should include "Content-Length: #{the_body.length}\r\n"
262
262
  message.to_s.should include the_body
263
- message.to_s.should match /\r\n\r\n/
263
+ message.to_s.should match(/\r\n\r\n/)
264
264
  end
265
265
  end
266
266
 
@@ -268,10 +268,10 @@ describe "RTSP::Message" do
268
268
  it "with required Request values" do
269
269
  message = RTSP::Message.set_parameter(@stream)
270
270
 
271
- message.to_s.should match /^SET_PARAMETER rtsp/
271
+ message.to_s.should match(/^SET_PARAMETER rtsp/)
272
272
  message.to_s.should include "SET_PARAMETER rtsp://1.2.3.4:554/stream1 RTSP/1.0\r\n"
273
273
  message.to_s.should include "CSeq: 1\r\n"
274
- message.to_s.should match /\r\n\r\n/
274
+ message.to_s.should match(/\r\n\r\n/)
275
275
  end
276
276
 
277
277
  it "with cseq, content type, session headers, and text body" do
@@ -283,14 +283,14 @@ describe "RTSP::Message" do
283
283
  session: 123456789 })
284
284
  message.body = the_body
285
285
 
286
- message.to_s.should match /^SET_PARAMETER rtsp/
286
+ message.to_s.should match(/^SET_PARAMETER rtsp/)
287
287
  message.to_s.should include "SET_PARAMETER rtsp://1.2.3.4:554/stream1 RTSP/1.0\r\n"
288
288
  message.to_s.should include "CSeq: 431\r\n"
289
289
  message.to_s.should include "Session: 123456789\r\n"
290
290
  message.to_s.should include "Content-Type: text/parameters\r\n"
291
291
  message.to_s.should include "Content-Length: #{the_body.length}\r\n"
292
292
  message.to_s.should include the_body
293
- message.to_s.should match /\r\n\r\n/
293
+ message.to_s.should match(/\r\n\r\n/)
294
294
  end
295
295
  end
296
296
 
@@ -298,10 +298,10 @@ describe "RTSP::Message" do
298
298
  it "with required Request values" do
299
299
  message = RTSP::Message.redirect(@stream)
300
300
 
301
- message.to_s.should match /^REDIRECT rtsp/
301
+ message.to_s.should match(/^REDIRECT rtsp/)
302
302
  message.to_s.should include "REDIRECT rtsp://1.2.3.4:554/stream1 RTSP/1.0\r\n"
303
303
  message.to_s.should include "CSeq: 1\r\n"
304
- message.to_s.should match /\r\n\r\n/
304
+ message.to_s.should match(/\r\n\r\n/)
305
305
  end
306
306
 
307
307
  it "with cseq, location, and range headers" do
@@ -310,12 +310,12 @@ describe "RTSP::Message" do
310
310
  location: "rtsp://bigserver.com:8001",
311
311
  range: { :clock => "19960213T143205Z-" } })
312
312
 
313
- message.to_s.should match /^REDIRECT rtsp/
313
+ message.to_s.should match(/^REDIRECT rtsp/)
314
314
  message.to_s.should include "REDIRECT rtsp://1.2.3.4:554/stream1 RTSP/1.0\r\n"
315
315
  message.to_s.should include "CSeq: 732\r\n"
316
316
  message.to_s.should include "Location: rtsp://bigserver.com:8001\r\n"
317
317
  message.to_s.should include "Range: clock=19960213T143205Z-\r\n"
318
- message.to_s.should match /\r\n\r\n/
318
+ message.to_s.should match(/\r\n\r\n/)
319
319
  end
320
320
  end
321
321
 
@@ -323,10 +323,10 @@ describe "RTSP::Message" do
323
323
  it "with required Request values" do
324
324
  message = RTSP::Message.record(@stream)
325
325
 
326
- message.to_s.should match /^RECORD rtsp/
326
+ message.to_s.should match(/^RECORD rtsp/)
327
327
  message.to_s.should include "RECORD rtsp://1.2.3.4:554/stream1 RTSP/1.0\r\n"
328
328
  message.to_s.should include "CSeq: 1\r\n"
329
- message.to_s.should match /\r\n\r\n/
329
+ message.to_s.should match(/\r\n\r\n/)
330
330
  end
331
331
 
332
332
  it "with cseq, session, and conference headers" do
@@ -335,12 +335,12 @@ describe "RTSP::Message" do
335
335
  session: 12345678,
336
336
  conference: "128.16.64.19/32492374" })
337
337
 
338
- message.to_s.should match /^RECORD rtsp/
338
+ message.to_s.should match(/^RECORD rtsp/)
339
339
  message.to_s.should include "RECORD rtsp://1.2.3.4:554/stream1 RTSP/1.0\r\n"
340
340
  message.to_s.should include "CSeq: 954\r\n"
341
341
  message.to_s.should include "Session: 12345678\r\n"
342
342
  message.to_s.should include "Conference: 128.16.64.19/32492374\r\n"
343
- message.to_s.should match /\r\n\r\n/
343
+ message.to_s.should match(/\r\n\r\n/)
344
344
  end
345
345
  end
346
346
 
@@ -390,13 +390,13 @@ describe "RTSP::Message" do
390
390
  it "adds the passed-in text to the body of the message" do
391
391
  new_body = "1234567890"
392
392
  message = RTSP::Message.record("rtsp://localhost/track").with_body(new_body)
393
- message.to_s.should match /\r\n\r\n#{new_body}$/
393
+ message.to_s.should match(/\r\n\r\n#{new_body}$/)
394
394
  end
395
395
 
396
396
  it "adds the Content-Length header to reflect the body" do
397
397
  new_body = "1234567890"
398
398
  message = RTSP::Message.record("rtsp://localhost/track").with_body(new_body)
399
- message.to_s.should match /Content-Length: #{new_body.size}\r\n/
399
+ message.to_s.should match(/Content-Length: #{new_body.size}\r\n/)
400
400
  end
401
401
  end
402
402
 
@@ -64,11 +64,11 @@ describe RTSP::Response do
64
64
  end
65
65
 
66
66
  it "contains the class name and object ID first" do
67
- @response.inspect.should match /^#<RTSP::Response:\d+/
67
+ @response.inspect.should match(/^#<RTSP::Response:\d+/)
68
68
  end
69
69
 
70
70
  it "begins with <# and ends with >" do
71
- @response.inspect.should match /^#<.*>$/
71
+ @response.inspect.should match(/^#<.*>$/)
72
72
  end
73
73
  end
74
74
 
@@ -21,7 +21,7 @@ describe RTSP do
21
21
  RTSP.const_defined?('VERSION').should be_true
22
22
  end
23
23
 
24
- it "has version 0.2.1" do
25
- RTSP::VERSION.should == '0.2.1'
24
+ it "has version 0.2.2" do
25
+ RTSP::VERSION.should == '0.2.2'
26
26
  end
27
27
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rtsp
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.1
4
+ version: 0.2.2
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,22 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2011-04-14 00:00:00.000000000Z
12
+ date: 2011-04-14 00:00:00.000000000 Z
13
13
  dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: parslet
16
+ requirement: &70200108735200 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: 1.1.0
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: *70200108735200
14
25
  - !ruby/object:Gem::Dependency
15
26
  name: sdp
16
- requirement: &70124087370880 !ruby/object:Gem::Requirement
27
+ requirement: &70200108733900 !ruby/object:Gem::Requirement
17
28
  none: false
18
29
  requirements:
19
30
  - - ~>
@@ -21,10 +32,10 @@ dependencies:
21
32
  version: 0.2.2
22
33
  type: :runtime
23
34
  prerelease: false
24
- version_requirements: *70124087370880
35
+ version_requirements: *70200108733900
25
36
  - !ruby/object:Gem::Dependency
26
37
  name: bundler
27
- requirement: &70124087370060 !ruby/object:Gem::Requirement
38
+ requirement: &70200108733140 !ruby/object:Gem::Requirement
28
39
  none: false
29
40
  requirements:
30
41
  - - ~>
@@ -32,10 +43,10 @@ dependencies:
32
43
  version: 1.0.0
33
44
  type: :development
34
45
  prerelease: false
35
- version_requirements: *70124087370060
46
+ version_requirements: *70200108733140
36
47
  - !ruby/object:Gem::Dependency
37
48
  name: code_statistics
38
- requirement: &70124087369300 !ruby/object:Gem::Requirement
49
+ requirement: &70200108731600 !ruby/object:Gem::Requirement
39
50
  none: false
40
51
  requirements:
41
52
  - - ~>
@@ -43,10 +54,10 @@ dependencies:
43
54
  version: 0.2.13
44
55
  type: :development
45
56
  prerelease: false
46
- version_requirements: *70124087369300
57
+ version_requirements: *70200108731600
47
58
  - !ruby/object:Gem::Dependency
48
59
  name: metric_fu
49
- requirement: &70124087368480 !ruby/object:Gem::Requirement
60
+ requirement: &70200108731040 !ruby/object:Gem::Requirement
50
61
  none: false
51
62
  requirements:
52
63
  - - ! '>='
@@ -54,10 +65,10 @@ dependencies:
54
65
  version: 2.0.0
55
66
  type: :development
56
67
  prerelease: false
57
- version_requirements: *70124087368480
68
+ version_requirements: *70200108731040
58
69
  - !ruby/object:Gem::Dependency
59
70
  name: rspec
60
- requirement: &70124087367800 !ruby/object:Gem::Requirement
71
+ requirement: &70200108730460 !ruby/object:Gem::Requirement
61
72
  none: false
62
73
  requirements:
63
74
  - - ! '>='
@@ -65,10 +76,10 @@ dependencies:
65
76
  version: 2.5.0
66
77
  type: :development
67
78
  prerelease: false
68
- version_requirements: *70124087367800
79
+ version_requirements: *70200108730460
69
80
  - !ruby/object:Gem::Dependency
70
81
  name: simplecov
71
- requirement: &70124087367180 !ruby/object:Gem::Requirement
82
+ requirement: &70200108729440 !ruby/object:Gem::Requirement
72
83
  none: false
73
84
  requirements:
74
85
  - - ! '>='
@@ -76,10 +87,10 @@ dependencies:
76
87
  version: 0.4.0
77
88
  type: :development
78
89
  prerelease: false
79
- version_requirements: *70124087367180
90
+ version_requirements: *70200108729440
80
91
  - !ruby/object:Gem::Dependency
81
92
  name: yard
82
- requirement: &70124087365940 !ruby/object:Gem::Requirement
93
+ requirement: &70200108727820 !ruby/object:Gem::Requirement
83
94
  none: false
84
95
  requirements:
85
96
  - - ! '>='
@@ -87,7 +98,7 @@ dependencies:
87
98
  version: 0.6.0
88
99
  type: :development
89
100
  prerelease: false
90
- version_requirements: *70124087365940
101
+ version_requirements: *70200108727820
91
102
  description: ! 'This library intends to follow the RTSP RFC document (2326)
92
103
 
93
104
  to allow for working with RTSP servers. At this point, it''s up to you to parse
@@ -187,3 +198,4 @@ test_files:
187
198
  - features/step_definitions/control_streams_as_client_steps.rb
188
199
  - features/support/env.rb
189
200
  - features/support/hooks.rb
201
+ has_rdoc: