rtsp_server 0.0.2-universal-java

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.
Files changed (44) hide show
  1. checksums.yaml +7 -0
  2. data/.gemtest +0 -0
  3. data/ChangeLog.rdoc +74 -0
  4. data/Gemfile +3 -0
  5. data/LICENSE.rdoc +20 -0
  6. data/README.rdoc +152 -0
  7. data/Rakefile +23 -0
  8. data/bin/rtsp_client +133 -0
  9. data/features/client_changes_state.feature +58 -0
  10. data/features/client_requests.feature +27 -0
  11. data/features/control_streams_as_client.feature +26 -0
  12. data/features/step_definitions/client_changes_state_steps.rb +52 -0
  13. data/features/step_definitions/client_requests_steps.rb +68 -0
  14. data/features/step_definitions/control_streams_as_client_steps.rb +34 -0
  15. data/features/support/env.rb +50 -0
  16. data/features/support/hooks.rb +3 -0
  17. data/lib/ext/logger.rb +8 -0
  18. data/lib/rtsp/client.rb +520 -0
  19. data/lib/rtsp/common.rb +148 -0
  20. data/lib/rtsp/error.rb +6 -0
  21. data/lib/rtsp/global.rb +63 -0
  22. data/lib/rtsp/helpers.rb +28 -0
  23. data/lib/rtsp/message.rb +272 -0
  24. data/lib/rtsp/request.rb +39 -0
  25. data/lib/rtsp/response.rb +47 -0
  26. data/lib/rtsp/server.rb +311 -0
  27. data/lib/rtsp/socat_streaming.rb +320 -0
  28. data/lib/rtsp/stream_server.rb +37 -0
  29. data/lib/rtsp/transport_parser.rb +96 -0
  30. data/lib/rtsp/version.rb +4 -0
  31. data/lib/rtsp.rb +6 -0
  32. data/rtsp.gemspec +44 -0
  33. data/spec/rtsp/client_spec.rb +326 -0
  34. data/spec/rtsp/helpers_spec.rb +53 -0
  35. data/spec/rtsp/message_spec.rb +420 -0
  36. data/spec/rtsp/response_spec.rb +306 -0
  37. data/spec/rtsp/transport_parser_spec.rb +137 -0
  38. data/spec/rtsp_spec.rb +27 -0
  39. data/spec/spec_helper.rb +88 -0
  40. data/spec/support/fake_rtsp_server.rb +123 -0
  41. data/tasks/roodi.rake +9 -0
  42. data/tasks/roodi_config.yaml +14 -0
  43. data/tasks/stats.rake +12 -0
  44. metadata +280 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: ccad9e4be96987634a8df45e84603cc6786161d5
4
+ data.tar.gz: cda5810ec70b56bcf2a7c2389874c64720bbef17
5
+ SHA512:
6
+ metadata.gz: eb3a7f4b3a46c19bcd4f2a60c6ec99e1685fcb9bcb1cd0b73d1bec612b0833bf615d3277de7956405f383fc7ed73be0efdb74fd4c2d11d599219d704d0e108e8
7
+ data.tar.gz: 54080420cc181b44cfe6bd87da00ec0852259a9b3686b869dc61ed123167772426fcba69ba2e3a2a5d01d640995cf6e721f1d8a584f3c064ab3a18d7a65c5b24
data/.gemtest ADDED
File without changes
data/ChangeLog.rdoc ADDED
@@ -0,0 +1,74 @@
1
+ === 0.4.0 / 2012-03-08
2
+
3
+ * gh-11: Transport header parser bolstering:
4
+ * values that should be caps, will parse OK as lowercase now.
5
+ * :broadcast_type now parses 'multicast'.
6
+ * :destination now returns the value of the destination instead of
7
+ "destination=x.x.x.x"
8
+ * :source now returns the value of the source instead of "source=x.x.x.x"
9
+ * Added parsing for fields:
10
+ * ttl
11
+ * port
12
+ * ssrc
13
+ * channel
14
+ * address
15
+ * mode
16
+ * gh-10: Session header now detects timeout value. This means that where use
17
+ of the value extracted from this header used to be a simple Integer, now you
18
+ have a session Hash with :session_id and :timeout keys.
19
+
20
+ === 0.3.0 / 2012-03-02
21
+
22
+ * Extracted RTP-esque functionality to an +rtp+ gem, on which this gem is now
23
+ dependent on version 0.0.1 of that.
24
+ * Laxed dependency requirement on parslet.
25
+ * Bumped dependency requirement on sdp to ~> 0.2.6, due to parslet conflicts
26
+
27
+ === 0.2.2 / 2011-11-02
28
+
29
+ * Added a queue for listening and building the RTP file from the received data.
30
+ * Fixed bugs:
31
+ * gh-6: .gemspec was missing +parslet+ dependency. Thanks [tindron[http://github.com/tindron]].
32
+
33
+ === 0.2.1 / 2011-09-20
34
+
35
+ * `gem test rtsp` is failing; added rtsp.gemspec to list of files in the spec.
36
+
37
+ === 0.2.0 / 2011-09-19
38
+
39
+ * Changed RTSP::Capturer init_*_server methods to take params in order to reduce
40
+ dependency on state of the Capturer object.
41
+ * Improvements:
42
+ * If RTSP::Capturer can't open port 9000, it increments by 1 and tries again,
43
+ 50 times, then raises.
44
+ * gh-4: Remove dependency on ore en lieu of standard gem commands.
45
+ * Participate in http://test.rubygems.org!
46
+ * Fixed bugs:
47
+ * gh-5: Fixed 'Bad file descriptor' bug when capturing to file.
48
+
49
+ === 0.1.2 / 2011-04-14
50
+
51
+ * Manually released; the gemspec that Ore created didn't install bin/rtsp_client.
52
+
53
+ === 0.1.1 / 2011-04-14
54
+
55
+ * Fixed bugs:
56
+ * gh-1: No longer use Socket::SO_REUSEADDR or Socket::SO_REUSEPORT.
57
+ * gh-2: rtsp_client now requires the installed rtsp/client.
58
+ * Capturer#run's log message now says what it's logging.
59
+ * bin/rtsp_client:
60
+ * Fixed bad description for --stream.
61
+ * Added --version.
62
+ * Updated README.rdoc:
63
+ * ...to clarify that REDIRECT isn't yet supported.
64
+ * ...with brief usage on bin/rtsp_client.
65
+
66
+ === 0.1.0 / 2011-04-12
67
+
68
+ * Happy birthday!
69
+ * All standard RTSP methods supported.
70
+ * Captures RTP data to a file, but doesn't ensure RTP sequencing before putting to file.
71
+ * One client object can only handle 1 stream; use a client per stream until this functionality
72
+ gets implemented.
73
+ * Only handles unicast, UDP streams.
74
+ * RTSP exceptions are all +RTSP::Error+s; this will change.
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source :rubygems
2
+
3
+ gemspec
data/LICENSE.rdoc ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2011 sloveless, mkirby
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.rdoc ADDED
@@ -0,0 +1,152 @@
1
+ = rtsp
2
+
3
+ * https://github.com/turboladen/rtsp
4
+
5
+ == DESCRIPTION:
6
+
7
+ 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
12
+
13
+ RTSP: http://tools.ietf.org/html/rfc2326
14
+
15
+ SDP: http://tools.ietf.org/html/rfc4566
16
+
17
+ == FEATURES/PROBLEMS:
18
+
19
+ * 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.
25
+
26
+ == SYNOPSIS:
27
+
28
+ === Basic Usage
29
+
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
+
38
+ client.server_uri # => #<URI::Generic:0x00000100ba4db0 URL:rtsp://64.202.98.91:554/sa.sdp>
39
+ client.session_state # => :init
40
+ client.cseq # => 1
41
+ client.connection.do_capture # => true
42
+ 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>
47
+ client.capturer.transport_protocol # => :UDP
48
+
49
+ response = client.options
50
+ response.class # => RTSP::Response
51
+ response.code # => 200
52
+ response.message # => "OK"
53
+ client.cseq # => 2
54
+
55
+ response = client.describe
56
+ response.body.class # => SDP::Description
57
+ response.content_type # => "application/sdp"
58
+ response.server # => "DSS/5.5 (Build/489.7; Platform/Linux; Release/Darwin; )"
59
+ client.aggregate_control_track # => "rtsp://64.202.98.91:554/sa.sdp/"
60
+ client.media_control_tracks # => ["rtsp://64.202.98.91:554/sa.sdp/trackID=1"]
61
+ client.cseq # => 3
62
+
63
+ response = client.setup(client.media_control_tracks.first)
64
+ response.session[:session_id] # => 7098486223178290313
65
+ client.session[:session_id] # => 7098486223178290313
66
+ client.cseq # => 4
67
+ client.session_state # => :ready
68
+
69
+
70
+ response = client.play(client.aggregate_control_track)
71
+ response.range # => "npt=now="
72
+ resposne.rtp_info # => "url=rtsp://64.202.98.91:554/sa.sdp/trackID=1"
73
+ client.session_state # => :playing
74
+
75
+ # Wait while the video streams
76
+ sleep 5
77
+
78
+ client.pause(client.aggregate_control_track)
79
+ client.session_state # => :ready
80
+
81
+ # Wait while the video is paused
82
+ sleep 2
83
+
84
+ client.teardown(client.aggregate_control_track)
85
+ client.session[:session_id] # => 0
86
+ client.session_state # => :init
87
+
88
+ # Check the streamed file's contents
89
+ puts client.capturer.rtp_file # => (Lots of data)
90
+
91
+ === CLI App
92
+
93
+ RTSP also provides a +rtsp_client+ executable that allows a little talking to
94
+ an RTSP server.
95
+
96
+ Knowing which tracks are available on the server can help you determine which
97
+ tracks to use in your programmatic use of an RTSP::Client object to try to
98
+ play. Show the available aggregate control track and media control tracks:
99
+
100
+ $ rtsp_client --show-tracks rtsp://64.202.98.91/sa.sdp
101
+
102
+ Or if you want the entire SDP description from the server:
103
+
104
+ $ rtsp_client --describe rtsp://64.202.98.91/sa.sdp
105
+
106
+ And then, of course, pull a stream (this assumes you SETUP the first media
107
+ track and call play on the aggregate track):
108
+
109
+ $ rtsp_client --stream rtsp://64.202.98.91/sa.sdp
110
+
111
+ As usual, get help by:
112
+
113
+ $ rtsp_client --help
114
+
115
+
116
+ == REQUIREMENTS:
117
+
118
+ * (Tested) Rubies
119
+ * 1.9.2-p180
120
+ * 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'
133
+
134
+ == INSTALL:
135
+
136
+ * (sudo) gem install rtsp
137
+
138
+ == DEVELOPERS:
139
+
140
+ After checking out the source, run:
141
+
142
+ $ bundle install
143
+
144
+ This task will install any missing dependencies.
145
+
146
+ == LICENSE:
147
+
148
+ (The MIT License)
149
+
150
+ Copyright (c) 2011 Steve Loveless, Mike Kirby
151
+
152
+ See LICENSE.rdoc for details.
data/Rakefile ADDED
@@ -0,0 +1,23 @@
1
+ require 'bundler/gem_tasks'
2
+ require 'rspec/core/rake_task'
3
+ require 'yard'
4
+
5
+ RSpec::Core::RakeTask.new(:spec) do |t|
6
+ t.rspec_opts = ['--format', 'documentation', '--color']
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
15
+ task :default => :spec
16
+ task :test => :spec # for `gem test`
17
+
18
+ YARD::Rake::YardocTask.new do |t|
19
+ t.options = ['--verbose']
20
+ end
21
+
22
+ # Load all extra rake tasks
23
+ Dir["#{File.dirname(__FILE__)}/tasks/*.rake"].each { |ext| load ext }
data/bin/rtsp_client ADDED
@@ -0,0 +1,133 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'tempfile'
4
+ require 'optparse'
5
+ require 'rtsp/client'
6
+
7
+ optparse = OptionParser.new do |opts|
8
+ opts.banner = "Usage: #{__FILE__} [options] url"
9
+
10
+ #----------------------------------------------------------------------------
11
+ # Turn on logging
12
+ RTSP::Client.configure { |c| c.log = false }
13
+ opts.on('-d', '--debug', "Turn on RTSP::Client logging.") do
14
+ RTSP::Client.configure { |c| c.log = true }
15
+ end
16
+
17
+ #----------------------------------------------------------------------------
18
+ # Get description
19
+ opts.on('--describe [URL]', "Get description from the given URL.") do |url|
20
+ if url.nil?
21
+ puts "Must pass in a URL."
22
+ exit
23
+ end
24
+
25
+ rtsp_client = RTSP::Client.new(url)
26
+ puts rtsp_client.describe.body.inspect
27
+ exit
28
+ end
29
+
30
+ #----------------------------------------------------------------------------
31
+ # Show available tracks
32
+ opts.on('--show-tracks [URL]', "Show available tracks from the given URL.") do |url|
33
+ if url.nil?
34
+ puts "Must pass in a URL."
35
+ exit
36
+ end
37
+
38
+ rtsp_client = RTSP::Client.new(url)
39
+ rtsp_client.describe
40
+ puts "Aggregate control track: #{rtsp_client.aggregate_control_track}"
41
+ puts "Media control tracks: #{rtsp_client.media_control_tracks}"
42
+ exit
43
+ end
44
+
45
+ #----------------------------------------------------------------------------
46
+ # Stream
47
+ opts.on('--stream [URL]', "Pull the first media stream from the given URL.") do |url|
48
+ if url.nil?
49
+ puts "Must pass in a URL."
50
+ exit
51
+ end
52
+
53
+ rtsp_client = RTSP::Client.new(url) do |connection, capturer|
54
+ capturer.rtp_file = File.open("#{Dir.pwd}/rtsp_client_stream.rtp", "wb")
55
+ end
56
+
57
+ begin
58
+ puts "Getting server options..."
59
+ response = rtsp_client.options
60
+ puts "\tServer: #{response.server}"
61
+ puts "\tSupported methods: #{response.public}"
62
+ puts ""
63
+
64
+ puts "Getting description..."
65
+ response = rtsp_client.describe
66
+ puts "\tcache_control: #{response.cache_control}" if response.respond_to? "cache_control"
67
+ puts "\tdate: #{response.date}"
68
+ puts "\texpires: #{response.expires}" if response.respond_to? "expires"
69
+ puts "\tcontent_type: #{response.content_type}"
70
+ puts "\tcontent_base: #{response.content_base}"
71
+ puts "\tAggregate control track: #{rtsp_client.aggregate_control_track}"
72
+ puts "\tMedia control tracks: #{rtsp_client.media_control_tracks}"
73
+ puts ""
74
+
75
+ puts "Setting up #{rtsp_client.media_control_tracks.first}"
76
+ response = rtsp_client.setup rtsp_client.media_control_tracks.first
77
+ puts "\ttransport: #{response.transport}"
78
+ puts ""
79
+
80
+ if response.message == "OK"
81
+ puts "Playing #{rtsp_client.aggregate_control_track}"
82
+ r = rtsp_client.play rtsp_client.aggregate_control_track
83
+ puts "\trange: #{r.range}"
84
+ puts "\trtp_info: #{r.rtp_info}"
85
+ puts ""
86
+
87
+
88
+ 1...5.times do
89
+ print "."
90
+ sleep 1
91
+ end
92
+ puts ""
93
+
94
+ if rtsp_client.capturer.rtp_file.size.zero?
95
+ puts "Captured 0 bytes. Your firewall might be blocking the RTP traffic on port #{rtsp_client.capturer.rtp_port}."
96
+ else
97
+ puts "RTP data captured to file: #{rtsp_client.capturer.rtp_file}"
98
+ end
99
+
100
+ puts "Tearing down..."
101
+ r2 = rtsp_client.teardown(rtsp_client.aggregate_control_track)
102
+ puts "\tconnection: #{r2.connection}" if r2.respond_to? "connection"
103
+ else
104
+ puts "Play call returned: #{response.message}. Exiting."
105
+ exit
106
+ end
107
+ rescue RTSP::Error => ex
108
+ puts ex.backtrace
109
+ puts ex.message
110
+ end
111
+ end
112
+
113
+ #----------------------------------------------------------------------------
114
+ # Help
115
+ opts.on('--version', "The version of the Ruby RTSP gem used for this.") do
116
+ puts RTSP::VERSION
117
+ exit
118
+ end
119
+
120
+ #----------------------------------------------------------------------------
121
+ # Help
122
+ opts.on('-h', '--help', "You're looking at it.") do
123
+ puts opts
124
+ exit
125
+ end
126
+ end
127
+
128
+ if ARGV.size.zero?
129
+ puts optparse.help if ARGV.size.zero?
130
+ exit
131
+ end
132
+ optparse.parse!
133
+
@@ -0,0 +1,58 @@
1
+ Feature: Client changes state
2
+ As an RTSP client user
3
+ I want to monitor the state of my client
4
+ So that I can be sure of what my client is doing at any time
5
+
6
+ Scenario Outline: State doesn't change after certain requests
7
+ Given I haven't made any RTSP requests
8
+ When I issue an "<request_type>" request with "<parameters>"
9
+ Then the state stays the same
10
+ Examples:
11
+ | request_type | parameters |
12
+ | options | |
13
+ | describe | |
14
+
15
+ Scenario Outline: State changes from Init
16
+ Given I haven't made any RTSP requests
17
+ When I issue an "<request_type>" request with "<parameters>"
18
+ Then the state changes to "<state_result>"
19
+ Examples:
20
+ | request_type | parameters | state_result |
21
+ | setup | url | ready |
22
+ | teardown | url | init |
23
+
24
+ Scenario Outline: State changes from Ready
25
+ Given I have set up a stream
26
+ When I issue an "<request_type>" request with "<parameters>"
27
+ Then the state changes to "<state_result>"
28
+ Examples:
29
+ | request_type | parameters | state_result |
30
+ | play | url | playing |
31
+ | record | url | recording |
32
+ | teardown | url | init |
33
+ | setup | url | ready |
34
+
35
+ Scenario Outline: State changes from Playing
36
+ Given I have set up a stream
37
+ And I have started playing a stream
38
+ When I issue an "<request_type>" request with "<parameters>"
39
+ Then the state changes to "<state_result>"
40
+ Examples:
41
+ | request_type | parameters | state_result |
42
+ | pause | url | ready |
43
+ | teardown | url | init |
44
+ | play | url | playing |
45
+ | setup | url | playing |
46
+
47
+ Scenario Outline: State changes from Recording
48
+ Given I have set up a stream
49
+ And I have started recording a stream
50
+ When I issue an "<request_type>" request with "<parameters>"
51
+ Then the state changes to "<state_result>"
52
+ Examples:
53
+ | request_type | parameters | state_result |
54
+ | pause | url | ready |
55
+ | teardown | url | init |
56
+ | record | url | recording |
57
+ | setup | url | recording |
58
+
@@ -0,0 +1,27 @@
1
+ Feature: Client request messages
2
+ As an RTSP client API user
3
+ I want to make RTSP requests
4
+ So that I can build a client using these request messages
5
+
6
+ Scenario: OPTIONS
7
+ Given a known RTSP server
8
+ When I make a "options" request
9
+ Then I should receive an RTSP response to that OPTIONS request
10
+
11
+ Scenario: DESCRIBE
12
+ Given a known RTSP server
13
+ When I make a "describe" request
14
+ Then I should receive an RTSP response to that DESCRIBE request
15
+
16
+ Scenario: ANNOUNCE
17
+ Given a known RTSP server
18
+ When I make a "announce" request
19
+ Then I should receive an RTSP response to that ANNOUNCE request
20
+
21
+ Scenario: SETUP
22
+ Given a known RTSP server
23
+ When I make a "setup" request with headers:
24
+ | header | value |
25
+ | transport | RTP/AVP |
26
+ Then I should receive an RTSP response to that SETUP request
27
+
@@ -0,0 +1,26 @@
1
+ Feature: Control stream from an RTSP server
2
+ As an RTSP consumer
3
+ I want to be able to control RTSP streams from a server
4
+ So that I can view its contents as I desire
5
+
6
+ @wip
7
+ Scenario: Play single stream
8
+ Given an RTSP server at "10.221.222.235" and port 9010 and URL ""
9
+ When I play a stream from that server
10
+ Then I should not receive any errors
11
+ And I should receive data on the same port
12
+
13
+ Scenario: Play then pause single stream
14
+ Given an RTSP server at "10.221.222.235" and port 9010 and URL ""
15
+ When I play a stream from that server for 10 seconds
16
+ And I pause that stream
17
+ Then I should not receive data on the same port
18
+
19
+ Scenario: Play two streams individually and simultaneously
20
+
21
+ Scenario: Play then pause two streams individually and simultaneously
22
+
23
+ Scenario: Play two streams using the aggregate control URL
24
+
25
+ Scenario: Play then pause two streams using the aggregate control URL
26
+
@@ -0,0 +1,52 @@
1
+ Given /^I haven't made any RTSP requests$/ do
2
+ RTSP::Client.configure { |config| config.log = false }
3
+ end
4
+
5
+ Given /^I have set up a stream$/ do
6
+ @url = "rtsp://fake-rtsp-server/some_path"
7
+ @client = RTSP::Client.new(@url) do |connection|
8
+ connection.socket = @fake_server
9
+ connection.timeout = 3
10
+ end
11
+ @client.setup @url
12
+ @client.session_state.should == :ready
13
+ end
14
+
15
+ Given /^I have started (playing|recording) a stream$/ do |method|
16
+ if method == "playing"
17
+ @client.setup @url
18
+ @client.play @url
19
+ elsif method == "recording"
20
+ @client.record @url
21
+ end
22
+ @client.session_state.should == method.to_sym
23
+ end
24
+
25
+ When /^I issue an "([^"]*)" request with "([^"]*)"$/ do |request_type, params|
26
+ unless @client
27
+ url = "rtsp://fake-rtsp-server/some_path"
28
+
29
+ @client = RTSP::Client.new(url) do |connection|
30
+ connection.socket = @fake_server
31
+ connection.timeout = 3
32
+ end
33
+ end
34
+
35
+ @initial_state = @client.session_state
36
+ params = params.empty? ? {} : params
37
+
38
+ if request_type == 'play'
39
+ @client.setup(url)
40
+ @client.play(params)
41
+ else
42
+ @client.send(request_type.to_sym, params)
43
+ end
44
+ end
45
+
46
+ Then /^the state stays the same$/ do
47
+ @client.session_state.should == @initial_state
48
+ end
49
+
50
+ Then /^the state changes to "([^"]*)"$/ do |new_state|
51
+ @client.session_state.should == new_state.to_sym
52
+ end
@@ -0,0 +1,68 @@
1
+ Given /^a known RTSP server$/ do
2
+ @server_url = "rtsp://64.202.98.91:554/sa.sdp"
3
+
4
+ @client = RTSP::Client.new(@server_url) do |connection|
5
+ connection.socket = @fake_server
6
+ connection.timeout = 3
7
+ end
8
+ end
9
+
10
+ When /^I make a "([^"]*)" request$/ do |method|
11
+ @response = if method == 'announce'
12
+ @client.setup(@server_url)
13
+ @client.announce(@server_url, @client.describe)
14
+ else
15
+ @client.send(method.to_sym)
16
+ end
17
+ end
18
+
19
+ When /^I make a "([^"]*)" request with headers:$/ do |method, headers_table|
20
+ # table is a Cucumber::Ast::Table
21
+ headers = {}
22
+
23
+ headers_table.hashes.each do |hash|
24
+ header_type = hash["header"].to_sym
25
+ headers[header_type] = hash["value"]
26
+ end
27
+
28
+ @response = if method == 'setup'
29
+ @client.setup(@server_url, headers)
30
+ else
31
+ @client.send(method.to_sym, headers)
32
+ end
33
+ end
34
+
35
+ Then /^I should receive an RTSP response to that OPTIONS request$/ do
36
+ @response.should be_a RTSP::Response
37
+ @response.code.should == 200
38
+ @response.message.should == "OK"
39
+ @response.cseq.should == 1
40
+ @response.public.should == "DESCRIBE, SETUP, TEARDOWN, PLAY, PAUSE"
41
+ @response.body.should be_empty
42
+ end
43
+
44
+ Then /^I should receive an RTSP response to that DESCRIBE request$/ do
45
+ @response.should be_a RTSP::Response
46
+ @response.code.should == 200
47
+ @response.message.should == "OK"
48
+ @response.server.should == "DSS/5.5 (Build/489.7; Platform/Linux; Release/Darwin; )"
49
+ @response.cseq.should == 1
50
+ @response.body.should be_a SDP::Description
51
+ @response.body.username.should == "-"
52
+ end
53
+
54
+ Then /^I should receive an RTSP response to that ANNOUNCE request$/ do
55
+ @response.should be_a RTSP::Response
56
+ @response.code.should == 200
57
+ @response.message.should == "OK"
58
+ @response.cseq.should == 2
59
+ end
60
+
61
+ Then /^I should receive an RTSP response to that SETUP request$/ do
62
+ @response.should be_a RTSP::Response
63
+ @response.code.should == 200
64
+ @response.message.should == "OK"
65
+ @response.cseq.should == 1
66
+ @response.transport.should match(/RTP\/AVP;unicast;destination=\S+;source=\S+;client_port=\d+-\d+;server_port=\d+-\d+/)
67
+ end
68
+
@@ -0,0 +1,34 @@
1
+ Given /^an RTSP server at "([^"]*)" and port (\d+)$/ do |ip_address, port|
2
+ @rtp_port = port.to_i
3
+ @client = RTSP::Client.new(ip_address) do |connection, capturer|
4
+ capturer.rtp_port = @rtp_port
5
+ end
6
+ end
7
+
8
+ Given /^an RTSP server at "([^"]*)" and port (\d+) and URL "([^"]*)"$/ do |ip_address, port, path|
9
+ uri = "rtsp://#{ip_address}:#{port}#{path}"
10
+ @rtp_port = port
11
+ @client = RTSP::Client.new(uri) do |connection, capturer|
12
+ capturer.rtp_port = @rtp_port
13
+ end
14
+ end
15
+
16
+ When /^I play a stream from that server$/ do
17
+ @play_result = lambda { @client.play }
18
+ end
19
+
20
+ Then /^I should not receive any errors$/ do
21
+ @play_result.should_not raise_error
22
+ end
23
+
24
+ Then /^I should receive data on the same port$/ do
25
+ @client.capturer.rtp_file.should_not be_empty
26
+ end
27
+
28
+ Given /^I know what the describe response looks like$/ do
29
+ @response_text = @fake_server.describe
30
+ end
31
+
32
+ When /^I ask the server to describe$/ do
33
+ puts @client.describe
34
+ end