lib/rtsp/client.rb in rtsp-0.4.1 vs lib/rtsp/client.rb in rtsp-0.4.2
- old
+ new
@@ -77,11 +77,11 @@
# @return [Struct::Connection]
attr_accessor :connection
# Use to get/set an object for capturing received data.
- # @param [RTP::Receiver]
+ #
# @return [RTP::Receiver]
attr_accessor :capturer
# @return [Symbol] See {RFC section A.1.}[http://tools.ietf.org/html/rfc2326#page-76]
attr_reader :session_state
@@ -110,25 +110,20 @@
end
@connection = Struct::Connection.new
@capturer = RTP::Receiver.new
- yield(connection, capturer) if block_given?
+ yield(@connection, @capturer) if block_given?
- @connection.server_url = server_url || @connection.server_url
- @server_uri = build_resource_uri_from(@connection.server_url)
- @connection.timeout ||= 30
- @connection.socket ||= TCPSocket.new(@server_uri.host, @server_uri.port)
- @connection.do_capture ||= true
- @connection.interleave ||= false
- @capturer.rtp_port ||= 9000
- @capturer.transport_protocol ||= :UDP
- @capturer.broadcast_type ||= :unicast
- @capturer.rtp_file ||= Tempfile.new(RTP::Receiver::DEFAULT_CAPFILE_NAME)
+ @connection.server_url = server_url || @connection.server_url
+ @server_uri = build_resource_uri_from(@connection.server_url)
+ @connection.timeout ||= 30
+ @connection.socket ||= TCPSocket.new(@server_uri.host, @server_uri.port)
+ @connection.do_capture ||= true
+ @connection.interleave ||= false
- @play_thread = nil
- @cseq = 1
+ @cseq = 1
reset_state
end
# The URL for the RTSP server to talk to can change if multiple servers are
# involved in delivering content. This method can be used to change the
@@ -151,22 +146,20 @@
begin
response = Timeout::timeout(@connection.timeout) do
@connection.socket.send(message.to_s, 0)
socket_data = @connection.socket.recvfrom MAX_BYTES_TO_RECEIVE
+
+ RTSP::Client.log "Received response:"
+ socket_data.first.each_line { |line| RTSP::Client.log line.strip }
+
RTSP::Response.new socket_data.first
end
rescue Timeout::Error
raise RTSP::Error, "Request took more than #{@connection.timeout} seconds to send."
end
- RTSP::Client.log "Received response:"
-
- if response
- response.to_s.each_line { |line| RTSP::Client.log line.strip }
- end
-
response
end
# Sends an OPTIONS message to the server specified by +@server_uri+. Sets
# +@supported_methods+ based on the list of supported methods returned in
@@ -233,12 +226,12 @@
# the Client instance.
#
# @return [String] The String to use with the Transport header.
# @see http://tools.ietf.org/html/rfc2326#page-58 RFC 2326, Section 12.39.
def request_transport
- value = "RTP/AVP;#{@capturer.broadcast_type};client_port="
- value << "#{@capturer.rtp_port}-#{@capturer.rtp_port + 1}\r\n"
+ value = "RTP/AVP;#{@capturer.ip_addressing_type};client_port="
+ value << "#{@capturer.rtp_port}-#{@capturer.rtcp_port}\r\n"
end
# Sends the SETUP request, then sets +@session+ to the value returned in the
# Session header from the server, then sets the +@session_state+ to +:ready+.
#
@@ -258,18 +251,18 @@
@session_state = :ready
end
@session = response.session
parser = RTSP::TransportParser.new
- @transport = parser.parse response.transport
+ @transport = parser.parse(response.transport)
unless @transport[:transport_protocol].nil?
@capturer.transport_protocol = @transport[:transport_protocol]
end
- @capturer.rtp_port = @transport[:client_port][:rtp].to_i
- @capturer.broadcast_type = @transport[:broadcast_type]
+ @capturer.rtp_port = @transport[:client_port][:rtp].to_i
+ @capturer.ip_address = @transport[:destination].to_s
end
end
# Sends the PLAY request and sets +@session_state+ to +:playing+.
#
@@ -279,30 +272,22 @@
# @todo If playback over UDP doesn't result in any data coming in on the
# socket, re-setup with RTP/AVP/TCP;unicast;interleaved=0-1.
# @raise [RTSP::Error] If +#play+ is called but the session hasn't yet been
# set up via +#setup+.
# @see http://tools.ietf.org/html/rfc2326#page-34 RFC 2326, Section 10.5.
- def play(track, additional_headers={})
+ def play(track, additional_headers={}, &block)
message = RTSP::Message.play(track).with_headers({
cseq: @cseq, session: @session[:session_id] })
message.add_headers additional_headers
request(message) do
unless @session_state == :ready
raise RTSP::Error, "Session not set up yet. Run #setup first."
end
- if @play_thread.nil?
- RTSP::Client.log "Capturing RTP data on port #{@transport[:client_port][:rtp]}"
-
- unless @capturer.running?
- @play_thread = Thread.new do
- @capturer.run
- end
- end
- end
-
+ RTSP::Client.log "Capturing RTP data on port #{@transport[:client_port][:rtp]}"
+ @capturer.start(&block)
@session_state = :playing
end
end
# Sends the PAUSE request and sets +@session_state+ to +:ready+.
@@ -311,11 +296,11 @@
# @param [Hash] additional_headers
# @return [RTSP::Response]
# @see http://tools.ietf.org/html/rfc2326#page-36 RFC 2326, Section 10.6.
def pause(track, additional_headers={})
message = RTSP::Message.pause(track).with_headers({
- cseq: @cseq, session: @session[:session_id] })
+ cseq: @cseq, session: @session[:session_id] })
message.add_headers additional_headers
request(message) do
if [:playing, :recording].include? @session_state
@session_state = :ready
@@ -334,37 +319,24 @@
message = RTSP::Message.teardown(track).with_headers({
cseq: @cseq, session: @session[:session_id] })
message.add_headers additional_headers
request(message) do
+ @capturer.stop
reset_state
-
- if @play_thread
- @capturer.stop
- @capturer.rtp_file.close
- @play_thread.exit
- end
end
end
- # Sets state related variables back to their starting values;
- # +@session_state+ is set to +:init+; +@session+ is set to 0.
- def reset_state
- @session_state = :init
- @session = {}
- end
-
# Sends the GET_PARAMETERS request.
#
# @param [String] track The presentation or media track to ping.
# @param [String] body The string containing the parameters to send.
# @param [Hash] additional_headers
# @return [RTSP::Response]
# @see http://tools.ietf.org/html/rfc2326#page-37 RFC 2326, Section 10.8.
def get_parameter(track, body="", additional_headers={})
- message = RTSP::Message.get_parameter(track).with_headers({
- cseq: @cseq })
+ message = RTSP::Message.get_parameter(track).with_headers({ cseq: @cseq })
message.add_headers additional_headers
message.body = body
request(message)
end
@@ -375,12 +347,11 @@
# @param [String] parameters The string containing the parameters to send.
# @param [Hash] additional_headers
# @return [RTSP::Response]
# @see http://tools.ietf.org/html/rfc2326#page-38 RFC 2326, Section 10.9.
def set_parameter(track, parameters, additional_headers={})
- message = RTSP::Message.set_parameter(track).with_headers({
- cseq: @cseq })
+ message = RTSP::Message.set_parameter(track).with_headers({ cseq: @cseq })
message.add_headers additional_headers
message.body = parameters
request(message)
end
@@ -402,11 +373,11 @@
# Executes the Request with the arguments passed in, yields the response to
# the calling block, checks the CSeq response and the session response,
# then increments +@cseq+ by 1. Handles any exceptions raised during the
# Request.
#
- # @param [Hash] new_args
+ # @param [RTSP::Message] message
# @yield [RTSP::Response]
# @return [RTSP::Response]
# @raise [RTSP::Error] All 4xx & 5xx response codes & their messages.
def request message
response = send_message message
@@ -432,19 +403,10 @@
end
response
end
- # Ensures that +@session+ is set before continuing on.
- #
- # @raise [RTSP::Error] Raises if @session isn't set.
- def ensure_session
- if @session.empty?
- raise RTSP::Error, "Session number not retrieved from server yet. Run SETUP first."
- end
- end
-
# Extracts the URL associated with the "control" attribute from the main
# section of the session description.
#
# @return [String] The URL as a String.
def aggregate_control_track
@@ -476,45 +438,67 @@
end
tracks
end
- # Compares the sequence number passed in to the current client sequence
- # number ( +@cseq+ ) and raises if they're not equal. If that's the case, the
- # server responded to a different request.
+ private
+
+ # Sets state related variables back to their starting values;
+ # +@session_state+ is set to +:init+; +@session+ is set to 0.
+ def reset_state
+ @session_state = :init
+ @session = {}
+ end
+
+ # Takes the methods returned from the Public header from an OPTIONS response
+ # and puts them to an Array.
#
- # @param [Fixnum] server_cseq Sequence number returned by the server.
- # @raise [RTSP::Error] If the server returns a CSeq value that's different
- # from what the client sent.
- def compare_sequence_number server_cseq
- if @cseq != server_cseq
- message = "Sequence number mismatch. Client: #{@cseq}, Server: #{server_cseq}"
- raise RTSP::Error, message
- end
+ # @param [String] method_list The string returned from the server containing
+ # the list of methods it supports.
+ # @return [Array<Symbol>] The list of methods as symbols.
+ # @see #options
+ def extract_supported_methods_from method_list
+ method_list.downcase.split(', ').map { |m| m.to_sym }
end
# Compares the session number passed in to the current client session
# number ( +@session+ ) and raises if they're not equal. If that's the case,
# the server responded to a different request.
#
+ # @todo Remove this--it's not used.
# @param [Fixnum] server_session Session number returned by the server.
# @raise [RTSP::Error] If the server returns a Session value that's different
# from what the client sent.
def compare_session_number server_session
if @session[:session_id] != server_session
message = "Session number mismatch. Client: #{@session[:session_id]}, Server: #{server_session}"
raise RTSP::Error, message
end
end
- # Takes the methods returned from the Public header from an OPTIONS response
- # and puts them to an Array.
+ # Compares the sequence number passed in to the current client sequence
+ # number ( +@cseq+ ) and raises if they're not equal. If that's the case, the
+ # server responded to a different request.
#
- # @param [String] method_list The string returned from the server containing
- # the list of methods it supports.
- # @return [Array<Symbol>] The list of methods as symbols.
- # @see #options
- def extract_supported_methods_from method_list
- method_list.downcase.split(', ').map { |m| m.to_sym }
+ # @param [Fixnum] server_cseq Sequence number returned by the server.
+ # @raise [RTSP::Error] If the server returns a CSeq value that's different
+ # from what the client sent.
+ def compare_sequence_number server_cseq
+ if @cseq != server_cseq
+ message = "Sequence number mismatch. Client: #{@cseq}, Server: #{server_cseq}"
+ raise RTSP::Error, message
+ end
end
+
+ # Ensures that +@session+ is set before continuing on.
+ #
+ # @raise [RTSP::Error] Raises if @session isn't set.
+ def ensure_session
+ if @session.empty?
+ raise RTSP::Error, "Session number not retrieved from server yet. Run SETUP first."
+ end
+ end
+
end
end
+
+RTSP::Client.log = false