rtsp 0.0.1.alpha

Sign up to get free protection for your applications and to get access to all the features.
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
@@ -0,0 +1,4 @@
1
+ infinity_test do
2
+ use :rubies => %w(1.8.7 1.9.1 1.9.2), :test_framework => :rspec
3
+ notifications :growl
4
+ end
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --format documentation
2
+ --color
3
+ --tty
data/Gemfile ADDED
@@ -0,0 +1,12 @@
1
+ source :rubygems
2
+
3
+ gem 'sdp', '~> 0.2.0'
4
+
5
+ group :development do
6
+ gem "rspec", '~> 2.4.0'
7
+ gem "hoe-yard", :require => "hoe/yard"
8
+ gem 'yard', '~> 0.6.0'
9
+ gem 'infinity_test'
10
+ gem 'metric_fu'
11
+ gem 'code_statistics', '~> 0.2.13'
12
+ end
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
@@ -0,0 +1,4 @@
1
+ h3. 0.0.1 / 2010-12-15
2
+
3
+ * Happy birthday!
4
+
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
@@ -0,0 +1,7 @@
1
+
2
+ Thanks for installing rtsp. We hope you get some good streaming out of it!
3
+
4
+ Take a look at the README to help get you started.
5
+
6
+ NOTE: This is only an alpha version!! It is not well tested and doesn't have
7
+ much error handling built in yet.
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
+