rtsp 0.2.1 → 0.2.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.
@@ -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: