rtsp 0.0.1.alpha
Sign up to get free protection for your applications and to get access to all the features.
- data/.autotest +23 -0
- data/.infinity_test +4 -0
- data/.rspec +3 -0
- data/Gemfile +12 -0
- data/Gemfile.lock +104 -0
- data/History.txt +4 -0
- data/Manifest.txt +26 -0
- data/PostInstall.txt +7 -0
- data/README.rdoc +74 -0
- data/Rakefile +57 -0
- data/bin/rtsp +121 -0
- data/features/step_definitions/stream_steps.rb +50 -0
- data/features/stream.feature +17 -0
- data/features/support/common.rb +1 -0
- data/features/support/env.rb +37 -0
- data/features/support/world.rb +1 -0
- data/lib/rtsp/client.rb +272 -0
- data/lib/rtsp/request_messages.rb +104 -0
- data/lib/rtsp/response.rb +76 -0
- data/lib/rtsp/status_code.rb +7 -0
- data/lib/rtsp.rb +12 -0
- data/spec/.rspec +1 -0
- data/spec/rtsp/client_spec.rb +38 -0
- data/spec/rtsp/response_spec.rb +189 -0
- data/spec/rtsp_spec.rb +27 -0
- data/spec/spec_helper.rb +11 -0
- metadata +241 -0
data/.autotest
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
# -*- ruby -*-
|
2
|
+
|
3
|
+
require 'autotest/restart'
|
4
|
+
|
5
|
+
# Autotest.add_hook :initialize do |at|
|
6
|
+
# at.extra_files << "../some/external/dependency.rb"
|
7
|
+
#
|
8
|
+
# at.libs << ":../some/external"
|
9
|
+
#
|
10
|
+
# at.add_exception 'vendor'
|
11
|
+
#
|
12
|
+
# at.add_mapping(/dependency.rb/) do |f, _|
|
13
|
+
# at.files_matching(/test_.*rb$/)
|
14
|
+
# end
|
15
|
+
#
|
16
|
+
# %w(TestA TestB).each do |klass|
|
17
|
+
# at.extra_class_map[klass] = "test/test_misc.rb"
|
18
|
+
# end
|
19
|
+
# end
|
20
|
+
|
21
|
+
# Autotest.add_hook :run_command do |at|
|
22
|
+
# system "rake build"
|
23
|
+
# end
|
data/.infinity_test
ADDED
data/.rspec
ADDED
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,104 @@
|
|
1
|
+
GEM
|
2
|
+
remote: http://rubygems.org/
|
3
|
+
specs:
|
4
|
+
Saikuro (1.1.0)
|
5
|
+
abstract (1.0.0)
|
6
|
+
activesupport (3.0.3)
|
7
|
+
arrayfields (4.7.4)
|
8
|
+
blankslate (2.1.2.3)
|
9
|
+
chronic (0.2.3)
|
10
|
+
hoe (>= 1.2.1)
|
11
|
+
churn (0.0.13)
|
12
|
+
chronic (>= 0.2.3)
|
13
|
+
hirb
|
14
|
+
json_pure
|
15
|
+
main
|
16
|
+
ruby_parser (~> 2.0.4)
|
17
|
+
sexp_processor (~> 3.0.3)
|
18
|
+
code_statistics (0.2.13)
|
19
|
+
colored (1.2)
|
20
|
+
diff-lcs (1.1.2)
|
21
|
+
erubis (2.6.6)
|
22
|
+
abstract (>= 1.0.0)
|
23
|
+
fattr (2.2.0)
|
24
|
+
flay (1.4.1)
|
25
|
+
ruby_parser (~> 2.0)
|
26
|
+
sexp_processor (~> 3.0)
|
27
|
+
flog (2.5.0)
|
28
|
+
ruby_parser (~> 2.0)
|
29
|
+
sexp_processor (~> 3.0)
|
30
|
+
haml (3.0.25)
|
31
|
+
hirb (0.3.6)
|
32
|
+
hoe (2.8.0)
|
33
|
+
rake (>= 0.8.7)
|
34
|
+
hoe-yard (0.1.2)
|
35
|
+
yard (>= 0.2.3.1)
|
36
|
+
i18n (0.5.0)
|
37
|
+
infinity_test (1.0.2)
|
38
|
+
notifiers (>= 1.1.0)
|
39
|
+
watchr (>= 0.7)
|
40
|
+
json_pure (1.4.6)
|
41
|
+
main (4.4.0)
|
42
|
+
arrayfields (>= 4.7.4)
|
43
|
+
fattr (>= 2.1.0)
|
44
|
+
metric_fu (2.0.1)
|
45
|
+
Saikuro (>= 1.1.0)
|
46
|
+
activesupport (>= 2.0.0)
|
47
|
+
chronic (~> 0.2.3)
|
48
|
+
churn (>= 0.0.7)
|
49
|
+
flay (>= 1.2.1)
|
50
|
+
flog (>= 2.2.0)
|
51
|
+
rails_best_practices (>= 0.3.16)
|
52
|
+
rcov (>= 0.8.3.3)
|
53
|
+
reek (>= 1.2.6)
|
54
|
+
roodi (>= 2.1.0)
|
55
|
+
notifiers (1.1.0)
|
56
|
+
parslet (1.0.1)
|
57
|
+
blankslate (~> 2.1.2.3)
|
58
|
+
rails_best_practices (0.6.5)
|
59
|
+
activesupport
|
60
|
+
colored (~> 1.2)
|
61
|
+
erubis (~> 2.6.6)
|
62
|
+
haml (~> 3.0.18)
|
63
|
+
i18n
|
64
|
+
ruby-progressbar (~> 0.0.9)
|
65
|
+
ruby_parser (~> 2.0.4)
|
66
|
+
rake (0.8.7)
|
67
|
+
rcov (0.9.9)
|
68
|
+
reek (1.2.8)
|
69
|
+
ruby2ruby (~> 1.2)
|
70
|
+
ruby_parser (~> 2.0)
|
71
|
+
sexp_processor (~> 3.0)
|
72
|
+
roodi (2.1.0)
|
73
|
+
ruby_parser
|
74
|
+
rspec (2.4.0)
|
75
|
+
rspec-core (~> 2.4.0)
|
76
|
+
rspec-expectations (~> 2.4.0)
|
77
|
+
rspec-mocks (~> 2.4.0)
|
78
|
+
rspec-core (2.4.0)
|
79
|
+
rspec-expectations (2.4.0)
|
80
|
+
diff-lcs (~> 1.1.2)
|
81
|
+
rspec-mocks (2.4.0)
|
82
|
+
ruby-progressbar (0.0.9)
|
83
|
+
ruby2ruby (1.2.5)
|
84
|
+
ruby_parser (~> 2.0)
|
85
|
+
sexp_processor (~> 3.0)
|
86
|
+
ruby_parser (2.0.5)
|
87
|
+
sexp_processor (~> 3.0)
|
88
|
+
sdp (0.2.0)
|
89
|
+
parslet (~> 1.0.0)
|
90
|
+
sexp_processor (3.0.5)
|
91
|
+
watchr (0.7)
|
92
|
+
yard (0.6.4)
|
93
|
+
|
94
|
+
PLATFORMS
|
95
|
+
ruby
|
96
|
+
|
97
|
+
DEPENDENCIES
|
98
|
+
code_statistics (~> 0.2.13)
|
99
|
+
hoe-yard
|
100
|
+
infinity_test
|
101
|
+
metric_fu
|
102
|
+
rspec (~> 2.4.0)
|
103
|
+
sdp (~> 0.2.0)
|
104
|
+
yard (~> 0.6.0)
|
data/History.txt
ADDED
data/Manifest.txt
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
.autotest
|
2
|
+
.infinity_test
|
3
|
+
.rspec
|
4
|
+
Gemfile
|
5
|
+
Gemfile.lock
|
6
|
+
History.txt
|
7
|
+
Manifest.txt
|
8
|
+
PostInstall.txt
|
9
|
+
README.rdoc
|
10
|
+
Rakefile
|
11
|
+
bin/rtsp
|
12
|
+
features/step_definitions/stream_steps.rb
|
13
|
+
features/stream.feature
|
14
|
+
features/support/common.rb
|
15
|
+
features/support/env.rb
|
16
|
+
features/support/world.rb
|
17
|
+
lib/rtsp.rb
|
18
|
+
lib/rtsp/client.rb
|
19
|
+
lib/rtsp/request_messages.rb
|
20
|
+
lib/rtsp/response.rb
|
21
|
+
lib/rtsp/status_code.rb
|
22
|
+
spec/.rspec
|
23
|
+
spec/rtsp/client_spec.rb
|
24
|
+
spec/rtsp/response_spec.rb
|
25
|
+
spec/rtsp_spec.rb
|
26
|
+
spec/spec_helper.rb
|
data/PostInstall.txt
ADDED
data/README.rdoc
ADDED
@@ -0,0 +1,74 @@
|
|
1
|
+
= rtsp_client
|
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://www.ietf.org/rfc/rfc2326.txt
|
14
|
+
|
15
|
+
SDP: http://tools.ietf.org/html/rfc4566
|
16
|
+
|
17
|
+
== FEATURES/PROBLEMS:
|
18
|
+
|
19
|
+
* RTSP client
|
20
|
+
* Currently, only unicast
|
21
|
+
|
22
|
+
== SYNOPSIS:
|
23
|
+
|
24
|
+
The uber-quick get started:
|
25
|
+
|
26
|
+
rtsp_client = RTSP::Client.new "192.168.1.10"
|
27
|
+
rtsp_client.setup :port => 8554
|
28
|
+
rtsp_client.play
|
29
|
+
rtsp_client.teardown
|
30
|
+
|
31
|
+
== REQUIREMENTS:
|
32
|
+
|
33
|
+
* Ruby
|
34
|
+
* 1.8.7
|
35
|
+
* 1.9.1
|
36
|
+
* 1.9.2
|
37
|
+
|
38
|
+
== INSTALL:
|
39
|
+
|
40
|
+
* (sudo) gem install rtsp
|
41
|
+
|
42
|
+
== DEVELOPERS:
|
43
|
+
|
44
|
+
After checking out the source, run:
|
45
|
+
|
46
|
+
$ rake newb
|
47
|
+
|
48
|
+
This task will install any missing dependencies, run the tests/specs,
|
49
|
+
and generate the RDoc.
|
50
|
+
|
51
|
+
== LICENSE:
|
52
|
+
|
53
|
+
(The MIT License)
|
54
|
+
|
55
|
+
Copyright (c) 2010 FIX
|
56
|
+
|
57
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
58
|
+
a copy of this software and associated documentation files (the
|
59
|
+
'Software'), to deal in the Software without restriction, including
|
60
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
61
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
62
|
+
permit persons to whom the Software is furnished to do so, subject to
|
63
|
+
the following conditions:
|
64
|
+
|
65
|
+
The above copyright notice and this permission notice shall be
|
66
|
+
included in all copies or substantial portions of the Software.
|
67
|
+
|
68
|
+
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
69
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
70
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
71
|
+
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
72
|
+
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
73
|
+
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
74
|
+
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/Rakefile
ADDED
@@ -0,0 +1,57 @@
|
|
1
|
+
require 'rubygems' if RUBY_VERSION < "1.9.0"
|
2
|
+
require 'hoe'
|
3
|
+
require 'hoe/yard'
|
4
|
+
require 'yard'
|
5
|
+
require 'newgem/tasks'
|
6
|
+
require 'bundler/setup'
|
7
|
+
require File.expand_path(File.dirname(__FILE__)) + '/lib/rtsp'
|
8
|
+
|
9
|
+
Hoe.plugin :newgem
|
10
|
+
Hoe.plugin :yard
|
11
|
+
Hoe.plugin :cucumberfeatures
|
12
|
+
Hoe.plugins.delete :rubyforge
|
13
|
+
|
14
|
+
# Gets the description from the README file
|
15
|
+
def get_descr_from_readme
|
16
|
+
paragraph_count = 0
|
17
|
+
|
18
|
+
File.readlines('README.rdoc', '').each do |paragraph|
|
19
|
+
paragraph_count += 1
|
20
|
+
|
21
|
+
return paragraph if paragraph_count == 2
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
# The main Gemspec definition
|
26
|
+
Hoe.spec 'rtsp' do
|
27
|
+
self.summary = 'Library to allow RTSP streaming from RTSP-enabled devices.'
|
28
|
+
self.developer('Steve Loveless & Mike Kirby', 'steve.loveless@gmail.com, mkirby@gmail.com')
|
29
|
+
self.post_install_message = File.readlines 'PostInstall.txt'
|
30
|
+
self.version = RTSP::VERSION
|
31
|
+
self.url = RTSP::WWW
|
32
|
+
self.description = get_descr_from_readme
|
33
|
+
self.readme_file = 'README.rdoc'
|
34
|
+
self.history_file = 'History.txt'
|
35
|
+
self.rspec_options += ['--color', '--format', 'documentation']
|
36
|
+
self.extra_deps += [
|
37
|
+
['sdp', '~>0.2.0']
|
38
|
+
]
|
39
|
+
self.extra_dev_deps += [
|
40
|
+
['rspec', ">=2.0.1"],
|
41
|
+
['yard', '>=0.6.4'],
|
42
|
+
['cucumber'],
|
43
|
+
['hoe-yard', '>=0.1.2']
|
44
|
+
]
|
45
|
+
|
46
|
+
self.test_globs = 'spec/*.rb'
|
47
|
+
|
48
|
+
# Extra Yard options
|
49
|
+
self.yard_title = "#{self.name} Documentation (#{self.version})"
|
50
|
+
self.yard_opts += ['--output-dir', 'doc']
|
51
|
+
self.yard_opts += ['--private']
|
52
|
+
self.yard_opts += ['--protected']
|
53
|
+
self.yard_opts += ['--verbose']
|
54
|
+
self.yard_opts += ['--files',
|
55
|
+
[self.history_file, 'Manifest.txt', self.readme_file]
|
56
|
+
]
|
57
|
+
end
|
data/bin/rtsp
ADDED
@@ -0,0 +1,121 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require 'tempfile'
|
5
|
+
require 'optparse'
|
6
|
+
|
7
|
+
$:.unshift File.expand_path(File.dirname(__FILE__) + '/../lib/')
|
8
|
+
require 'rtsp/client'
|
9
|
+
|
10
|
+
options = {}
|
11
|
+
|
12
|
+
optparse = OptionParser.new do |opts|
|
13
|
+
opts.banner = "Usage: #{__FILE__} [options] url"
|
14
|
+
|
15
|
+
options[:debug] = false
|
16
|
+
opts.on('-d', '--debug', "Turn on debug logging. (not hooked up!)") do
|
17
|
+
options[:debug] = true
|
18
|
+
end
|
19
|
+
|
20
|
+
opts.on('--show-tracks', "Show available tracks from the given URL.") do |url|
|
21
|
+
rtsp_client = RTSP::Client.new(url)
|
22
|
+
puts rtsp_client.stream_tracks
|
23
|
+
end
|
24
|
+
|
25
|
+
opts.on('-h', '--help', "You're looking at it.") do
|
26
|
+
puts opts
|
27
|
+
exit
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
optparse.parse!
|
32
|
+
|
33
|
+
# Allows for running an RTSP client
|
34
|
+
url = ARGV.first || "rtsp://64.202.98.91:554/sa.sdp"
|
35
|
+
|
36
|
+
rtsp_client = RTSP::Client.new(url)
|
37
|
+
response = rtsp_client.options
|
38
|
+
puts "code: #{response.code}"
|
39
|
+
puts "message: #{response.message}"
|
40
|
+
#puts "server: #{response.server}"
|
41
|
+
puts "cseq: #{response.cseq}"
|
42
|
+
puts "public: #{response.public}"
|
43
|
+
|
44
|
+
response = rtsp_client.describe
|
45
|
+
puts "code: #{response.code}"
|
46
|
+
puts "message: #{response.message}"
|
47
|
+
puts "server: #{response.server}" if response.respond_to? "server"
|
48
|
+
puts "cseq: #{response.cseq}"
|
49
|
+
puts "cache_control: #{response.cache_control}" if response.respond_to? "cache_control"
|
50
|
+
puts "content_length: #{response.content_length}"
|
51
|
+
puts "date: #{response.date}"
|
52
|
+
puts "expires: #{response.expires}" if response.respond_to? "expires"
|
53
|
+
puts "content_type: #{response.content_type}"
|
54
|
+
puts "content_base: #{response.content_base}"
|
55
|
+
|
56
|
+
# content_base is the base URI for any track to work with
|
57
|
+
track = URI.parse response.content_base
|
58
|
+
puts rtsp_client.aggregate_control_track
|
59
|
+
puts rtsp_client.media_control_tracks
|
60
|
+
|
61
|
+
# Add the first media_control_track to the URI
|
62
|
+
puts track.path += rtsp_client.media_control_tracks.first
|
63
|
+
puts track.to_s
|
64
|
+
|
65
|
+
# Replace the client's list of tracks with the available track
|
66
|
+
rtsp_client.stream_tracks[0] = track.to_s
|
67
|
+
response = rtsp_client.setup(:destination => 'unicast')
|
68
|
+
puts "code: #{response.code}"
|
69
|
+
puts "message: #{response.message}"
|
70
|
+
puts "server: #{response.server}" if response.respond_to? "server"
|
71
|
+
puts "cseq: #{response.cseq}"
|
72
|
+
puts "session: #{response.session}"
|
73
|
+
puts "transport: #{response.transport}"
|
74
|
+
session = response.session
|
75
|
+
transport_info = response.transport
|
76
|
+
|
77
|
+
if response.message == "OK"
|
78
|
+
r = rtsp_client.play(:session => session)
|
79
|
+
puts "code: #{r.code}"
|
80
|
+
puts "message: #{r.message}"
|
81
|
+
puts "server: #{r.server}" if response.respond_to? "server"
|
82
|
+
puts "cseq: #{r.cseq}"
|
83
|
+
puts "session: #{r.session}"
|
84
|
+
puts "range: #{r.range}"
|
85
|
+
puts "rtp_info: #{r.rtp_info}"
|
86
|
+
cseq = r.cseq
|
87
|
+
sleep 5
|
88
|
+
#rtsp_client.pause({ :session => session, :sequence => cseq })
|
89
|
+
r2 = rtsp_client.teardown
|
90
|
+
puts "code: #{r2.code}"
|
91
|
+
puts "message: #{r2.message}"
|
92
|
+
puts "server: #{r2.server}" if r2.respond_to? "server"
|
93
|
+
puts "cseq: #{r2.cseq}"
|
94
|
+
puts "connection: #{r2.connection}" if r2.respond_to? "connection"
|
95
|
+
end
|
96
|
+
exit
|
97
|
+
|
98
|
+
#rtsp_client = RTSP::Client.new "192.168.10.219"
|
99
|
+
#rtsp_client.setup :port => 8554
|
100
|
+
|
101
|
+
socket = UDPSocket.new
|
102
|
+
socket.bind "0.0.0.0", 8554
|
103
|
+
streamed_file = Tempfile.new "spectra_hd_streamed_file"
|
104
|
+
|
105
|
+
begin
|
106
|
+
Timeout::timeout(5) do
|
107
|
+
while data = socket.recvfrom(102400).first
|
108
|
+
puts "data size = #{data.size}"
|
109
|
+
streamed_file.write data
|
110
|
+
end
|
111
|
+
end
|
112
|
+
rescue Timeout::Error
|
113
|
+
# blah
|
114
|
+
end
|
115
|
+
|
116
|
+
socket.close
|
117
|
+
rtsp_client.teardown
|
118
|
+
|
119
|
+
require 'fileutils'
|
120
|
+
FileUtils.cp(streamed_file, "/Users/sloveless/Desktop/")
|
121
|
+
streamed_file.close
|
@@ -0,0 +1,50 @@
|
|
1
|
+
Given /^an RTSP server at "([^"]*)" and port (\d+)$/ do |ip_address, port|
|
2
|
+
@rtp_port = port
|
3
|
+
@client = RTSP::Client.new ip_address
|
4
|
+
@client.setup :port => @rtp_port.to_i
|
5
|
+
end
|
6
|
+
|
7
|
+
Given /^an RTSP server at "([^"]*)" and port (\d+) and URL "([^"]*)"$/ do |ip_address, port, path|
|
8
|
+
uri = "rtsp://#{ip_address}:#{port}#{path}"
|
9
|
+
@rtp_port = port
|
10
|
+
@client = RTSP::Client.new uri
|
11
|
+
#@client.setup( { :port => @rtp_port.to_i, :stream_path => path })
|
12
|
+
@client.setup( { :port => @rtp_port.to_i })
|
13
|
+
end
|
14
|
+
|
15
|
+
When /^I play a stream from that server$/ do
|
16
|
+
@play_result = lambda { @client.play }
|
17
|
+
end
|
18
|
+
|
19
|
+
Then /^I should not receive any errors$/ do
|
20
|
+
@play_result.should_not raise_error
|
21
|
+
end
|
22
|
+
|
23
|
+
Then /^I should receive data on the same port$/ do
|
24
|
+
socket = UDPSocket.new
|
25
|
+
socket.bind("0.0.0.0", @rtp_port)
|
26
|
+
|
27
|
+
begin
|
28
|
+
status = Timeout::timeout(5) do
|
29
|
+
while data = socket.recvfrom(102400)[0]
|
30
|
+
puts "marker size:#{data.size}"
|
31
|
+
puts "data: #{data}" if data =~ /\r\n/
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
data.should_not be_nil
|
36
|
+
rescue Timeout::Error
|
37
|
+
# Blind rescue
|
38
|
+
ensure
|
39
|
+
socket.close
|
40
|
+
@client.teardown
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
Given /^I know what the describe response looks like$/ do
|
45
|
+
@response_text = DESCRIBE_RESPONSE
|
46
|
+
end
|
47
|
+
|
48
|
+
When /^I ask the server to describe$/ do
|
49
|
+
puts @client.describe
|
50
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
Feature: Stream from an RTSP server
|
2
|
+
As an RTSP consumer
|
3
|
+
I want to be able to pull an RTSP stream from a server
|
4
|
+
So that I can view its contents
|
5
|
+
|
6
|
+
@wip
|
7
|
+
Scenario: Play
|
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: Describe
|
14
|
+
Given I know what the describe response looks like
|
15
|
+
When I ask the server to describe
|
16
|
+
Then I should not receive any errors
|
17
|
+
And I should receive data on the same port
|
@@ -0,0 +1 @@
|
|
1
|
+
|
@@ -0,0 +1,37 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'socket'
|
3
|
+
require 'timeout'
|
4
|
+
|
5
|
+
$:.unshift(File.dirname(__FILE__) + '/../../lib')
|
6
|
+
require 'rtsp/client'
|
7
|
+
|
8
|
+
|
9
|
+
DESCRIBE_RESPONSE = <<-RESP
|
10
|
+
RTSP/1.0 200 OK
|
11
|
+
Server: DSS/5.5 (Build/489.7; Platform/Linux; Release/Darwin; )
|
12
|
+
Cseq: 1
|
13
|
+
Cache-Control: no-cache
|
14
|
+
Content-length: 406
|
15
|
+
Date: Sun, 23 Jan 2011 00:36:45 GMT
|
16
|
+
Expires: Sun, 23 Jan 2011 00:36:45 GMT
|
17
|
+
Content-Type: application/sdp
|
18
|
+
x-Accept-Retransmit: our-retransmit
|
19
|
+
x-Accept-Dynamic-Rate: 1
|
20
|
+
Content-Base: rtsp://64.202.98.91:554/gs.sdp/
|
21
|
+
|
22
|
+
v=0
|
23
|
+
o=- 545877020 467920391 IN IP4 127.0.0.1
|
24
|
+
s=Groove Salad from SomaFM [aacPlus]
|
25
|
+
i=Downtempo Ambient Groove
|
26
|
+
c=IN IP4 0.0.0.0
|
27
|
+
t=0 0
|
28
|
+
a=x-qt-text-cmt:Orban Opticodec-PC
|
29
|
+
a=x-qt-text-nam:Groove Salad from SomaFM [aacPlus]
|
30
|
+
a=x-qt-text-inf:Downtempo Ambient Groove
|
31
|
+
a=control:*
|
32
|
+
m=audio 0 RTP/AVP 96
|
33
|
+
b=AS:48
|
34
|
+
a=rtpmap:96 MP4A-LATM/44100/2
|
35
|
+
a=fmtp:96 cpresent=0;config=400027200000
|
36
|
+
a=control:trackID=1
|
37
|
+
RESP
|
@@ -0,0 +1 @@
|
|
1
|
+
|