rtsp 0.4.1 → 0.4.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (105) hide show
  1. data/ChangeLog.rdoc +10 -0
  2. data/Gemfile +1 -1
  3. data/README.rdoc +52 -38
  4. data/Rakefile +2 -8
  5. data/bin/rtsp_client +3 -3
  6. data/lib/rtsp/client.rb +69 -85
  7. data/lib/rtsp/message.rb +4 -5
  8. data/lib/rtsp/presentation.rb +1 -1
  9. data/lib/rtsp/session.rb +1 -1
  10. data/lib/rtsp/version.rb +1 -1
  11. data/rtsp.gemspec +13 -14
  12. data/spec/integration/client_use_spec.rb +206 -0
  13. data/spec/integration/coverage/index.html +1 -1
  14. data/spec/spec_helper.rb +2 -1
  15. data/spec/support/fake_rtsp_server.rb +1 -1
  16. data/spec/unit/rtsp/client_spec.rb +407 -0
  17. data/spec/{rtsp → unit/rtsp}/helpers_spec.rb +1 -1
  18. data/spec/{rtsp → unit/rtsp}/message_spec.rb +1 -1
  19. data/spec/{rtsp → unit/rtsp}/response_spec.rb +1 -1
  20. data/spec/{rtsp → unit/rtsp}/transport_parser_spec.rb +1 -1
  21. data/spec/{rtsp_spec.rb → unit/rtsp_spec.rb} +3 -3
  22. metadata +22 -185
  23. data/spec/rtsp/client_spec.rb +0 -326
  24. data/spec/rtsp/coverage/assets/0.7.1/application.css +0 -1110
  25. data/spec/rtsp/coverage/assets/0.7.1/application.js +0 -626
  26. data/spec/rtsp/coverage/assets/0.7.1/fancybox/blank.gif +0 -0
  27. data/spec/rtsp/coverage/assets/0.7.1/fancybox/fancy_close.png +0 -0
  28. data/spec/rtsp/coverage/assets/0.7.1/fancybox/fancy_loading.png +0 -0
  29. data/spec/rtsp/coverage/assets/0.7.1/fancybox/fancy_nav_left.png +0 -0
  30. data/spec/rtsp/coverage/assets/0.7.1/fancybox/fancy_nav_right.png +0 -0
  31. data/spec/rtsp/coverage/assets/0.7.1/fancybox/fancy_shadow_e.png +0 -0
  32. data/spec/rtsp/coverage/assets/0.7.1/fancybox/fancy_shadow_n.png +0 -0
  33. data/spec/rtsp/coverage/assets/0.7.1/fancybox/fancy_shadow_ne.png +0 -0
  34. data/spec/rtsp/coverage/assets/0.7.1/fancybox/fancy_shadow_nw.png +0 -0
  35. data/spec/rtsp/coverage/assets/0.7.1/fancybox/fancy_shadow_s.png +0 -0
  36. data/spec/rtsp/coverage/assets/0.7.1/fancybox/fancy_shadow_se.png +0 -0
  37. data/spec/rtsp/coverage/assets/0.7.1/fancybox/fancy_shadow_sw.png +0 -0
  38. data/spec/rtsp/coverage/assets/0.7.1/fancybox/fancy_shadow_w.png +0 -0
  39. data/spec/rtsp/coverage/assets/0.7.1/fancybox/fancy_title_left.png +0 -0
  40. data/spec/rtsp/coverage/assets/0.7.1/fancybox/fancy_title_main.png +0 -0
  41. data/spec/rtsp/coverage/assets/0.7.1/fancybox/fancy_title_over.png +0 -0
  42. data/spec/rtsp/coverage/assets/0.7.1/fancybox/fancy_title_right.png +0 -0
  43. data/spec/rtsp/coverage/assets/0.7.1/fancybox/fancybox-x.png +0 -0
  44. data/spec/rtsp/coverage/assets/0.7.1/fancybox/fancybox-y.png +0 -0
  45. data/spec/rtsp/coverage/assets/0.7.1/fancybox/fancybox.png +0 -0
  46. data/spec/rtsp/coverage/assets/0.7.1/favicon_green.png +0 -0
  47. data/spec/rtsp/coverage/assets/0.7.1/favicon_red.png +0 -0
  48. data/spec/rtsp/coverage/assets/0.7.1/favicon_yellow.png +0 -0
  49. data/spec/rtsp/coverage/assets/0.7.1/loading.gif +0 -0
  50. data/spec/rtsp/coverage/assets/0.7.1/magnify.png +0 -0
  51. data/spec/rtsp/coverage/assets/0.7.1/smoothness/images/ui-bg_flat_0_aaaaaa_40x100.png +0 -0
  52. data/spec/rtsp/coverage/assets/0.7.1/smoothness/images/ui-bg_flat_75_ffffff_40x100.png +0 -0
  53. data/spec/rtsp/coverage/assets/0.7.1/smoothness/images/ui-bg_glass_55_fbf9ee_1x400.png +0 -0
  54. data/spec/rtsp/coverage/assets/0.7.1/smoothness/images/ui-bg_glass_65_ffffff_1x400.png +0 -0
  55. data/spec/rtsp/coverage/assets/0.7.1/smoothness/images/ui-bg_glass_75_dadada_1x400.png +0 -0
  56. data/spec/rtsp/coverage/assets/0.7.1/smoothness/images/ui-bg_glass_75_e6e6e6_1x400.png +0 -0
  57. data/spec/rtsp/coverage/assets/0.7.1/smoothness/images/ui-bg_glass_95_fef1ec_1x400.png +0 -0
  58. data/spec/rtsp/coverage/assets/0.7.1/smoothness/images/ui-bg_highlight-soft_75_cccccc_1x100.png +0 -0
  59. data/spec/rtsp/coverage/assets/0.7.1/smoothness/images/ui-icons_222222_256x240.png +0 -0
  60. data/spec/rtsp/coverage/assets/0.7.1/smoothness/images/ui-icons_2e83ff_256x240.png +0 -0
  61. data/spec/rtsp/coverage/assets/0.7.1/smoothness/images/ui-icons_454545_256x240.png +0 -0
  62. data/spec/rtsp/coverage/assets/0.7.1/smoothness/images/ui-icons_888888_256x240.png +0 -0
  63. data/spec/rtsp/coverage/assets/0.7.1/smoothness/images/ui-icons_cd0a0a_256x240.png +0 -0
  64. data/spec/rtsp/coverage/index.html +0 -72
  65. data/spec/unit/rtsp/coverage/assets/0.7.1/application.css +0 -1110
  66. data/spec/unit/rtsp/coverage/assets/0.7.1/application.js +0 -626
  67. data/spec/unit/rtsp/coverage/assets/0.7.1/fancybox/blank.gif +0 -0
  68. data/spec/unit/rtsp/coverage/assets/0.7.1/fancybox/fancy_close.png +0 -0
  69. data/spec/unit/rtsp/coverage/assets/0.7.1/fancybox/fancy_loading.png +0 -0
  70. data/spec/unit/rtsp/coverage/assets/0.7.1/fancybox/fancy_nav_left.png +0 -0
  71. data/spec/unit/rtsp/coverage/assets/0.7.1/fancybox/fancy_nav_right.png +0 -0
  72. data/spec/unit/rtsp/coverage/assets/0.7.1/fancybox/fancy_shadow_e.png +0 -0
  73. data/spec/unit/rtsp/coverage/assets/0.7.1/fancybox/fancy_shadow_n.png +0 -0
  74. data/spec/unit/rtsp/coverage/assets/0.7.1/fancybox/fancy_shadow_ne.png +0 -0
  75. data/spec/unit/rtsp/coverage/assets/0.7.1/fancybox/fancy_shadow_nw.png +0 -0
  76. data/spec/unit/rtsp/coverage/assets/0.7.1/fancybox/fancy_shadow_s.png +0 -0
  77. data/spec/unit/rtsp/coverage/assets/0.7.1/fancybox/fancy_shadow_se.png +0 -0
  78. data/spec/unit/rtsp/coverage/assets/0.7.1/fancybox/fancy_shadow_sw.png +0 -0
  79. data/spec/unit/rtsp/coverage/assets/0.7.1/fancybox/fancy_shadow_w.png +0 -0
  80. data/spec/unit/rtsp/coverage/assets/0.7.1/fancybox/fancy_title_left.png +0 -0
  81. data/spec/unit/rtsp/coverage/assets/0.7.1/fancybox/fancy_title_main.png +0 -0
  82. data/spec/unit/rtsp/coverage/assets/0.7.1/fancybox/fancy_title_over.png +0 -0
  83. data/spec/unit/rtsp/coverage/assets/0.7.1/fancybox/fancy_title_right.png +0 -0
  84. data/spec/unit/rtsp/coverage/assets/0.7.1/fancybox/fancybox-x.png +0 -0
  85. data/spec/unit/rtsp/coverage/assets/0.7.1/fancybox/fancybox-y.png +0 -0
  86. data/spec/unit/rtsp/coverage/assets/0.7.1/fancybox/fancybox.png +0 -0
  87. data/spec/unit/rtsp/coverage/assets/0.7.1/favicon_green.png +0 -0
  88. data/spec/unit/rtsp/coverage/assets/0.7.1/favicon_red.png +0 -0
  89. data/spec/unit/rtsp/coverage/assets/0.7.1/favicon_yellow.png +0 -0
  90. data/spec/unit/rtsp/coverage/assets/0.7.1/loading.gif +0 -0
  91. data/spec/unit/rtsp/coverage/assets/0.7.1/magnify.png +0 -0
  92. data/spec/unit/rtsp/coverage/assets/0.7.1/smoothness/images/ui-bg_flat_0_aaaaaa_40x100.png +0 -0
  93. data/spec/unit/rtsp/coverage/assets/0.7.1/smoothness/images/ui-bg_flat_75_ffffff_40x100.png +0 -0
  94. data/spec/unit/rtsp/coverage/assets/0.7.1/smoothness/images/ui-bg_glass_55_fbf9ee_1x400.png +0 -0
  95. data/spec/unit/rtsp/coverage/assets/0.7.1/smoothness/images/ui-bg_glass_65_ffffff_1x400.png +0 -0
  96. data/spec/unit/rtsp/coverage/assets/0.7.1/smoothness/images/ui-bg_glass_75_dadada_1x400.png +0 -0
  97. data/spec/unit/rtsp/coverage/assets/0.7.1/smoothness/images/ui-bg_glass_75_e6e6e6_1x400.png +0 -0
  98. data/spec/unit/rtsp/coverage/assets/0.7.1/smoothness/images/ui-bg_glass_95_fef1ec_1x400.png +0 -0
  99. data/spec/unit/rtsp/coverage/assets/0.7.1/smoothness/images/ui-bg_highlight-soft_75_cccccc_1x100.png +0 -0
  100. data/spec/unit/rtsp/coverage/assets/0.7.1/smoothness/images/ui-icons_222222_256x240.png +0 -0
  101. data/spec/unit/rtsp/coverage/assets/0.7.1/smoothness/images/ui-icons_2e83ff_256x240.png +0 -0
  102. data/spec/unit/rtsp/coverage/assets/0.7.1/smoothness/images/ui-icons_454545_256x240.png +0 -0
  103. data/spec/unit/rtsp/coverage/assets/0.7.1/smoothness/images/ui-icons_888888_256x240.png +0 -0
  104. data/spec/unit/rtsp/coverage/assets/0.7.1/smoothness/images/ui-icons_cd0a0a_256x240.png +0 -0
  105. data/spec/unit/rtsp/coverage/index.html +0 -72
@@ -1,3 +1,13 @@
1
+ === 0.4.2 / 2012-11-14
2
+
3
+ * Bug fixes
4
+ * {gh-17}[https://github.com/turboladen/rtsp/issues/17] Can now parse HTTP
5
+ responses (some servers may send HTTP responses to RTSP requests).
6
+ * Other
7
+ * Turned logging off by default. To enable, simply do <tt>RTSP::Client.log = true</tt>
8
+ * Updated to work with RTP 0.1.0.
9
+ * Can now inspect RTP packets during #play.
10
+
1
11
  === 0.4.1 / 2012-11-14
2
12
 
3
13
  * gh-16: Can now parse Session IDs to be alpha characters. Thanks @greywolf-colorado!
data/Gemfile CHANGED
@@ -1,5 +1,5 @@
1
1
  source :rubygems
2
2
 
3
- #gem 'rtp', path: '../rtp'
4
3
  gemspec
4
+ gem 'thor'
5
5
 
@@ -2,48 +2,47 @@
2
2
 
3
3
  * https://github.com/turboladen/rtsp
4
4
 
5
+ {<img src="https://secure.travis-ci.org/turboladen/rtsp.png" alt="Build Status" />}[https://travis-ci.org/turboladen/rtsp]
6
+
5
7
  == DESCRIPTION:
6
8
 
7
9
  This library intends to follow the RTSP RFC document (2326) to allow for working
8
- with RTSP servers. At this point, it's up to you to parse the data from a play
9
- call, but we'll get there. ...eventually.
10
-
11
- For more information
10
+ with RTSP servers. By way of {rtp}[https://github.com/turboladen/rtp], you can
11
+ either inspect the RTP packets as they come across the wire or use the file
12
+ that the data got saved to.
12
13
 
13
- RTSP: http://tools.ietf.org/html/rfc2326
14
+ For more information:
14
15
 
15
- SDP: http://tools.ietf.org/html/rfc4566
16
+ * RTSP: {http://tools.ietf.org/html/rfc2326}[http://tools.ietf.org/html/rfc2326]
17
+ * RTP: {http://tools.ietf.org/html/rfc3550}[http://tools.ietf.org/html/rfc3550]
18
+ * SDP: {http://tools.ietf.org/html/rfc4566}[http://tools.ietf.org/html/rfc4566]
16
19
 
17
20
  == FEATURES/PROBLEMS:
18
21
 
19
22
  * All standard RTSP methods supported except REDIRECT.
20
- * Captures RTP data to a file, but doesn't ensure RTP sequencing before putting to file.
21
- * One client object can only handle 1 stream; use a client per stream until this functionality
22
- gets implemented.
23
- * Only handles unicast, UDP streams.
24
- * RTSP exceptions are all +RTSP::Error+s; this will change.
23
+ * Captures RTP data to a file, or yields if a block is passed to #play.
24
+ * One client object can only handle 1 stream; use a client per stream until this
25
+ functionality gets implemented.
26
+ * Only handles unicast, TCP RTSP communication.
27
+ * RTSP exceptions are all {RTSP::Error}s.
25
28
 
26
29
  == SYNOPSIS:
27
30
 
28
31
  === Basic Usage
29
32
 
30
- RTSP::Client.log? # => true
31
- RTSP::Client.log = false
32
- client = RTSP::Client.new "rtsp://64.202.98.91/sa.sdp" do |connection, capturer|
33
- connection.timeout = 5
34
- capturer.rtp_port = 8554
35
- capturer.rtp_file = File.open("captured_stuff.rtp", "wb")
36
- end
37
-
33
+ RTSP::Client.log? # => false
34
+ RTSP::Client.log = true
35
+ client = RTSP::Client.new "rtsp://64.202.98.91/sa.sdp"
36
+
38
37
  client.server_uri # => #<URI::Generic:0x00000100ba4db0 URL:rtsp://64.202.98.91:554/sa.sdp>
39
38
  client.session_state # => :init
40
39
  client.cseq # => 1
41
40
  client.connection.do_capture # => true
42
41
  client.connection.interleave # => false
43
- client.connection.timeout # => 5
44
- client.capturer.broadcast_type # => :unicast
45
- client.capturer.rtp_port # => 8554
46
- client.capturer.rtp_file # => #<File:captured_stuff.rtp>
42
+ client.connection.timeout # => 30
43
+ client.capturer.ip_addressing_type # => :unicast
44
+ client.capturer.rtp_port # => 6970
45
+ client.capturer.capture_file # => #<File:/var/folders/tg/j9jxvvfs4qn9cg4vztzyy2gc0000gp/T/rtp_capture.raw-59901-1l8dgv2>
47
46
  client.capturer.transport_protocol # => :UDP
48
47
 
49
48
  response = client.options
@@ -66,7 +65,6 @@ gets implemented.
66
65
  client.cseq # => 4
67
66
  client.session_state # => :ready
68
67
 
69
-
70
68
  response = client.play(client.aggregate_control_track)
71
69
  response.range # => "npt=now="
72
70
  resposne.rtp_info # => "url=rtsp://64.202.98.91:554/sa.sdp/trackID=1"
@@ -86,7 +84,31 @@ gets implemented.
86
84
  client.session_state # => :init
87
85
 
88
86
  # Check the streamed file's contents
89
- puts client.capturer.rtp_file # => (Lots of data)
87
+ puts client.capturer.capture_file # => (Lots of data)
88
+
89
+ === RTP packet inspection
90
+
91
+ As of RTP 0.1.0, you can now inspect and use packets as they come across the
92
+ wire:
93
+
94
+ client = RTSP::Client.new "rtsp://64.202.98.91/sa.sdp"
95
+ client.describe
96
+ client.setup(client.media_control_tracks.first)
97
+ payload_file = File.new('rtp.data', 'wb')
98
+
99
+ client.play(client.aggregate_control_track) do |packet|
100
+ puts "packet is a #{packet.class}"
101
+ puts "RTP seqence: #{packet.sequence_number}"
102
+ puts "RTP payload type: #{packet.payload_type}"
103
+
104
+ # Let's save the payload data while we're at it...
105
+ payload_file.write(packet.rtp_payload)
106
+ end
107
+
108
+ payload_file.close
109
+
110
+ Take a look at the {RTP::Packet docs}[http://rdoc.info/gems/rtp/RTP/Packet] for
111
+ more information.
90
112
 
91
113
  === CLI App
92
114
 
@@ -116,20 +138,12 @@ As usual, get help by:
116
138
  == REQUIREMENTS:
117
139
 
118
140
  * (Tested) Rubies
119
- * 1.9.2-p180
141
+ * 1.9.2
142
+ * 1.9.3
120
143
  * RubyGems
121
- * sdp, '~> 0.2.2'
122
- * RubyGems (development)
123
- * bundler, '~> 1.0.0'
124
- * code_statistics, '~> 0.2.13'
125
- * metric_fu, '>= 2.0.0'
126
- * ore, '~> 0.7.2'
127
- * ore-core, '~> 0.1.0'
128
- * ore-tasks, '~> 0.3.0'
129
- * rake, '~> 0.8.7'
130
- * rspec, '~> 2.5.0'
131
- * simplecov, '>= 0.4.0'
132
- * yard, '~> 0.6.0'
144
+ * sdp
145
+ * rtp
146
+ * parslet
133
147
 
134
148
  == INSTALL:
135
149
 
data/Rakefile CHANGED
@@ -2,22 +2,16 @@ require 'bundler/gem_tasks'
2
2
  require 'rspec/core/rake_task'
3
3
  require 'yard'
4
4
 
5
- RSpec::Core::RakeTask.new(:spec) do |t|
6
- t.rspec_opts = ['--format', 'documentation', '--color']
7
- end
5
+ RSpec::Core::RakeTask.new
8
6
 
9
7
  namespace :spec do
10
8
  RSpec::Core::RakeTask.new(:warnings) do |t|
11
9
  t.ruby_opts = "-w"
12
- t.rspec_opts = ['--format', 'documentation', '--color']
13
10
  end
14
11
  end
15
12
  task :default => :spec
16
13
  task :test => :spec # for `gem test`
17
14
 
18
15
  YARD::Rake::YardocTask.new do |t|
19
- t.options = ['--verbose']
16
+ t.options = %w[--verbose]
20
17
  end
21
-
22
- # Load all extra rake tasks
23
- Dir["#{File.dirname(__FILE__)}/tasks/*.rake"].each { |ext| load ext }
@@ -11,7 +11,7 @@ optparse = OptionParser.new do |opts|
11
11
  # Turn on logging
12
12
  RTSP::Client.configure { |c| c.log = false }
13
13
  opts.on('-d', '--debug', "Turn on RTSP::Client logging.") do
14
- RTSP::Client.configure { |c| c.log = true }
14
+ RTSP::Client.log = true
15
15
  end
16
16
 
17
17
  #----------------------------------------------------------------------------
@@ -50,8 +50,8 @@ optparse = OptionParser.new do |opts|
50
50
  exit
51
51
  end
52
52
 
53
- rtsp_client = RTSP::Client.new(url) do |connection, capturer|
54
- capturer.rtp_file = File.open("#{Dir.pwd}/rtsp_client_stream.rtp", "wb")
53
+ rtsp_client = RTSP::Client.new(url) do |_, capturer|
54
+ capturer.capture_file = File.open("#{Dir.pwd}/rtsp_client_stream.rtp", "wb")
55
55
  end
56
56
 
57
57
  begin
@@ -79,7 +79,7 @@ module RTSP
79
79
  attr_accessor :connection
80
80
 
81
81
  # Use to get/set an object for capturing received data.
82
- # @param [RTP::Receiver]
82
+ #
83
83
  # @return [RTP::Receiver]
84
84
  attr_accessor :capturer
85
85
 
@@ -112,21 +112,16 @@ module RTSP
112
112
  @connection = Struct::Connection.new
113
113
  @capturer = RTP::Receiver.new
114
114
 
115
- yield(connection, capturer) if block_given?
116
-
117
- @connection.server_url = server_url || @connection.server_url
118
- @server_uri = build_resource_uri_from(@connection.server_url)
119
- @connection.timeout ||= 30
120
- @connection.socket ||= TCPSocket.new(@server_uri.host, @server_uri.port)
121
- @connection.do_capture ||= true
122
- @connection.interleave ||= false
123
- @capturer.rtp_port ||= 9000
124
- @capturer.transport_protocol ||= :UDP
125
- @capturer.broadcast_type ||= :unicast
126
- @capturer.rtp_file ||= Tempfile.new(RTP::Receiver::DEFAULT_CAPFILE_NAME)
127
-
128
- @play_thread = nil
129
- @cseq = 1
115
+ yield(@connection, @capturer) if block_given?
116
+
117
+ @connection.server_url = server_url || @connection.server_url
118
+ @server_uri = build_resource_uri_from(@connection.server_url)
119
+ @connection.timeout ||= 30
120
+ @connection.socket ||= TCPSocket.new(@server_uri.host, @server_uri.port)
121
+ @connection.do_capture ||= true
122
+ @connection.interleave ||= false
123
+
124
+ @cseq = 1
130
125
  reset_state
131
126
  end
132
127
 
@@ -153,18 +148,16 @@ module RTSP
153
148
  response = Timeout::timeout(@connection.timeout) do
154
149
  @connection.socket.send(message.to_s, 0)
155
150
  socket_data = @connection.socket.recvfrom MAX_BYTES_TO_RECEIVE
151
+
152
+ RTSP::Client.log "Received response:"
153
+ socket_data.first.each_line { |line| RTSP::Client.log line.strip }
154
+
156
155
  RTSP::Response.new socket_data.first
157
156
  end
158
157
  rescue Timeout::Error
159
158
  raise RTSP::Error, "Request took more than #{@connection.timeout} seconds to send."
160
159
  end
161
160
 
162
- RTSP::Client.log "Received response:"
163
-
164
- if response
165
- response.to_s.each_line { |line| RTSP::Client.log line.strip }
166
- end
167
-
168
161
  response
169
162
  end
170
163
 
@@ -235,8 +228,8 @@ module RTSP
235
228
  # @return [String] The String to use with the Transport header.
236
229
  # @see http://tools.ietf.org/html/rfc2326#page-58 RFC 2326, Section 12.39.
237
230
  def request_transport
238
- value = "RTP/AVP;#{@capturer.broadcast_type};client_port="
239
- value << "#{@capturer.rtp_port}-#{@capturer.rtp_port + 1}\r\n"
231
+ value = "RTP/AVP;#{@capturer.ip_addressing_type};client_port="
232
+ value << "#{@capturer.rtp_port}-#{@capturer.rtcp_port}\r\n"
240
233
  end
241
234
 
242
235
  # Sends the SETUP request, then sets +@session+ to the value returned in the
@@ -260,14 +253,14 @@ module RTSP
260
253
 
261
254
  @session = response.session
262
255
  parser = RTSP::TransportParser.new
263
- @transport = parser.parse response.transport
256
+ @transport = parser.parse(response.transport)
264
257
 
265
258
  unless @transport[:transport_protocol].nil?
266
259
  @capturer.transport_protocol = @transport[:transport_protocol]
267
260
  end
268
261
 
269
- @capturer.rtp_port = @transport[:client_port][:rtp].to_i
270
- @capturer.broadcast_type = @transport[:broadcast_type]
262
+ @capturer.rtp_port = @transport[:client_port][:rtp].to_i
263
+ @capturer.ip_address = @transport[:destination].to_s
271
264
  end
272
265
  end
273
266
 
@@ -281,7 +274,7 @@ module RTSP
281
274
  # @raise [RTSP::Error] If +#play+ is called but the session hasn't yet been
282
275
  # set up via +#setup+.
283
276
  # @see http://tools.ietf.org/html/rfc2326#page-34 RFC 2326, Section 10.5.
284
- def play(track, additional_headers={})
277
+ def play(track, additional_headers={}, &block)
285
278
  message = RTSP::Message.play(track).with_headers({
286
279
  cseq: @cseq, session: @session[:session_id] })
287
280
  message.add_headers additional_headers
@@ -291,16 +284,8 @@ module RTSP
291
284
  raise RTSP::Error, "Session not set up yet. Run #setup first."
292
285
  end
293
286
 
294
- if @play_thread.nil?
295
- RTSP::Client.log "Capturing RTP data on port #{@transport[:client_port][:rtp]}"
296
-
297
- unless @capturer.running?
298
- @play_thread = Thread.new do
299
- @capturer.run
300
- end
301
- end
302
- end
303
-
287
+ RTSP::Client.log "Capturing RTP data on port #{@transport[:client_port][:rtp]}"
288
+ @capturer.start(&block)
304
289
  @session_state = :playing
305
290
  end
306
291
  end
@@ -313,7 +298,7 @@ module RTSP
313
298
  # @see http://tools.ietf.org/html/rfc2326#page-36 RFC 2326, Section 10.6.
314
299
  def pause(track, additional_headers={})
315
300
  message = RTSP::Message.pause(track).with_headers({
316
- cseq: @cseq, session: @session[:session_id] })
301
+ cseq: @cseq, session: @session[:session_id] })
317
302
  message.add_headers additional_headers
318
303
 
319
304
  request(message) do
@@ -336,23 +321,11 @@ module RTSP
336
321
  message.add_headers additional_headers
337
322
 
338
323
  request(message) do
324
+ @capturer.stop
339
325
  reset_state
340
-
341
- if @play_thread
342
- @capturer.stop
343
- @capturer.rtp_file.close
344
- @play_thread.exit
345
- end
346
326
  end
347
327
  end
348
328
 
349
- # Sets state related variables back to their starting values;
350
- # +@session_state+ is set to +:init+; +@session+ is set to 0.
351
- def reset_state
352
- @session_state = :init
353
- @session = {}
354
- end
355
-
356
329
  # Sends the GET_PARAMETERS request.
357
330
  #
358
331
  # @param [String] track The presentation or media track to ping.
@@ -361,8 +334,7 @@ module RTSP
361
334
  # @return [RTSP::Response]
362
335
  # @see http://tools.ietf.org/html/rfc2326#page-37 RFC 2326, Section 10.8.
363
336
  def get_parameter(track, body="", additional_headers={})
364
- message = RTSP::Message.get_parameter(track).with_headers({
365
- cseq: @cseq })
337
+ message = RTSP::Message.get_parameter(track).with_headers({ cseq: @cseq })
366
338
  message.add_headers additional_headers
367
339
  message.body = body
368
340
 
@@ -377,8 +349,7 @@ module RTSP
377
349
  # @return [RTSP::Response]
378
350
  # @see http://tools.ietf.org/html/rfc2326#page-38 RFC 2326, Section 10.9.
379
351
  def set_parameter(track, parameters, additional_headers={})
380
- message = RTSP::Message.set_parameter(track).with_headers({
381
- cseq: @cseq })
352
+ message = RTSP::Message.set_parameter(track).with_headers({ cseq: @cseq })
382
353
  message.add_headers additional_headers
383
354
  message.body = parameters
384
355
 
@@ -404,7 +375,7 @@ module RTSP
404
375
  # then increments +@cseq+ by 1. Handles any exceptions raised during the
405
376
  # Request.
406
377
  #
407
- # @param [Hash] new_args
378
+ # @param [RTSP::Message] message
408
379
  # @yield [RTSP::Response]
409
380
  # @return [RTSP::Response]
410
381
  # @raise [RTSP::Error] All 4xx & 5xx response codes & their messages.
@@ -434,15 +405,6 @@ module RTSP
434
405
  response
435
406
  end
436
407
 
437
- # Ensures that +@session+ is set before continuing on.
438
- #
439
- # @raise [RTSP::Error] Raises if @session isn't set.
440
- def ensure_session
441
- if @session.empty?
442
- raise RTSP::Error, "Session number not retrieved from server yet. Run SETUP first."
443
- end
444
- end
445
-
446
408
  # Extracts the URL associated with the "control" attribute from the main
447
409
  # section of the session description.
448
410
  #
@@ -478,24 +440,31 @@ module RTSP
478
440
  tracks
479
441
  end
480
442
 
481
- # Compares the sequence number passed in to the current client sequence
482
- # number ( +@cseq+ ) and raises if they're not equal. If that's the case, the
483
- # server responded to a different request.
443
+ private
444
+
445
+ # Sets state related variables back to their starting values;
446
+ # +@session_state+ is set to +:init+; +@session+ is set to 0.
447
+ def reset_state
448
+ @session_state = :init
449
+ @session = {}
450
+ end
451
+
452
+ # Takes the methods returned from the Public header from an OPTIONS response
453
+ # and puts them to an Array.
484
454
  #
485
- # @param [Fixnum] server_cseq Sequence number returned by the server.
486
- # @raise [RTSP::Error] If the server returns a CSeq value that's different
487
- # from what the client sent.
488
- def compare_sequence_number server_cseq
489
- if @cseq != server_cseq
490
- message = "Sequence number mismatch. Client: #{@cseq}, Server: #{server_cseq}"
491
- raise RTSP::Error, message
492
- end
455
+ # @param [String] method_list The string returned from the server containing
456
+ # the list of methods it supports.
457
+ # @return [Array<Symbol>] The list of methods as symbols.
458
+ # @see #options
459
+ def extract_supported_methods_from method_list
460
+ method_list.downcase.split(', ').map { |m| m.to_sym }
493
461
  end
494
462
 
495
463
  # Compares the session number passed in to the current client session
496
464
  # number ( +@session+ ) and raises if they're not equal. If that's the case,
497
465
  # the server responded to a different request.
498
466
  #
467
+ # @todo Remove this--it's not used.
499
468
  # @param [Fixnum] server_session Session number returned by the server.
500
469
  # @raise [RTSP::Error] If the server returns a Session value that's different
501
470
  # from what the client sent.
@@ -506,15 +475,30 @@ module RTSP
506
475
  end
507
476
  end
508
477
 
509
- # Takes the methods returned from the Public header from an OPTIONS response
510
- # and puts them to an Array.
478
+ # Compares the sequence number passed in to the current client sequence
479
+ # number ( +@cseq+ ) and raises if they're not equal. If that's the case, the
480
+ # server responded to a different request.
511
481
  #
512
- # @param [String] method_list The string returned from the server containing
513
- # the list of methods it supports.
514
- # @return [Array<Symbol>] The list of methods as symbols.
515
- # @see #options
516
- def extract_supported_methods_from method_list
517
- method_list.downcase.split(', ').map { |m| m.to_sym }
482
+ # @param [Fixnum] server_cseq Sequence number returned by the server.
483
+ # @raise [RTSP::Error] If the server returns a CSeq value that's different
484
+ # from what the client sent.
485
+ def compare_sequence_number server_cseq
486
+ if @cseq != server_cseq
487
+ message = "Sequence number mismatch. Client: #{@cseq}, Server: #{server_cseq}"
488
+ raise RTSP::Error, message
489
+ end
518
490
  end
491
+
492
+ # Ensures that +@session+ is set before continuing on.
493
+ #
494
+ # @raise [RTSP::Error] Raises if @session isn't set.
495
+ def ensure_session
496
+ if @session.empty?
497
+ raise RTSP::Error, "Session number not retrieved from server yet. Run SETUP first."
498
+ end
499
+ end
500
+
519
501
  end
520
502
  end
503
+
504
+ RTSP::Client.log = false