Class: RTSP::Server
Overview
Instantiates an RTSP Server Streaming is performed using socat. All you need is the multicast source RTP host and port.
require ‘rtsp/server’ server = RTSP::Server.new “10.221.222.90”, 8554
This is for the stream at index 1 (rtsp://10.221.222.90:8554/stream1) RTSP::StreamServer.instance.source_ip << “239.221.222.241” RTSP::StreamServer.instance.source_port << 6780 RTSP::StreamServer.instance.fmtp << “96 packetization-mode=1…” RTSP::StreamServer.instance.rtp_map << “96 H264/90000”
This is for the stream at index 2 (rtsp://10.221.222.90:8554/stream2) RTSP::StreamServer.instance.source_ip << “239.221.222.141” RTSP::StreamServer.instance.source_port << 6740 RTSP::StreamServer.instance.fmtp << “96 packetization-mode=1…” RTSP::StreamServer.instance.rtp_map << “96 MP4/90000”
Now start the server server.start
Constant Summary collapse
- OPTIONS_LIST =
%w(OPTIONS DESCRIBE SETUP TEARDOWN PLAY PAUSE GET_PARAMETER SET_PARAMETER)
Constants included from Global
Global::DEFAULT_RTSP_PORT, Global::DEFAULT_VERSION
Instance Attribute Summary collapse
-
#agent ⇒ Object
Returns the value of attribute agent.
-
#options_list ⇒ Object
Returns the value of attribute options_list.
-
#session ⇒ Object
Returns the value of attribute session.
-
#version ⇒ Object
Returns the value of attribute version.
Attributes included from Global
#log, #log_level, #logger, #raise_errors
Instance Method Summary collapse
-
#add_headers(request, response, body, status = "200 OK") ⇒ Array<Array<String>>
Adds the headers to the response.
-
#announce(request) ⇒ Array<Array<String>>
Handles the announce request.
-
#describe(request) ⇒ Array<Array<String>>
Handles the describe request.
-
#get_parameter(request) ⇒ Array<Array<String>>
Handles the get_parameter request.
-
#initialize(host, port = 554) ⇒ Server
constructor
Initializes the the Stream Server.
-
#method_missing(method_name, *args, &block) ⇒ Object
Handles unsupported RTSP requests.
-
#options(request) ⇒ Array<Array<String>>
Handles the options request.
-
#pause(request) ⇒ Array<Array<String>>
Handles a pause request.
-
#play(request) ⇒ Array<Array<String>>
Handles the play request.
-
#process_request(request_str, io) ⇒ String
Process an RTSP request.
-
#redirect(request) ⇒ Array<Array<String>>
Handles the redirect request.
-
#serve(io) ⇒ Object
Serves a client request.
-
#set_parameter(request) ⇒ Array<Array<String>>
Handles the set_parameter request.
-
#setup(request) ⇒ Array<Array<String>>
Handles the setup request.
-
#start ⇒ Object
Starts accepting TCP connections.
-
#teardown(request) ⇒ Array<Array<String>>
Handles the teardown request.
-
#udp_listen ⇒ Object
Listens on the UDP socket for RTSP requests.
Methods included from Global
log?, raise_errors?, reset_config!, rtsp_version
Constructor Details
#initialize(host, port = 554) ⇒ Server
Initializes the the Stream Server.
45 46 47 48 49 50 51 52 53 54 |
# File 'lib/rtsp/server.rb', line 45 def initialize(host, port=554) @session = rand(99999999) @stream_server = RTSP::StreamServer.instance @interface_ip = host @stream_server.interface_ip = host @tcp_server = TCPServer.new(host, port) @udp_server = UDPSocket.new @udp_server.bind(host, port) @agent = {} end |
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(method_name, *args, &block) ⇒ Object
Handles unsupported RTSP requests.
294 295 296 297 298 |
# File 'lib/rtsp/server.rb', line 294 def method_missing(method_name, *args, &block) RTSP::Server.log("Received request for #{method_name} (not implemented)", :warn) [[], "Not Implemented"] end |
Instance Attribute Details
#agent ⇒ Object
Returns the value of attribute agent.
39 40 41 |
# File 'lib/rtsp/server.rb', line 39 def agent @agent end |
#options_list ⇒ Object
Returns the value of attribute options_list.
36 37 38 |
# File 'lib/rtsp/server.rb', line 36 def @options_list end |
#session ⇒ Object
Returns the value of attribute session.
38 39 40 |
# File 'lib/rtsp/server.rb', line 38 def session @session end |
#version ⇒ Object
Returns the value of attribute version.
37 38 39 |
# File 'lib/rtsp/server.rb', line 37 def version @version end |
Instance Method Details
#add_headers(request, response, body, status = "200 OK") ⇒ Array<Array<String>>
Adds the headers to the response.
270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 |
# File 'lib/rtsp/server.rb', line 270 def add_headers(request, response, body, status="200 OK") result = [] version ||= SUPPORTED_VERSION result << "RTSP/#{version} #{status}" result << "CSeq: #{request.cseq}" unless body.nil? result << "Content-Type: #{request.accept}" rescue NoMethodError result << "Content-Base: #{request.url}/" rescue NoMethodError result << "Content-Length: #{body.size}" end result << "Date: #{Time.now.gmtime.strftime('%a, %b %d %Y %H:%M:%S GMT')}" result << response.join("\r\n") unless response.nil? result << body unless body.nil? result.flatten.join "\r\n" end |
#announce(request) ⇒ Array<Array<String>>
Handles the announce request.
156 157 158 |
# File 'lib/rtsp/server.rb', line 156 def announce(request) [] end |
#describe(request) ⇒ Array<Array<String>>
Handles the describe request.
145 146 147 148 149 150 |
# File 'lib/rtsp/server.rb', line 145 def describe(request) RTSP::Server.log "Received DESCRIBE request from #{request.remote_host}" description = @stream_server.description(request.multicast?, request.stream_index) [[], description] end |
#get_parameter(request) ⇒ Array<Array<String>>
Handles the get_parameter request.
205 206 207 208 209 210 |
# File 'lib/rtsp/server.rb', line 205 def get_parameter(request) RTSP::Server.log "Received GET_PARAMETER request from #{request.remote_host}" " Pending Implementation" [[]] end |
#options(request) ⇒ Array<Array<String>>
Handles the options request.
132 133 134 135 136 137 138 139 |
# File 'lib/rtsp/server.rb', line 132 def (request) RTSP::Server.log "Received OPTIONS request from #{request.remote_host}" response = [] response << "Public: #{OPTIONS_LIST.join ','}" response << "\r\n" [response] end |
#pause(request) ⇒ Array<Array<String>>
Handles a pause request.
252 253 254 255 256 257 258 259 260 261 |
# File 'lib/rtsp/server.rb', line 252 def pause(request) RTSP::Server.log "Received PAUSE request from #{request.remote_host}" response = [] sid = request.session[:session_id] rescue NoMethodError response << "Session: #{sid}" response << "\r\n" @stream_server.disconnect sid [response] end |
#play(request) ⇒ Array<Array<String>>
Handles the play request.
183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 |
# File 'lib/rtsp/server.rb', line 183 def play(request) RTSP::Server.log "Received PLAY request from #{request.remote_host}" sid = request.session[:session_id] rescue NoMethodError response = [] response << "Session: #{sid}" response << "Range: #{request.range}" rescue NoMethodError index = request.stream_index - 1 rescue NoMethodError index = 1 unless index.is_a?(Fixnum) rtp_sequence, = @stream_server.parse_sequence_number( @stream_server.source_ip[index], @stream_server.source_port[index]) @stream_server.start_streaming sid response << "RTP-Info: url=#{request.url}/track1;" + "seq=#{rtp_sequence + 6} ;rtptime=#{}" response << "\r\n" [response] end |
#process_request(request_str, io) ⇒ String
Process an RTSP request
118 119 120 121 122 123 124 125 126 |
# File 'lib/rtsp/server.rb', line 118 def process_request(request_str, io) remote_address = io.remote_address.ip_address /(?<action>.*) rtsp:\/\// =~ request_str request = RTSP::Request.new(request_str, remote_address) @agent[io] = request.user_agent rescue NoMethodError response, body = send(action.downcase.to_sym, request) add_headers(request, response, body) end |
#redirect(request) ⇒ Array<Array<String>>
Handles the redirect request.
227 228 229 230 231 232 |
# File 'lib/rtsp/server.rb', line 227 def redirect(request) RTSP::Server.log "Received REDIRECT request from #{request.remote_host}" " Pending Implementation" [[]] end |
#serve(io) ⇒ Object
Serves a client request.
87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 |
# File 'lib/rtsp/server.rb', line 87 def serve io request_str = "" count = 0 begin request_str << io.read_nonblock(500) rescue IO::WaitReadable, EOFError => ex return(-1) if ex.is_a?(EOFError) count += 1 sleep 0.001 sleep 1 if count > 10 count = 0 unless request_str == "" retry if count < 70 return -1 if request_str == "" end responses = [] request_str.split("\r\n\r\n").each do |r| responses << process_request(r, io) end io.send(responses.join, 0) return(-1) if request_str.include?("TEARDOWN") end |
#set_parameter(request) ⇒ Array<Array<String>>
Handles the set_parameter request.
216 217 218 219 220 221 |
# File 'lib/rtsp/server.rb', line 216 def set_parameter(request) RTSP::Server.log "Received SET_PARAMETER request from #{request.remote_host}" " Pending Implementation" [[]] end |
#setup(request) ⇒ Array<Array<String>>
Handles the setup request.
164 165 166 167 168 169 170 171 172 173 174 175 176 177 |
# File 'lib/rtsp/server.rb', line 164 def setup(request) RTSP::Server.log "Received SETUP request from #{request.remote_host}" @session = @session.next multicast_check = request.transport.include?('multicast') server_port = @stream_server.setup_streamer(@session, request.transport_url, request.stream_index, multicast_check) response = [] transport = generate_transport(request, server_port, request.stream_index) response << "Transport: #{transport.join}" response << "Session: #{@session}; timeout=60" response << "\r\n" [response] end |
#start ⇒ Object
Starts accepting TCP connections
57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 |
# File 'lib/rtsp/server.rb', line 57 def start Thread.start { udp_listen } loop do client = @tcp_server.accept Thread.start do begin loop { break if serve(client) == -1 } rescue EOFError # do nothing ensure client.close unless @agent[client].include? "QuickTime" end end end end |
#teardown(request) ⇒ Array<Array<String>>
Handles the teardown request.
238 239 240 241 242 243 244 245 246 |
# File 'lib/rtsp/server.rb', line 238 def teardown(request) RTSP::Server.log "Received TEARDOWN request from #{request.remote_host}" sid = request.session[:session_id] rescue NoMethodError @stream_server.stop_streaming sid response = [] response << "\r\n" [response] end |
#udp_listen ⇒ Object
Listens on the UDP socket for RTSP requests.
76 77 78 79 80 81 82 |
# File 'lib/rtsp/server.rb', line 76 def udp_listen loop do data, sender = @udp_server.recvfrom(500) response = process_request(data, sender[3]) @udp_server.send(response, 0, sender[3], sender[1]) end end |