Module: RTSP::SocatStreaming
Constant Summary collapse
- RTCP_SOURCE =
["80c80006072dee6ad42c300f76c3b928377e99e5006c461ba92d8a3" + "081ca0006072dee6a010e49583330444e2d41414a4248513600000000"]
- MP4_RTP_MAP =
"96 MP4V-ES/30000"- MP4_FMTP =
"96 profile-level-id=5;config=000001b005000001b50900000100000" + "0012000c888ba9860fa22c087828307"
- H264_RTP_MAP =
"96 H264/90000"- H264_FMTP =
"96 packetization-mode=1;profile-level-id=428032;" + "sprop-parameter-sets=Z0KAMtoAgAMEwAQAAjKAAAr8gYAAAYhMAABMS0IvfjAA" + "ADEJgAAJiWhF78CA,aM48gA=="
- SOCAT_OPTIONS =
"rcvbuf=2500000,sndbuf=2500000,sndtimeo=0.00001,rcvtimeo=0.00001"- BLOCK_SIZE =
2000- BSD_OPTIONS =
"setsockopt-int=0xffff:0x200:0x01"
Constants included from Global
Global::DEFAULT_RTSP_PORT, Global::DEFAULT_VERSION
Instance Attribute Summary collapse
-
#fmtp ⇒ Array<String>
Media format attributes.
-
#interface_ip ⇒ String
IP address of the interface of the RTSP streamer.
-
#pids ⇒ Hash
readonly
Hash of session IDs and pids.
-
#rtcp_source_identifier ⇒ String
RTCP source identifier.
-
#rtcp_threads ⇒ Hash
readonly
Hash of session IDs and RTCP threads.
-
#rtp_map ⇒ Array<String>
Media type attributes.
-
#rtp_sequence ⇒ Fixnum
RTP sequence number of the source stream.
-
#rtp_timestamp ⇒ Fixnum
RTP timestamp of the source stream.
-
#sessions ⇒ Hash
Hash of session IDs and SOCAT commands.
-
#source_ip ⇒ Array<String>
IP address of the source camera.
-
#source_port ⇒ Array<Fixnum>
Port where the source camera is streaming.
Attributes included from Global
#log, #log_level, #logger, #raise_errors
Instance Method Summary collapse
-
#description(multicast = false, stream_index = 1) ⇒ Object
Returns the default stream description.
-
#disconnect(sid) ⇒ Object
Disconnects the stream matching the session ID.
-
#generate_rtcp_source_id(friendly_name) ⇒ String
Generates a RTCP source ID based on the friendly name.
-
#parse_sequence_number(src_ip, src_port) ⇒ Array<Fixnum>
Parses the headers from an RTP stream.
-
#setup_streamer(sid, transport_url, index = 1) ⇒ Fixnum
Creates a RTP streamer using socat.
-
#start_streaming(sid) ⇒ Object
Start streaming for the requested session.
-
#stop_streaming(sid) ⇒ Object
Stop streaming for the requested session.
Methods included from Global
#log?, #raise_errors?, #reset_config!, #rtsp_version
Instance Attribute Details
#fmtp ⇒ Array<String>
Returns Media format attributes.
52 53 54 |
# File 'lib/rtsp/socat_streaming.rb', line 52 def fmtp @fmtp end |
#interface_ip ⇒ String
Returns IP address of the interface of the RTSP streamer.
37 38 39 |
# File 'lib/rtsp/socat_streaming.rb', line 37 def interface_ip @interface_ip end |
#pids ⇒ Hash (readonly)
Returns Hash of session IDs and pids.
25 26 27 |
# File 'lib/rtsp/socat_streaming.rb', line 25 def pids @pids end |
#rtcp_source_identifier ⇒ String
Returns RTCP source identifier.
46 47 48 |
# File 'lib/rtsp/socat_streaming.rb', line 46 def rtcp_source_identifier @rtcp_source_identifier end |
#rtcp_threads ⇒ Hash (readonly)
Returns Hash of session IDs and RTCP threads.
28 29 30 |
# File 'lib/rtsp/socat_streaming.rb', line 28 def rtcp_threads @rtcp_threads end |
#rtp_map ⇒ Array<String>
Returns Media type attributes.
49 50 51 |
# File 'lib/rtsp/socat_streaming.rb', line 49 def rtp_map @rtp_map end |
#rtp_sequence ⇒ Fixnum
Returns RTP sequence number of the source stream.
43 44 45 |
# File 'lib/rtsp/socat_streaming.rb', line 43 def rtp_sequence @rtp_sequence end |
#rtp_timestamp ⇒ Fixnum
Returns RTP timestamp of the source stream.
40 41 42 |
# File 'lib/rtsp/socat_streaming.rb', line 40 def @rtp_timestamp end |
#sessions ⇒ Hash
Returns Hash of session IDs and SOCAT commands.
22 23 24 |
# File 'lib/rtsp/socat_streaming.rb', line 22 def sessions @sessions end |
#source_ip ⇒ Array<String>
Returns IP address of the source camera.
31 32 33 |
# File 'lib/rtsp/socat_streaming.rb', line 31 def source_ip @source_ip end |
#source_port ⇒ Array<Fixnum>
Returns Port where the source camera is streaming.
34 35 36 |
# File 'lib/rtsp/socat_streaming.rb', line 34 def source_port @source_port end |
Instance Method Details
#description(multicast = false, stream_index = 1) ⇒ Object
Returns the default stream description.
@param multicast True if the description is for a multicast stream.
123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 |
# File 'lib/rtsp/socat_streaming.rb', line 123 def description multicast=false, stream_index=1 rtp_map = @rtp_map[stream_index - 1] || H264_RTP_MAP fmtp = @fmtp[stream_index - 1] || H264_FMTP <<EOF v=0\r o=- 1345481255966282 1 IN IP4 #{@interface_ip}\r s=Session streamed by "Streaming Server"\r i=stream1\r t=0 0\r a=tool:LIVE555 Streaming Media v2007.07.09\r a=type:broadcast\r a=control:*\r a=range:npt=0-\r a=x-qt-text-nam:Session streamed by "Streaming Server"\r a=x-qt-text-inf:stream1\r m=video 0 RTP/AVP 96\r c=IN IP4 #{multicast ? "#{multicast_ip(stream_index)}/10" : "0.0.0.0"}\r a=rtpmap:#{rtp_map}\r a=fmtp:#{fmtp}\r a=control:track1\r EOF end |
#disconnect(sid) ⇒ Object
Disconnects the stream matching the session ID.
150 151 152 153 154 155 156 157 |
# File 'lib/rtsp/socat_streaming.rb', line 150 def disconnect sid pid = @pids[sid].to_i @pids.delete(sid) @sessions.delete(sid) Process.kill(9, pid) if pid > 1000 rescue Errno::ESRCH log "Tried to kill dead process: #{pid}" end |
#generate_rtcp_source_id(friendly_name) ⇒ String
Generates a RTCP source ID based on the friendly name. This ID is used in the RTCP communication with the client. The default RTCP_SOURCE will be used if one is not provided.
60 61 62 63 |
# File 'lib/rtsp/socat_streaming.rb', line 60 def generate_rtcp_source_id friendly_name ["80c80006072dee6ad42c300f76c3b928377e99e5006c461ba92d8a3081ca0006072dee6a010e" + friendly_name.unpack("H*").first + "00000000"].pack("H*") end |
#parse_sequence_number(src_ip, src_port) ⇒ Array<Fixnum>
Parses the headers from an RTP stream.
164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 |
# File 'lib/rtsp/socat_streaming.rb', line 164 def parse_sequence_number(src_ip, src_port) sock = UDPSocket.new ip = IPAddr.new(src_ip).hton + IPAddr.new("0.0.0.0").hton sock.setsockopt(Socket::IPPROTO_IP, Socket::IP_ADD_MEMBERSHIP, ip) sock.setsockopt(Socket::SOL_SOCKET, Socket::SO_REUSEADDR, 1) sock.bind(Socket::INADDR_ANY, src_port) begin data = sock.recv_nonblock(1500) rescue Errno::EAGAIN retry end sock.close packet = RTP::Packet.read(data) [packet["sequence_number"], packet["timestamp"]] end |
#setup_streamer(sid, transport_url, index = 1) ⇒ Fixnum
Creates a RTP streamer using socat.
71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 |
# File 'lib/rtsp/socat_streaming.rb', line 71 def setup_streamer(sid, transport_url, index=1) dest_ip, dest_port = transport_url.split ":" @rtcp_source_identifier ||= RTCP_SOURCE.pack("H*") local_port = free_port(true) @rtcp_threads[sid] = Thread.start do s = UDPSocket.new s.bind(@interface_ip, local_port+1) loop do begin _, sender = s.recvfrom(36) s.send(@rtcp_source_identifier, 0, sender[3], sender[1]) end end end @cleaner ||= Thread.start { cleanup_defunct } @processes ||= Sys::ProcTable.ps.map { |p| p.cmdline } @sessions[sid] = build_socat(dest_ip, dest_port, local_port, index) local_port end |
#start_streaming(sid) ⇒ Object
Start streaming for the requested session.
102 103 104 |
# File 'lib/rtsp/socat_streaming.rb', line 102 def start_streaming sid spawn_socat(sid, @sessions[sid]) end |
#stop_streaming(sid) ⇒ Object
Stop streaming for the requested session.
109 110 111 112 113 114 115 116 117 |
# File 'lib/rtsp/socat_streaming.rb', line 109 def stop_streaming sid if sid.nil? disconnect_all_streams else disconnect sid @rtcp_threads[sid].kill unless rtcp_threads[sid].nil? @rtcp_threads.delete sid end end |