rtsp 0.4.3 → 0.4.4
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.
- checksums.yaml +7 -0
- data/ChangeLog.rdoc +37 -18
- data/Gemfile +1 -1
- data/Rakefile +2 -1
- data/bin/client_tester +78 -0
- data/bin/rtsp_client +13 -0
- data/lib/rtsp.rb +9 -1
- data/lib/rtsp/client.rb +35 -4
- data/lib/rtsp/message.rb +8 -0
- data/lib/rtsp/transport_parser.rb +24 -1
- data/lib/rtsp/version.rb +11 -2
- data/rtsp.gemspec +14 -14
- data/spec/integration/client_use_spec.rb +102 -72
- data/spec/integration/real_server_wowza_client_use_spec.rb +250 -0
- data/spec/support/fake_rtsp_server.rb +5 -1
- data/spec/unit/rtsp_spec.rb +16 -4
- metadata +31 -216
- data/lib/ext/time_ext.rb +0 -7
- data/lib/rtsp/presentation.rb +0 -160
- data/lib/rtsp/session.rb +0 -65
- data/spec/integration/coverage/assets/0.7.1/application.css +0 -1110
- data/spec/integration/coverage/assets/0.7.1/application.js +0 -626
- data/spec/integration/coverage/assets/0.7.1/fancybox/blank.gif +0 -0
- data/spec/integration/coverage/assets/0.7.1/fancybox/fancy_close.png +0 -0
- data/spec/integration/coverage/assets/0.7.1/fancybox/fancy_loading.png +0 -0
- data/spec/integration/coverage/assets/0.7.1/fancybox/fancy_nav_left.png +0 -0
- data/spec/integration/coverage/assets/0.7.1/fancybox/fancy_nav_right.png +0 -0
- data/spec/integration/coverage/assets/0.7.1/fancybox/fancy_shadow_e.png +0 -0
- data/spec/integration/coverage/assets/0.7.1/fancybox/fancy_shadow_n.png +0 -0
- data/spec/integration/coverage/assets/0.7.1/fancybox/fancy_shadow_ne.png +0 -0
- data/spec/integration/coverage/assets/0.7.1/fancybox/fancy_shadow_nw.png +0 -0
- data/spec/integration/coverage/assets/0.7.1/fancybox/fancy_shadow_s.png +0 -0
- data/spec/integration/coverage/assets/0.7.1/fancybox/fancy_shadow_se.png +0 -0
- data/spec/integration/coverage/assets/0.7.1/fancybox/fancy_shadow_sw.png +0 -0
- data/spec/integration/coverage/assets/0.7.1/fancybox/fancy_shadow_w.png +0 -0
- data/spec/integration/coverage/assets/0.7.1/fancybox/fancy_title_left.png +0 -0
- data/spec/integration/coverage/assets/0.7.1/fancybox/fancy_title_main.png +0 -0
- data/spec/integration/coverage/assets/0.7.1/fancybox/fancy_title_over.png +0 -0
- data/spec/integration/coverage/assets/0.7.1/fancybox/fancy_title_right.png +0 -0
- data/spec/integration/coverage/assets/0.7.1/fancybox/fancybox-x.png +0 -0
- data/spec/integration/coverage/assets/0.7.1/fancybox/fancybox-y.png +0 -0
- data/spec/integration/coverage/assets/0.7.1/fancybox/fancybox.png +0 -0
- data/spec/integration/coverage/assets/0.7.1/favicon_green.png +0 -0
- data/spec/integration/coverage/assets/0.7.1/favicon_red.png +0 -0
- data/spec/integration/coverage/assets/0.7.1/favicon_yellow.png +0 -0
- data/spec/integration/coverage/assets/0.7.1/loading.gif +0 -0
- data/spec/integration/coverage/assets/0.7.1/magnify.png +0 -0
- data/spec/integration/coverage/assets/0.7.1/smoothness/images/ui-bg_flat_0_aaaaaa_40x100.png +0 -0
- data/spec/integration/coverage/assets/0.7.1/smoothness/images/ui-bg_flat_75_ffffff_40x100.png +0 -0
- data/spec/integration/coverage/assets/0.7.1/smoothness/images/ui-bg_glass_55_fbf9ee_1x400.png +0 -0
- data/spec/integration/coverage/assets/0.7.1/smoothness/images/ui-bg_glass_65_ffffff_1x400.png +0 -0
- data/spec/integration/coverage/assets/0.7.1/smoothness/images/ui-bg_glass_75_dadada_1x400.png +0 -0
- data/spec/integration/coverage/assets/0.7.1/smoothness/images/ui-bg_glass_75_e6e6e6_1x400.png +0 -0
- data/spec/integration/coverage/assets/0.7.1/smoothness/images/ui-bg_glass_95_fef1ec_1x400.png +0 -0
- data/spec/integration/coverage/assets/0.7.1/smoothness/images/ui-bg_highlight-soft_75_cccccc_1x100.png +0 -0
- data/spec/integration/coverage/assets/0.7.1/smoothness/images/ui-icons_222222_256x240.png +0 -0
- data/spec/integration/coverage/assets/0.7.1/smoothness/images/ui-icons_2e83ff_256x240.png +0 -0
- data/spec/integration/coverage/assets/0.7.1/smoothness/images/ui-icons_454545_256x240.png +0 -0
- data/spec/integration/coverage/assets/0.7.1/smoothness/images/ui-icons_888888_256x240.png +0 -0
- data/spec/integration/coverage/assets/0.7.1/smoothness/images/ui-icons_cd0a0a_256x240.png +0 -0
- data/spec/integration/coverage/index.html +0 -72
- data/spec/unit/ext/coverage/assets/0.7.1/application.css +0 -1110
- data/spec/unit/ext/coverage/assets/0.7.1/application.js +0 -626
- data/spec/unit/ext/coverage/assets/0.7.1/fancybox/blank.gif +0 -0
- data/spec/unit/ext/coverage/assets/0.7.1/fancybox/fancy_close.png +0 -0
- data/spec/unit/ext/coverage/assets/0.7.1/fancybox/fancy_loading.png +0 -0
- data/spec/unit/ext/coverage/assets/0.7.1/fancybox/fancy_nav_left.png +0 -0
- data/spec/unit/ext/coverage/assets/0.7.1/fancybox/fancy_nav_right.png +0 -0
- data/spec/unit/ext/coverage/assets/0.7.1/fancybox/fancy_shadow_e.png +0 -0
- data/spec/unit/ext/coverage/assets/0.7.1/fancybox/fancy_shadow_n.png +0 -0
- data/spec/unit/ext/coverage/assets/0.7.1/fancybox/fancy_shadow_ne.png +0 -0
- data/spec/unit/ext/coverage/assets/0.7.1/fancybox/fancy_shadow_nw.png +0 -0
- data/spec/unit/ext/coverage/assets/0.7.1/fancybox/fancy_shadow_s.png +0 -0
- data/spec/unit/ext/coverage/assets/0.7.1/fancybox/fancy_shadow_se.png +0 -0
- data/spec/unit/ext/coverage/assets/0.7.1/fancybox/fancy_shadow_sw.png +0 -0
- data/spec/unit/ext/coverage/assets/0.7.1/fancybox/fancy_shadow_w.png +0 -0
- data/spec/unit/ext/coverage/assets/0.7.1/fancybox/fancy_title_left.png +0 -0
- data/spec/unit/ext/coverage/assets/0.7.1/fancybox/fancy_title_main.png +0 -0
- data/spec/unit/ext/coverage/assets/0.7.1/fancybox/fancy_title_over.png +0 -0
- data/spec/unit/ext/coverage/assets/0.7.1/fancybox/fancy_title_right.png +0 -0
- data/spec/unit/ext/coverage/assets/0.7.1/fancybox/fancybox-x.png +0 -0
- data/spec/unit/ext/coverage/assets/0.7.1/fancybox/fancybox-y.png +0 -0
- data/spec/unit/ext/coverage/assets/0.7.1/fancybox/fancybox.png +0 -0
- data/spec/unit/ext/coverage/assets/0.7.1/favicon_green.png +0 -0
- data/spec/unit/ext/coverage/assets/0.7.1/favicon_red.png +0 -0
- data/spec/unit/ext/coverage/assets/0.7.1/favicon_yellow.png +0 -0
- data/spec/unit/ext/coverage/assets/0.7.1/loading.gif +0 -0
- data/spec/unit/ext/coverage/assets/0.7.1/magnify.png +0 -0
- data/spec/unit/ext/coverage/assets/0.7.1/smoothness/images/ui-bg_flat_0_aaaaaa_40x100.png +0 -0
- data/spec/unit/ext/coverage/assets/0.7.1/smoothness/images/ui-bg_flat_75_ffffff_40x100.png +0 -0
- data/spec/unit/ext/coverage/assets/0.7.1/smoothness/images/ui-bg_glass_55_fbf9ee_1x400.png +0 -0
- data/spec/unit/ext/coverage/assets/0.7.1/smoothness/images/ui-bg_glass_65_ffffff_1x400.png +0 -0
- data/spec/unit/ext/coverage/assets/0.7.1/smoothness/images/ui-bg_glass_75_dadada_1x400.png +0 -0
- data/spec/unit/ext/coverage/assets/0.7.1/smoothness/images/ui-bg_glass_75_e6e6e6_1x400.png +0 -0
- data/spec/unit/ext/coverage/assets/0.7.1/smoothness/images/ui-bg_glass_95_fef1ec_1x400.png +0 -0
- data/spec/unit/ext/coverage/assets/0.7.1/smoothness/images/ui-bg_highlight-soft_75_cccccc_1x100.png +0 -0
- data/spec/unit/ext/coverage/assets/0.7.1/smoothness/images/ui-icons_222222_256x240.png +0 -0
- data/spec/unit/ext/coverage/assets/0.7.1/smoothness/images/ui-icons_2e83ff_256x240.png +0 -0
- data/spec/unit/ext/coverage/assets/0.7.1/smoothness/images/ui-icons_454545_256x240.png +0 -0
- data/spec/unit/ext/coverage/assets/0.7.1/smoothness/images/ui-icons_888888_256x240.png +0 -0
- data/spec/unit/ext/coverage/assets/0.7.1/smoothness/images/ui-icons_cd0a0a_256x240.png +0 -0
- data/spec/unit/ext/coverage/index.html +0 -72
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA1:
|
|
3
|
+
metadata.gz: 28131f72eddd446ae03db4520033ac3d4e4b4fb0
|
|
4
|
+
data.tar.gz: b272f509cd3dbb6380ade57c31821b56e892fb1b
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: 1b5fe820b9b15ceceed4663bc94248086591e017e1eadfb41fed47b2e5a12977975d7f0618ee07c8a71e5c7de9662aba9d52c92c4548805c391153f7aa792661
|
|
7
|
+
data.tar.gz: 27337607eb94371bb43b15bd5ad9521c4df9ecd58e70310f0cdcc93d6270f9b516b75da90f534f3dceb0388cef377d20b3a18f07aa7481a29dadc13fd6582d8f
|
data/ChangeLog.rdoc
CHANGED
|
@@ -1,3 +1,12 @@
|
|
|
1
|
+
=== 0.4.4 / 2013-07-01
|
|
2
|
+
|
|
3
|
+
* Improvements
|
|
4
|
+
* {gh-21}[htts://github.com/turboladen/rtsp/issues/21] Transport header
|
|
5
|
+
parser is now a little more flexible. This functionality really needs a
|
|
6
|
+
rewrite, and should be done as part of
|
|
7
|
+
{gh-15}[htts://github.com/turboladen/rtsp/issues/15]. Thanks
|
|
8
|
+
{nmccready}[http:github.com/nmccready]!
|
|
9
|
+
|
|
1
10
|
=== 0.4.3 / 2012-11-20
|
|
2
11
|
|
|
3
12
|
* Bug fixes
|
|
@@ -12,25 +21,29 @@
|
|
|
12
21
|
* Other
|
|
13
22
|
* Turned logging off by default. To enable, simply do <tt>RTSP::Client.log = true</tt>
|
|
14
23
|
* Updated to work with RTP 0.1.0.
|
|
15
|
-
* Can now inspect RTP packets during #play.
|
|
24
|
+
* Can now inspect RTP packets during {RTSP::Client#play}.
|
|
16
25
|
|
|
17
26
|
=== 0.4.1 / 2012-11-14
|
|
18
27
|
|
|
19
28
|
* Bug fixes
|
|
20
|
-
* gh-16: Can now parse Session
|
|
29
|
+
* gh-16[https://github.com/turboladen/rtsp/issues/16]: Can now parse +Session+
|
|
30
|
+
IDs to be alpha characters. Thanks
|
|
31
|
+
greywolf-colorado[http://github.com/greywolf-colorado]!
|
|
21
32
|
|
|
22
33
|
* Improvements
|
|
23
|
-
* gh-17: Responses now handle
|
|
34
|
+
* gh-17[https://github.com/turboladen/rtsp/issues/17]: Responses now handle
|
|
35
|
+
HTTP responses.
|
|
24
36
|
|
|
25
37
|
=== 0.4.0 / 2012-03-08
|
|
26
38
|
|
|
27
39
|
* Improvements
|
|
28
|
-
* gh-11: Transport header
|
|
40
|
+
* gh-11[https://github.com/turboladen/rtsp/issues/17]: Transport header
|
|
41
|
+
parser bolstering:
|
|
29
42
|
* values that should be caps, will parse OK as lowercase now.
|
|
30
|
-
*
|
|
31
|
-
*
|
|
43
|
+
* +:broadcast_type+ now parses 'multicast'.
|
|
44
|
+
* +:destination+ now returns the value of the destination instead of
|
|
32
45
|
"destination=x.x.x.x"
|
|
33
|
-
*
|
|
46
|
+
* +:source+ now returns the value of the source instead of "source=x.x.x.x"
|
|
34
47
|
* Added parsing for fields:
|
|
35
48
|
* ttl
|
|
36
49
|
* port
|
|
@@ -38,9 +51,10 @@
|
|
|
38
51
|
* channel
|
|
39
52
|
* address
|
|
40
53
|
* mode
|
|
41
|
-
* gh-10: Session header now
|
|
54
|
+
* gh-10[https://github.com/turboladen/rtsp/issues/10]: +Session+ header now
|
|
55
|
+
detects timeout value. This means that where use
|
|
42
56
|
of the value extracted from this header used to be a simple Integer, now you
|
|
43
|
-
have a session Hash with
|
|
57
|
+
have a session Hash with +:session_id+ and +:timeout+ keys.
|
|
44
58
|
|
|
45
59
|
=== 0.3.0 / 2012-03-02
|
|
46
60
|
|
|
@@ -55,7 +69,8 @@
|
|
|
55
69
|
=== 0.2.2 / 2011-11-02
|
|
56
70
|
|
|
57
71
|
* Bug fixes
|
|
58
|
-
* gh-6: .gemspec was missing
|
|
72
|
+
* gh-6[https://github.com/turboladen/rtsp/issues/6]: .gemspec was missing
|
|
73
|
+
+parslet+ dependency. Thanks tindron[http://github.com/tindron].
|
|
59
74
|
|
|
60
75
|
* Improvements
|
|
61
76
|
* Added a queue for listening and building the RTP file from the received data.
|
|
@@ -68,14 +83,16 @@
|
|
|
68
83
|
=== 0.2.0 / 2011-09-19
|
|
69
84
|
|
|
70
85
|
* Bug fixes
|
|
71
|
-
* gh-5: Fixed 'Bad file
|
|
86
|
+
* gh-5[https://github.com/turboladen/rtsp/issues/5]: Fixed 'Bad file
|
|
87
|
+
descriptor' bug when capturing to file.
|
|
72
88
|
|
|
73
89
|
* Improvements
|
|
74
|
-
* If RTSP::Capturer can't open port 9000, it increments by 1 and tries again,
|
|
90
|
+
* If {RTSP::Capturer} can't open port 9000, it increments by 1 and tries again,
|
|
75
91
|
50 times, then raises.
|
|
76
|
-
* gh-4: Remove dependency on ore
|
|
92
|
+
* gh-4[https://github.com/turboladen/rtsp/issues/4]: Remove dependency on ore
|
|
93
|
+
en lieu of standard gem commands.
|
|
77
94
|
* Participate in http://test.rubygems.org!
|
|
78
|
-
* Changed RTSP::Capturer init_*_server methods to take params in order to reduce
|
|
95
|
+
* Changed {RTSP::Capturer} init_*_server methods to take params in order to reduce
|
|
79
96
|
dependency on state of the Capturer object.
|
|
80
97
|
|
|
81
98
|
=== 0.1.2 / 2011-04-14
|
|
@@ -86,16 +103,18 @@
|
|
|
86
103
|
=== 0.1.1 / 2011-04-14
|
|
87
104
|
|
|
88
105
|
* Bug fixes
|
|
89
|
-
* gh-1: No longer use
|
|
90
|
-
|
|
106
|
+
* gh-1[https://github.com/turboladen/rtsp/issues/1]: No longer use
|
|
107
|
+
+Socket::SO_REUSEADDR+ or +Socket::SO_REUSEPORT+.
|
|
108
|
+
* gh-2[https://github.com/turboladen/rtsp/issues/2]: rtsp_client now requires
|
|
109
|
+
the installed rtsp/client.
|
|
91
110
|
|
|
92
111
|
* Improvements
|
|
93
|
-
* Capturer#run's log message now says what it's logging.
|
|
112
|
+
* {RTSP::Capturer#run}'s log message now says what it's logging.
|
|
94
113
|
* bin/rtsp_client:
|
|
95
114
|
* Fixed bad description for --stream.
|
|
96
115
|
* Added --version.
|
|
97
116
|
* Updated README.rdoc:
|
|
98
|
-
* ...to clarify that REDIRECT isn't yet supported.
|
|
117
|
+
* ...to clarify that +REDIRECT+ isn't yet supported.
|
|
99
118
|
* ...with brief usage on bin/rtsp_client.
|
|
100
119
|
|
|
101
120
|
=== 0.1.0 / 2011-04-12
|
data/Gemfile
CHANGED
data/Rakefile
CHANGED
|
@@ -6,12 +6,13 @@ RSpec::Core::RakeTask.new
|
|
|
6
6
|
|
|
7
7
|
namespace :spec do
|
|
8
8
|
RSpec::Core::RakeTask.new(:warnings) do |t|
|
|
9
|
-
t.ruby_opts =
|
|
9
|
+
t.ruby_opts = '-w'
|
|
10
10
|
end
|
|
11
11
|
end
|
|
12
12
|
task :default => :spec
|
|
13
13
|
task :test => :spec # for `gem test`
|
|
14
14
|
|
|
15
15
|
YARD::Rake::YardocTask.new do |t|
|
|
16
|
+
t.files = %w(lib/**/*.rb - ChangeLog.rdoc)
|
|
16
17
|
t.options = %w[--verbose]
|
|
17
18
|
end
|
data/bin/client_tester
ADDED
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
|
|
3
|
+
require 'thor'
|
|
4
|
+
require './lib/rtsp/client'
|
|
5
|
+
require 'bundler/setup'
|
|
6
|
+
|
|
7
|
+
RTSP::Client.log = true
|
|
8
|
+
|
|
9
|
+
class ClientTester < Thor
|
|
10
|
+
include Thor::Actions
|
|
11
|
+
|
|
12
|
+
desc "soma", "Pulls a stream from SomaFM"
|
|
13
|
+
method_options capture_file: :boolean, duration: :numeric
|
|
14
|
+
def soma
|
|
15
|
+
url = "rtsp://64.202.98.91/sa.sdp"
|
|
16
|
+
pull_stream url, options
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
desc "sarix", "Pulls a stream from a Sarix camera"
|
|
20
|
+
method_options capture_file: :boolean, duration: :numeric
|
|
21
|
+
def sarix
|
|
22
|
+
url = "rtsp://10.221.222.242/stream1"
|
|
23
|
+
pull_stream url, options
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
desc "nsm", "Pulls a stream from a NSM"
|
|
27
|
+
method_options capture_file: :boolean, duration: :numeric
|
|
28
|
+
def nsm
|
|
29
|
+
url = "rtsp://10.221.241.208/?deviceid=uuid:0f4b187e-d6dd-414d-9400-1b0d2ee225a1&starttime=2012-12-06T12:20:25&endtime=2012-12-07T01:39:09"
|
|
30
|
+
pull_stream url, options
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
no_tasks do
|
|
34
|
+
def pull_stream(url, options={})
|
|
35
|
+
capture_file = options[:capture_file] || false
|
|
36
|
+
duration = options[:duration] || 5
|
|
37
|
+
client = RTSP::Client.new(url)
|
|
38
|
+
|
|
39
|
+
client.options
|
|
40
|
+
client.describe
|
|
41
|
+
|
|
42
|
+
media_track = client.media_control_tracks.first
|
|
43
|
+
puts "media track: #{media_track}"
|
|
44
|
+
|
|
45
|
+
aggregate_track = client.aggregate_control_track
|
|
46
|
+
puts "aggregate track: #{aggregate_track}"
|
|
47
|
+
|
|
48
|
+
client.setup media_track
|
|
49
|
+
|
|
50
|
+
if capture_file
|
|
51
|
+
client.play(aggregate_track)
|
|
52
|
+
else
|
|
53
|
+
client.play(aggregate_track) do |packet|
|
|
54
|
+
this_packet = packet.sequence_number
|
|
55
|
+
puts "RTP sequence: #{this_packet}"
|
|
56
|
+
puts "payload type", packet.payload_type
|
|
57
|
+
|
|
58
|
+
if defined? last_packet
|
|
59
|
+
puts "last: #{last_packet}"
|
|
60
|
+
diff = this_packet - last_packet
|
|
61
|
+
if diff != 1
|
|
62
|
+
puts "ZOMG!!!!!!!! PACKET DIFF: #{diff}"
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
last_packet = packet.sequence_number
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
sleep duration
|
|
71
|
+
client.teardown aggregate_track
|
|
72
|
+
puts "Capture file path: #{client.capturer.capture_file.path}"
|
|
73
|
+
puts "Capture file size: #{client.capturer.capture_file.size}"
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
ClientTester.start
|
data/bin/rtsp_client
CHANGED
|
@@ -27,6 +27,19 @@ optparse = OptionParser.new do |opts|
|
|
|
27
27
|
exit
|
|
28
28
|
end
|
|
29
29
|
|
|
30
|
+
#----------------------------------------------------------------------------
|
|
31
|
+
# Get options
|
|
32
|
+
opts.on('--options [URL]', "Get options 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
|
+
puts rtsp_client.options.body.inspect
|
|
40
|
+
exit
|
|
41
|
+
end
|
|
42
|
+
|
|
30
43
|
#----------------------------------------------------------------------------
|
|
31
44
|
# Show available tracks
|
|
32
45
|
opts.on('--show-tracks [URL]', "Show available tracks from the given URL.") do |url|
|
data/lib/rtsp.rb
CHANGED
|
@@ -3,4 +3,12 @@ require_relative 'rtsp/version'
|
|
|
3
3
|
|
|
4
4
|
# This base module simply defines properties about the library. See child
|
|
5
5
|
# classes/modules for the meat.
|
|
6
|
-
module RTSP
|
|
6
|
+
module RTSP
|
|
7
|
+
def self.release_version?
|
|
8
|
+
!!RELEASE
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def self.snapshot_version?
|
|
12
|
+
!!SNAPSHOT
|
|
13
|
+
end
|
|
14
|
+
end
|
data/lib/rtsp/client.rb
CHANGED
|
@@ -2,6 +2,7 @@ require 'socket'
|
|
|
2
2
|
require 'tempfile'
|
|
3
3
|
require 'timeout'
|
|
4
4
|
require 'rtp/receiver'
|
|
5
|
+
require "base64"
|
|
5
6
|
|
|
6
7
|
require_relative 'transport_parser'
|
|
7
8
|
require_relative 'error'
|
|
@@ -60,7 +61,7 @@ module RTSP
|
|
|
60
61
|
|
|
61
62
|
# @return [URI] The URI that points to the RTSP server's resource.
|
|
62
63
|
attr_reader :server_uri
|
|
63
|
-
|
|
64
|
+
|
|
64
65
|
# @return [Fixnum] Also known as the "sequence" number, this starts at 1 and
|
|
65
66
|
# increments after every request to the server. It is reset after
|
|
66
67
|
# calling #teardown.
|
|
@@ -121,6 +122,7 @@ module RTSP
|
|
|
121
122
|
@connection.do_capture ||= true
|
|
122
123
|
@connection.interleave ||= false
|
|
123
124
|
|
|
125
|
+
@max_authorization_tries = 3
|
|
124
126
|
@cseq = 1
|
|
125
127
|
reset_state
|
|
126
128
|
end
|
|
@@ -134,6 +136,20 @@ module RTSP
|
|
|
134
136
|
@server_uri = build_resource_uri_from new_url
|
|
135
137
|
end
|
|
136
138
|
|
|
139
|
+
# The user to be used in Basic Authentication
|
|
140
|
+
#
|
|
141
|
+
# @param [String] user
|
|
142
|
+
def server_user=(user)
|
|
143
|
+
@server_uri.user = user
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
# The password to be used in Basic Authentication
|
|
147
|
+
#
|
|
148
|
+
# @param [String] password
|
|
149
|
+
def server_password=(password)
|
|
150
|
+
@server_uri.password = password
|
|
151
|
+
end
|
|
152
|
+
|
|
137
153
|
# Sends the message over the socket.
|
|
138
154
|
#
|
|
139
155
|
# @param [RTSP::Message] message
|
|
@@ -253,8 +269,10 @@ module RTSP
|
|
|
253
269
|
|
|
254
270
|
@session = response.session
|
|
255
271
|
parser = RTSP::TransportParser.new
|
|
272
|
+
#pass up raw transport for debug and/or logging
|
|
273
|
+
yield response.transport if block_given?
|
|
256
274
|
@transport = parser.parse(response.transport)
|
|
257
|
-
|
|
275
|
+
|
|
258
276
|
unless @transport[:transport_protocol].nil?
|
|
259
277
|
@capturer.transport_protocol = @transport[:transport_protocol]
|
|
260
278
|
end
|
|
@@ -383,9 +401,10 @@ module RTSP
|
|
|
383
401
|
response = send_message message
|
|
384
402
|
#compare_sequence_number response.cseq
|
|
385
403
|
@cseq += 1
|
|
386
|
-
|
|
387
404
|
if response.code.to_s =~ /2../
|
|
388
405
|
yield response if block_given?
|
|
406
|
+
elsif response.code == 401
|
|
407
|
+
send_authorization(message)
|
|
389
408
|
elsif response.code.to_s =~ /(4|5)../
|
|
390
409
|
if (defined? response.connection) && response.connection == 'Close'
|
|
391
410
|
reset_state
|
|
@@ -441,7 +460,19 @@ module RTSP
|
|
|
441
460
|
end
|
|
442
461
|
|
|
443
462
|
private
|
|
444
|
-
|
|
463
|
+
|
|
464
|
+
# Resends a message with an Authorization header when possible
|
|
465
|
+
# @param [RTSP:Message] message The message that must be repeated with Authorization
|
|
466
|
+
def send_authorization(message)
|
|
467
|
+
if @server_uri.user and @server_uri.password
|
|
468
|
+
credentials = Base64.strict_encode64("#{@server_uri.user}:#{@server_uri.password}")
|
|
469
|
+
headers = { :authorization => "Basic #{credentials}" }
|
|
470
|
+
new_message = RTSP::Message.send(message.method_type.to_sym,@server_uri.to_s).with_headers(headers)
|
|
471
|
+
new_message.add_headers message.headers
|
|
472
|
+
request(new_message)
|
|
473
|
+
end
|
|
474
|
+
end
|
|
475
|
+
|
|
445
476
|
# Sets state related variables back to their starting values;
|
|
446
477
|
# +@session_state+ is set to +:init+; +@session+ is set to 0.
|
|
447
478
|
def reset_state
|
data/lib/rtsp/message.rb
CHANGED
|
@@ -83,6 +83,7 @@ module RTSP
|
|
|
83
83
|
@headers = default_headers
|
|
84
84
|
@body = ""
|
|
85
85
|
@version = DEFAULT_VERSION
|
|
86
|
+
|
|
86
87
|
end
|
|
87
88
|
|
|
88
89
|
# Adds the header and its value to the list of headers for the message.
|
|
@@ -172,6 +173,13 @@ module RTSP
|
|
|
172
173
|
def default_headers
|
|
173
174
|
headers = {}
|
|
174
175
|
|
|
176
|
+
if @request_uri.user and @request_uri.password
|
|
177
|
+
credentials = "#{@request_uri.user}:#{@request_uri.password}"
|
|
178
|
+
headers[:authorization] = "Basic #{Base64.strict_encode64(credentials)}"
|
|
179
|
+
@request_uri.user = nil
|
|
180
|
+
@request_uri.password = nil
|
|
181
|
+
end
|
|
182
|
+
|
|
175
183
|
headers[:cseq] ||= RTSP_DEFAULT_SEQUENCE_NUMBER
|
|
176
184
|
headers[:user_agent] ||= USER_AGENT
|
|
177
185
|
|
|
@@ -79,10 +79,33 @@ module RTSP
|
|
|
79
79
|
transport_specifier >>
|
|
80
80
|
(semi_colon >> broadcast_type.as(:broadcast_type)).maybe >>
|
|
81
81
|
(semi_colon >> destination).maybe >>
|
|
82
|
+
# server permutation
|
|
83
|
+
(semi_colon >> server_port.as(:server_port)).maybe >>
|
|
84
|
+
(semi_colon >> client_port.as(:client_port)).maybe >>
|
|
85
|
+
(semi_colon >> source).maybe >>
|
|
86
|
+
|
|
87
|
+
(semi_colon >> server_port.as(:server_port)).maybe >>
|
|
82
88
|
(semi_colon >> source).maybe >>
|
|
83
89
|
(semi_colon >> client_port.as(:client_port)).maybe >>
|
|
90
|
+
# client permutation
|
|
91
|
+
(semi_colon >> client_port.as(:client_port)).maybe >>
|
|
92
|
+
(semi_colon >> server_port.as(:server_port)).maybe >>
|
|
93
|
+
(semi_colon >> source).maybe >>
|
|
94
|
+
|
|
95
|
+
(semi_colon >> client_port.as(:client_port)).maybe >>
|
|
96
|
+
(semi_colon >> source).maybe >>
|
|
97
|
+
(semi_colon >> server_port.as(:server_port)).maybe >>
|
|
98
|
+
|
|
99
|
+
# source permutation
|
|
100
|
+
(semi_colon >> source).maybe >>
|
|
101
|
+
(semi_colon >> client_port.as(:client_port)).maybe >>
|
|
102
|
+
(semi_colon >> server_port.as(:server_port)).maybe >>
|
|
103
|
+
|
|
104
|
+
(semi_colon >> source).maybe >>
|
|
84
105
|
(semi_colon >> server_port.as(:server_port)).maybe >>
|
|
85
|
-
(semi_colon >>
|
|
106
|
+
(semi_colon >> client_port.as(:client_port)).maybe >>
|
|
107
|
+
#end permutations for client_port,server_port, and source
|
|
108
|
+
(semi_colon >> interleaved.as(:interleaved)).maybe >>
|
|
86
109
|
(semi_colon >> ttl).maybe >>
|
|
87
110
|
(semi_colon >> port.as(:port)).maybe >>
|
|
88
111
|
(semi_colon >> ssrc).maybe >>
|
data/lib/rtsp/version.rb
CHANGED
|
@@ -1,4 +1,13 @@
|
|
|
1
1
|
module RTSP
|
|
2
|
-
|
|
3
|
-
|
|
2
|
+
SNAPSHOT = false
|
|
3
|
+
RELEASE = true
|
|
4
|
+
BASE_VERSION = '0.4.4'
|
|
5
|
+
|
|
6
|
+
VERSION = if RELEASE
|
|
7
|
+
BASE_VERSION
|
|
8
|
+
elsif SNAPSHOT
|
|
9
|
+
"#{BASE_VERSION}.SNAPSHOT"
|
|
10
|
+
else
|
|
11
|
+
"#{BASE_VERSION}.#{Time.now.strftime('%Y%m%d.%H%M%S')}"
|
|
12
|
+
end
|
|
4
13
|
end
|
data/rtsp.gemspec
CHANGED
|
@@ -5,11 +5,11 @@ $:.unshift lib unless $:.include?(lib)
|
|
|
5
5
|
require 'rtsp/version'
|
|
6
6
|
|
|
7
7
|
Gem::Specification.new do |s|
|
|
8
|
-
s.name =
|
|
8
|
+
s.name = 'rtsp'
|
|
9
9
|
s.version = RTSP::VERSION
|
|
10
10
|
|
|
11
11
|
s.homepage = %q{https://github.com/turboladen/rtsp}
|
|
12
|
-
s.authors = [
|
|
12
|
+
s.authors = ['Steve Loveless', 'Mike Kirby', 'Sujin Philip']
|
|
13
13
|
s.summary = %q{Library to allow RTSP streaming from RTSP-enabled devices.}
|
|
14
14
|
s.description = %q{This library intends to follow the RTSP RFC document (2326)
|
|
15
15
|
to allow for working with RTSP servers. For more information see:
|
|
@@ -18,21 +18,21 @@ http://www.ietf.org/rfc/rfc2326.txt}
|
|
|
18
18
|
s.licenses = %w{MIT}
|
|
19
19
|
|
|
20
20
|
s.executables = %w{rtsp_client}
|
|
21
|
-
s.files = Dir.glob(
|
|
21
|
+
s.files = Dir.glob('{lib,bin,spec,tasks}/**/*') + Dir.glob('*.rdoc') +
|
|
22
22
|
%w(.gemtest rtsp.gemspec Gemfile Rakefile)
|
|
23
23
|
s.extra_rdoc_files = %w{ChangeLog.rdoc LICENSE.rdoc README.rdoc}
|
|
24
24
|
s.require_paths = %w{lib}
|
|
25
|
-
s.rubygems_version =
|
|
26
|
-
s.test_files = Dir.glob(
|
|
25
|
+
s.rubygems_version = '1.7.2'
|
|
26
|
+
s.test_files = Dir.glob('{spec,features}/**/*')
|
|
27
27
|
|
|
28
|
-
s.add_runtime_dependency
|
|
29
|
-
s.add_runtime_dependency
|
|
30
|
-
s.add_runtime_dependency
|
|
28
|
+
s.add_runtime_dependency 'parslet', '>= 1.1.0'
|
|
29
|
+
s.add_runtime_dependency 'rtp', '>= 0.1.3'
|
|
30
|
+
s.add_runtime_dependency 'sdp', '~> 0.2.6'
|
|
31
31
|
|
|
32
|
-
s.add_development_dependency
|
|
33
|
-
s.add_development_dependency
|
|
34
|
-
s.add_development_dependency
|
|
35
|
-
s.add_development_dependency
|
|
36
|
-
s.add_development_dependency
|
|
37
|
-
s.add_development_dependency
|
|
32
|
+
s.add_development_dependency 'bundler'
|
|
33
|
+
s.add_development_dependency 'cucumber', '>= 1.1.0'
|
|
34
|
+
s.add_development_dependency 'rake', '>= 0.8.7'
|
|
35
|
+
s.add_development_dependency 'rspec', '>= 2.5.0'
|
|
36
|
+
s.add_development_dependency 'simplecov', '>= 0.4.0'
|
|
37
|
+
s.add_development_dependency 'yard', '>= 0.6.0'
|
|
38
38
|
end
|