rtsp 0.0.1.alpha

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.
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
+