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.
298 299 300 301 302 |
# File 'lib/rtsp/server.rb', line 298 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.
274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 |
# File 'lib/rtsp/server.rb', line 274 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.
160 161 162 |
# File 'lib/rtsp/server.rb', line 160 def announce(request) [] end |
#describe(request) ⇒ Array<Array<String>>
Handles the describe request.
149 150 151 152 153 154 |
# File 'lib/rtsp/server.rb', line 149 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.
209 210 211 212 213 214 |
# File 'lib/rtsp/server.rb', line 209 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.
136 137 138 139 140 141 142 143 |
# File 'lib/rtsp/server.rb', line 136 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.
256 257 258 259 260 261 262 263 264 265 |
# File 'lib/rtsp/server.rb', line 256 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.
187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 |
# File 'lib/rtsp/server.rb', line 187 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
122 123 124 125 126 127 128 129 130 |
# File 'lib/rtsp/server.rb', line 122 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.
231 232 233 234 235 236 |
# File 'lib/rtsp/server.rb', line 231 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 112 113 114 115 |
# 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 = [] puts "REQUEST **********************************" p request_str request_str.split("\r\n\r\n").each do |r| responses << process_request(r, io) end puts "RESPONSE **********************************" p responses io.send(responses.join, 0) return(-1) if request_str.include?("TEARDOWN") end |
#set_parameter(request) ⇒ Array<Array<String>>
Handles the set_parameter request.
220 221 222 223 224 225 |
# File 'lib/rtsp/server.rb', line 220 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.
168 169 170 171 172 173 174 175 176 177 178 179 180 181 |
# File 'lib/rtsp/server.rb', line 168 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, 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.
242 243 244 245 246 247 248 249 250 |
# File 'lib/rtsp/server.rb', line 242 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 |