rtsp 0.4.1 → 0.4.2
Sign up to get free protection for your applications and to get access to all the features.
- data/ChangeLog.rdoc +10 -0
- data/Gemfile +1 -1
- data/README.rdoc +52 -38
- data/Rakefile +2 -8
- data/bin/rtsp_client +3 -3
- data/lib/rtsp/client.rb +69 -85
- data/lib/rtsp/message.rb +4 -5
- data/lib/rtsp/presentation.rb +1 -1
- data/lib/rtsp/session.rb +1 -1
- data/lib/rtsp/version.rb +1 -1
- data/rtsp.gemspec +13 -14
- data/spec/integration/client_use_spec.rb +206 -0
- data/spec/integration/coverage/index.html +1 -1
- data/spec/spec_helper.rb +2 -1
- data/spec/support/fake_rtsp_server.rb +1 -1
- data/spec/unit/rtsp/client_spec.rb +407 -0
- data/spec/{rtsp → unit/rtsp}/helpers_spec.rb +1 -1
- data/spec/{rtsp → unit/rtsp}/message_spec.rb +1 -1
- data/spec/{rtsp → unit/rtsp}/response_spec.rb +1 -1
- data/spec/{rtsp → unit/rtsp}/transport_parser_spec.rb +1 -1
- data/spec/{rtsp_spec.rb → unit/rtsp_spec.rb} +3 -3
- metadata +22 -185
- data/spec/rtsp/client_spec.rb +0 -326
- data/spec/rtsp/coverage/assets/0.7.1/application.css +0 -1110
- data/spec/rtsp/coverage/assets/0.7.1/application.js +0 -626
- data/spec/rtsp/coverage/assets/0.7.1/fancybox/blank.gif +0 -0
- data/spec/rtsp/coverage/assets/0.7.1/fancybox/fancy_close.png +0 -0
- data/spec/rtsp/coverage/assets/0.7.1/fancybox/fancy_loading.png +0 -0
- data/spec/rtsp/coverage/assets/0.7.1/fancybox/fancy_nav_left.png +0 -0
- data/spec/rtsp/coverage/assets/0.7.1/fancybox/fancy_nav_right.png +0 -0
- data/spec/rtsp/coverage/assets/0.7.1/fancybox/fancy_shadow_e.png +0 -0
- data/spec/rtsp/coverage/assets/0.7.1/fancybox/fancy_shadow_n.png +0 -0
- data/spec/rtsp/coverage/assets/0.7.1/fancybox/fancy_shadow_ne.png +0 -0
- data/spec/rtsp/coverage/assets/0.7.1/fancybox/fancy_shadow_nw.png +0 -0
- data/spec/rtsp/coverage/assets/0.7.1/fancybox/fancy_shadow_s.png +0 -0
- data/spec/rtsp/coverage/assets/0.7.1/fancybox/fancy_shadow_se.png +0 -0
- data/spec/rtsp/coverage/assets/0.7.1/fancybox/fancy_shadow_sw.png +0 -0
- data/spec/rtsp/coverage/assets/0.7.1/fancybox/fancy_shadow_w.png +0 -0
- data/spec/rtsp/coverage/assets/0.7.1/fancybox/fancy_title_left.png +0 -0
- data/spec/rtsp/coverage/assets/0.7.1/fancybox/fancy_title_main.png +0 -0
- data/spec/rtsp/coverage/assets/0.7.1/fancybox/fancy_title_over.png +0 -0
- data/spec/rtsp/coverage/assets/0.7.1/fancybox/fancy_title_right.png +0 -0
- data/spec/rtsp/coverage/assets/0.7.1/fancybox/fancybox-x.png +0 -0
- data/spec/rtsp/coverage/assets/0.7.1/fancybox/fancybox-y.png +0 -0
- data/spec/rtsp/coverage/assets/0.7.1/fancybox/fancybox.png +0 -0
- data/spec/rtsp/coverage/assets/0.7.1/favicon_green.png +0 -0
- data/spec/rtsp/coverage/assets/0.7.1/favicon_red.png +0 -0
- data/spec/rtsp/coverage/assets/0.7.1/favicon_yellow.png +0 -0
- data/spec/rtsp/coverage/assets/0.7.1/loading.gif +0 -0
- data/spec/rtsp/coverage/assets/0.7.1/magnify.png +0 -0
- data/spec/rtsp/coverage/assets/0.7.1/smoothness/images/ui-bg_flat_0_aaaaaa_40x100.png +0 -0
- data/spec/rtsp/coverage/assets/0.7.1/smoothness/images/ui-bg_flat_75_ffffff_40x100.png +0 -0
- data/spec/rtsp/coverage/assets/0.7.1/smoothness/images/ui-bg_glass_55_fbf9ee_1x400.png +0 -0
- data/spec/rtsp/coverage/assets/0.7.1/smoothness/images/ui-bg_glass_65_ffffff_1x400.png +0 -0
- data/spec/rtsp/coverage/assets/0.7.1/smoothness/images/ui-bg_glass_75_dadada_1x400.png +0 -0
- data/spec/rtsp/coverage/assets/0.7.1/smoothness/images/ui-bg_glass_75_e6e6e6_1x400.png +0 -0
- data/spec/rtsp/coverage/assets/0.7.1/smoothness/images/ui-bg_glass_95_fef1ec_1x400.png +0 -0
- data/spec/rtsp/coverage/assets/0.7.1/smoothness/images/ui-bg_highlight-soft_75_cccccc_1x100.png +0 -0
- data/spec/rtsp/coverage/assets/0.7.1/smoothness/images/ui-icons_222222_256x240.png +0 -0
- data/spec/rtsp/coverage/assets/0.7.1/smoothness/images/ui-icons_2e83ff_256x240.png +0 -0
- data/spec/rtsp/coverage/assets/0.7.1/smoothness/images/ui-icons_454545_256x240.png +0 -0
- data/spec/rtsp/coverage/assets/0.7.1/smoothness/images/ui-icons_888888_256x240.png +0 -0
- data/spec/rtsp/coverage/assets/0.7.1/smoothness/images/ui-icons_cd0a0a_256x240.png +0 -0
- data/spec/rtsp/coverage/index.html +0 -72
- data/spec/unit/rtsp/coverage/assets/0.7.1/application.css +0 -1110
- data/spec/unit/rtsp/coverage/assets/0.7.1/application.js +0 -626
- data/spec/unit/rtsp/coverage/assets/0.7.1/fancybox/blank.gif +0 -0
- data/spec/unit/rtsp/coverage/assets/0.7.1/fancybox/fancy_close.png +0 -0
- data/spec/unit/rtsp/coverage/assets/0.7.1/fancybox/fancy_loading.png +0 -0
- data/spec/unit/rtsp/coverage/assets/0.7.1/fancybox/fancy_nav_left.png +0 -0
- data/spec/unit/rtsp/coverage/assets/0.7.1/fancybox/fancy_nav_right.png +0 -0
- data/spec/unit/rtsp/coverage/assets/0.7.1/fancybox/fancy_shadow_e.png +0 -0
- data/spec/unit/rtsp/coverage/assets/0.7.1/fancybox/fancy_shadow_n.png +0 -0
- data/spec/unit/rtsp/coverage/assets/0.7.1/fancybox/fancy_shadow_ne.png +0 -0
- data/spec/unit/rtsp/coverage/assets/0.7.1/fancybox/fancy_shadow_nw.png +0 -0
- data/spec/unit/rtsp/coverage/assets/0.7.1/fancybox/fancy_shadow_s.png +0 -0
- data/spec/unit/rtsp/coverage/assets/0.7.1/fancybox/fancy_shadow_se.png +0 -0
- data/spec/unit/rtsp/coverage/assets/0.7.1/fancybox/fancy_shadow_sw.png +0 -0
- data/spec/unit/rtsp/coverage/assets/0.7.1/fancybox/fancy_shadow_w.png +0 -0
- data/spec/unit/rtsp/coverage/assets/0.7.1/fancybox/fancy_title_left.png +0 -0
- data/spec/unit/rtsp/coverage/assets/0.7.1/fancybox/fancy_title_main.png +0 -0
- data/spec/unit/rtsp/coverage/assets/0.7.1/fancybox/fancy_title_over.png +0 -0
- data/spec/unit/rtsp/coverage/assets/0.7.1/fancybox/fancy_title_right.png +0 -0
- data/spec/unit/rtsp/coverage/assets/0.7.1/fancybox/fancybox-x.png +0 -0
- data/spec/unit/rtsp/coverage/assets/0.7.1/fancybox/fancybox-y.png +0 -0
- data/spec/unit/rtsp/coverage/assets/0.7.1/fancybox/fancybox.png +0 -0
- data/spec/unit/rtsp/coverage/assets/0.7.1/favicon_green.png +0 -0
- data/spec/unit/rtsp/coverage/assets/0.7.1/favicon_red.png +0 -0
- data/spec/unit/rtsp/coverage/assets/0.7.1/favicon_yellow.png +0 -0
- data/spec/unit/rtsp/coverage/assets/0.7.1/loading.gif +0 -0
- data/spec/unit/rtsp/coverage/assets/0.7.1/magnify.png +0 -0
- data/spec/unit/rtsp/coverage/assets/0.7.1/smoothness/images/ui-bg_flat_0_aaaaaa_40x100.png +0 -0
- data/spec/unit/rtsp/coverage/assets/0.7.1/smoothness/images/ui-bg_flat_75_ffffff_40x100.png +0 -0
- data/spec/unit/rtsp/coverage/assets/0.7.1/smoothness/images/ui-bg_glass_55_fbf9ee_1x400.png +0 -0
- data/spec/unit/rtsp/coverage/assets/0.7.1/smoothness/images/ui-bg_glass_65_ffffff_1x400.png +0 -0
- data/spec/unit/rtsp/coverage/assets/0.7.1/smoothness/images/ui-bg_glass_75_dadada_1x400.png +0 -0
- data/spec/unit/rtsp/coverage/assets/0.7.1/smoothness/images/ui-bg_glass_75_e6e6e6_1x400.png +0 -0
- data/spec/unit/rtsp/coverage/assets/0.7.1/smoothness/images/ui-bg_glass_95_fef1ec_1x400.png +0 -0
- data/spec/unit/rtsp/coverage/assets/0.7.1/smoothness/images/ui-bg_highlight-soft_75_cccccc_1x100.png +0 -0
- data/spec/unit/rtsp/coverage/assets/0.7.1/smoothness/images/ui-icons_222222_256x240.png +0 -0
- data/spec/unit/rtsp/coverage/assets/0.7.1/smoothness/images/ui-icons_2e83ff_256x240.png +0 -0
- data/spec/unit/rtsp/coverage/assets/0.7.1/smoothness/images/ui-icons_454545_256x240.png +0 -0
- data/spec/unit/rtsp/coverage/assets/0.7.1/smoothness/images/ui-icons_888888_256x240.png +0 -0
- data/spec/unit/rtsp/coverage/assets/0.7.1/smoothness/images/ui-icons_cd0a0a_256x240.png +0 -0
- data/spec/unit/rtsp/coverage/index.html +0 -72
data/ChangeLog.rdoc
CHANGED
@@ -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
data/README.rdoc
CHANGED
@@ -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.
|
9
|
-
|
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
|
-
|
14
|
+
For more information:
|
14
15
|
|
15
|
-
|
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,
|
21
|
-
* One client object can only handle 1 stream; use a client per stream until this
|
22
|
-
gets implemented.
|
23
|
-
* Only handles unicast,
|
24
|
-
* RTSP exceptions are all
|
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? # =>
|
31
|
-
RTSP::Client.log =
|
32
|
-
client = RTSP::Client.new "rtsp://64.202.98.91/sa.sdp"
|
33
|
-
|
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 # =>
|
44
|
-
client.capturer.
|
45
|
-
client.capturer.rtp_port # =>
|
46
|
-
client.capturer.
|
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.
|
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
|
141
|
+
* 1.9.2
|
142
|
+
* 1.9.3
|
120
143
|
* RubyGems
|
121
|
-
* sdp
|
122
|
-
*
|
123
|
-
*
|
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
|
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 = [
|
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 }
|
data/bin/rtsp_client
CHANGED
@@ -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.
|
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 |
|
54
|
-
capturer.
|
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
|
data/lib/rtsp/client.rb
CHANGED
@@ -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
|
-
#
|
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
|
118
|
-
@server_uri
|
119
|
-
@connection.timeout
|
120
|
-
@connection.socket
|
121
|
-
@connection.do_capture
|
122
|
-
@connection.interleave
|
123
|
-
|
124
|
-
@
|
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.
|
239
|
-
value << "#{@capturer.rtp_port}-#{@capturer.
|
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
|
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
|
270
|
-
@capturer.
|
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
|
-
|
295
|
-
|
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
|
-
|
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 [
|
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
|
-
|
482
|
-
|
483
|
-
#
|
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 [
|
486
|
-
#
|
487
|
-
#
|
488
|
-
|
489
|
-
|
490
|
-
|
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
|
-
#
|
510
|
-
# and
|
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 [
|
513
|
-
#
|
514
|
-
#
|
515
|
-
|
516
|
-
|
517
|
-
|
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
|