File Coverage

blib/lib/RTSP/Server.pm
Criterion Covered Total %
statement 1 3 33.3
branch n/a
condition n/a
subroutine 1 1 100.0
pod n/a
total 2 4 50.0


line stmt bran cond sub pod time code
1             package RTSP::Server;
2              
3 1     1   20938 use Moose;
  0            
  0            
4             with 'MooseX::Getopt';
5              
6             use namespace::autoclean;
7              
8             use RTSP::Server::Logger;
9             use RTSP::Server::Source;
10             use RTSP::Server::Client;
11              
12             our $VERSION = '0.06';
13             our $RTP_START_PORT = 20_000;
14              
15             ## configuration attributes
16              
17             has 'client_listen_port' => (
18             is => 'rw',
19             isa => 'Int',
20             default => '554',
21             cmd_flag => 'clientport',
22             cmd_aliases => 'c',
23             metaclass => 'MooseX::Getopt::Meta::Attribute',
24             );
25              
26             has 'source_listen_port' => (
27             is => 'rw',
28             isa => 'Int',
29             default => '5545',
30             cmd_flag => 'serverport',
31             cmd_aliases => 's',
32             metaclass => 'MooseX::Getopt::Meta::Attribute',
33             );
34              
35             has 'client_listen_address' => (
36             is => 'rw',
37             isa => 'Str',
38             default => '0.0.0.0',
39             );
40              
41             has 'source_listen_address' => (
42             is => 'rw',
43             isa => 'Str',
44             default => '0.0.0.0',
45             );
46              
47             has 'log_level' => (
48             is => 'rw',
49             isa => 'Int',
50             default => 2,
51             cmd_flag => 'loglevel',
52             cmd_aliases => 'l',
53             metaclass => 'MooseX::Getopt::Meta::Attribute',
54             );
55              
56             has 'max_clients' => (
57             is => 'rw',
58             isa => 'Int',
59             default => 100,
60             );
61              
62             ## internal attributes
63              
64             has 'rtp_start_port' => (
65             is => 'rw',
66             isa => 'Int',
67             default => $RTP_START_PORT,
68             );
69              
70             has 'source_server' => (
71             is => 'rw',
72             clearer => 'close_source_server',
73             traits => [ 'NoGetopt' ],
74             );
75              
76             has 'client_server' => (
77             is => 'rw',
78             clearer => 'close_client_server',
79             traits => [ 'NoGetopt' ],
80             );
81              
82             has 'logger' => (
83             is => 'rw',
84             isa => 'RTSP::Server::Logger',
85             handles => [qw/ trace debug info warn error /],
86             lazy => 1,
87             builder => 'build_logger',
88             traits => [ 'NoGetopt' ],
89             );
90              
91             # map of uri => Mount
92             has 'mounts' => (
93             is => 'rw',
94             isa => 'HashRef',
95             default => sub { {} },
96             lazy => 1,
97             traits => [ 'NoGetopt' ],
98             );
99              
100             sub client_count {
101             my ($self) = @_;
102              
103             return $self->client_server->connection_count;
104             }
105              
106             sub client_stopped {
107             my ($self, $client) = @_;
108             $self->client_count($self->client_count + 1);
109             }
110              
111             sub next_rtp_start_port {
112             my ($self) = @_;
113              
114             my $port = $self->rtp_start_port;
115             $self->rtp_start_port($port + 2);
116              
117             return $port;
118             }
119              
120             # call from time to time to keep things tidy
121             sub housekeeping {
122             my ($self) = @_;
123              
124             # if we have no more mount points, it's safe to reset the rtp
125             # start ports
126             unless (keys %{ $self->mounts }) {
127             $self->rtp_start_port($RTP_START_PORT);
128             }
129             }
130              
131             # call this to start the server
132             sub listen {
133             my ($self) = @_;
134              
135             print "Starting RTSP server, log level = " . $self->log_level . "\n";
136              
137             my $source_server = $self->start_source_server;
138             my $client_server = $self->start_client_server;
139             }
140              
141             sub start_client_server {
142             my ($self) = @_;
143              
144             $self->close_client_server;
145              
146             my $bind_ip = $self->client_listen_address;
147             my $bind_port = $self->client_listen_port;
148              
149             my $server = RTSP::Server::Client->new(
150             listen_address => $bind_ip,
151             listen_port => $bind_port,
152             server => $self,
153             );
154              
155             $server->listen;
156              
157             $self->client_server($server);
158             $self->info("Client server started");
159            
160             return $server;
161             }
162              
163             sub start_source_server {
164             my ($self) = @_;
165              
166             $self->close_source_server;
167              
168             my $bind_ip = $self->source_listen_address;
169             my $bind_port = $self->source_listen_port;
170              
171             my $server = RTSP::Server::Source->new(
172             listen_address => $bind_ip,
173             listen_port => $bind_port,
174             server => $self,
175             );
176              
177             $server->listen;
178              
179             $self->source_server($server);
180             $self->info("Source server started");
181            
182             return $server;
183             }
184              
185             sub build_logger {
186             my ($self) = @_;
187              
188             return RTSP::Server::Logger->new(
189             log_level => $self->log_level
190             );
191             }
192              
193             __PACKAGE__->meta->make_immutable;
194              
195             __END__
196              
197             =head1 NAME
198              
199             RTSP::Server - Lightweight RTSP/RTP server. Like icecast, for
200             audio/video streams.
201              
202             =head1 SYNOPSIS
203              
204             use AnyEvent;
205             use RTSP::Server;
206              
207             # defaults:
208             my $srv = new RTSP::Server(
209             log_level => 2, # 0 = no output, 5 = most verbose
210             max_clients => 100,
211             client_listen_port => 554,
212             source_listen_port => 5545,
213             rtp_start_port => 20000,
214             client_listen_address => '0.0.0.0',
215             source_listen_address => '0.0.0.0',
216             );
217              
218             # listen and accept incoming connections asynchronously
219             # (returns immediately)
220             $srv->listen;
221              
222             # main loop
223             my $cv = AnyEvent->condvar;
224             # ...
225             $cv->recv;
226              
227             undef $srv; # when the server goes out of scope, all sockets will
228             # be cleaned up
229              
230             =head1 DESCRIPTION
231              
232             This server is designed to enable to rebroadcasting of RTP media
233             streams to clients, controlled by RTSP. Please see README for more
234             information.
235              
236             =head1 USAGE
237              
238             After starting the server, stream sources may send an ANNOUNCE for a
239             desired mountpoint, followed by a RECORD request to begin streaming.
240             Clients can then connect on the client port at the same mountpoint and
241             send a PLAY request to receive the RTP data streamed from the source.
242              
243             =head1 BUNDLED APPLICATIONS
244              
245             Includes rtsp-server.pl, which basically contains the synopsis.
246              
247             =head2 COMING SOON
248              
249             Priv dropping, authentication, client encoder, stats, tests
250              
251             =head1 SEE ALSO
252              
253             L<RTSP::Proxy>, L<RTSP::Client>, L<AnyEvent::Socket>
254              
255             =head1 AUTHOR
256              
257             Mischa Spiegelmock, E<lt>revmischa@cpan.orgE<gt>
258              
259             =head1 COPYRIGHT AND LICENSE
260              
261             Copyright (C) 2010 by Mischa Spiegelmock
262              
263             This library is free software; you can redistribute it and/or modify
264             it under the same terms as Perl itself, either Perl version 5.10.0 or,
265             at your option, any later version of Perl 5 you may have available.
266              
267              
268             =cut