Giter Club home page Giter Club logo

rtsp's Introduction

rtsp

<img src=“https://secure.travis-ci.org/turboladen/rtsp.png” alt=“Build Status” />

DESCRIPTION:

This library intends to follow the RTSP RFC document (2326) to allow for working with RTSP servers. By way of rtp, you can either inspect the RTP packets as they come across the wire or use the file that the data got saved to.

For more information:

FEATURES/PROBLEMS:

  • All standard RTSP methods supported except REDIRECT.

  • Captures RTP data to a file, or yields if a block is passed to #play.

  • One client object can only handle 1 stream; use a client per stream until this functionality gets implemented.

  • Only handles unicast, TCP RTSP communication.

  • RTSP exceptions are all {RTSP::Error}s.

SYNOPSIS:

Basic Usage

RTSP::Client.log?                # => false
RTSP::Client.log = true
client = RTSP::Client.new "rtsp://64.202.98.91/sa.sdp"

client.server_uri                   # => #<URI::Generic:0x00000100ba4db0 URL:rtsp://64.202.98.91:554/sa.sdp>
client.session_state                # => :init
client.cseq                         # => 1
client.connection.do_capture        # => true
client.connection.interleave        # => false
client.connection.timeout           # => 30
client.capturer.ip_addressing_type  # => :unicast
client.capturer.rtp_port            # => 6970
client.capturer.capture_file        # => #<File:/var/folders/tg/j9jxvvfs4qn9cg4vztzyy2gc0000gp/T/rtp_capture.raw-59901-1l8dgv2>
client.capturer.transport_protocol  # => :UDP

response = client.options
response.class             # => RTSP::Response
response.code              # => 200
response.message           # => "OK"
client.cseq                # => 2

response = client.describe
response.body.class             # => SDP::Description
response.content_type           # => "application/sdp"
response.server                 # => "DSS/5.5 (Build/489.7; Platform/Linux; Release/Darwin; )"
client.aggregate_control_track  # => "rtsp://64.202.98.91:554/sa.sdp/"
client.media_control_tracks     # => ["rtsp://64.202.98.91:554/sa.sdp/trackID=1"]
client.cseq                     # => 3

response = client.setup(client.media_control_tracks.first)
response.session[:session_id]   # => 7098486223178290313
client.session[:session_id]     # => 7098486223178290313
client.cseq                     # => 4
client.session_state            # => :ready

response = client.play(client.aggregate_control_track)
response.range            # => "npt=now="
resposne.rtp_info         # => "url=rtsp://64.202.98.91:554/sa.sdp/trackID=1"
client.session_state      # => :playing

# Wait while the video streams
sleep 5

client.pause(client.aggregate_control_track)
client.session_state    # => :ready

# Wait while the video is paused
sleep 2

client.teardown(client.aggregate_control_track)
client.session[:session_id]   # => 0
client.session_state          # => :init

# Check the streamed file's contents
puts client.capturer.capture_file     # => (Lots of data)

RTP packet inspection

As of RTP 0.1.0, you can now inspect and use packets as they come across the wire:

client = RTSP::Client.new "rtsp://64.202.98.91/sa.sdp"
client.describe
client.setup(client.media_control_tracks.first)
payload_file = File.new('rtp.data', 'wb')

client.play(client.aggregate_control_track) do |packet|
  puts "packet is a #{packet.class}"
  puts "RTP seqence: #{packet.sequence_number}"
  puts "RTP payload type: #{packet.payload_type}"

  # Let's save the payload data while we're at it...
  payload_file.write(packet.rtp_payload)
end

payload_file.close

Take a look at the RTP::Packet docs for more information.

CLI App

RTSP also provides a rtsp_client executable that allows a little talking to an RTSP server.

Knowing which tracks are available on the server can help you determine which tracks to use in your programmatic use of an RTSP::Client object to try to play. Show the available aggregate control track and media control tracks:

$ rtsp_client --show-tracks rtsp://64.202.98.91/sa.sdp

Or if you want the entire SDP description from the server:

$ rtsp_client --describe rtsp://64.202.98.91/sa.sdp

And then, of course, pull a stream (this assumes you SETUP the first media track and call play on the aggregate track):

$ rtsp_client --stream rtsp://64.202.98.91/sa.sdp

As usual, get help by:

$ rtsp_client --help

REQUIREMENTS:

  • (Tested) Rubies

    • 1.9.2

    • 1.9.3

  • RubyGems

    • sdp

    • rtp

    • parslet

INSTALL:

  • (sudo) gem install rtsp

DEVELOPERS:

After checking out the source, run:

$ bundle install

This task will install any missing dependencies.

LICENSE:

(The MIT License)

Copyright © 2011 Steve Loveless, Mike Kirby

See LICENSE.rdoc for details.

rtsp's People

Contributors

datacompboy avatar dblommesteijn avatar greywolf-colorado avatar mikekirby avatar nmccready avatar nolanbrown avatar tindron avatar turboladen avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

rtsp's Issues

Client should handle > 1 stream

A single client should be able to pull multiple streams from multiple servers (i.e. it should be able to pull a video stream from one server, while pulling an audio stream from another). Also, don't forget that each stream can have their own state.

Make it so!

Response should parse HTTP response

In 0.4.0, it fails to parse:

/Users/Steveloveless/.rvm/gems/ruby-1.9.3-p286/gems/rtsp-0.4.0/lib/rtsp/response.rb:77:in `extract_status_line': Status line corrupted: HTTP/1.0 501 Not Implemented (RTSP::Error)

Socket::SO_REUSEPORT isn't available in some kernels

Using on Ubuntu 11.04 (2.6.38-7-generic #39-Ubuntu SMP Fri Mar 25 19:38:02 UTC 2011 i686 i686 i386 GNU/Linux) with ruby 1.9.2p180 I got:
uninitialized constant Socket::SO_REUSEPORT (NameError)

After doing more investigating, it seems that this socket flag isn't necessarily always available. If it's available use it; if not, don't.

Does not parse SETUP response: transport correct

From RFC:
Transport = "Transport" ":"
1#transport-spec
transport-spec = transport-protocol/profile[/lower-transport]
_parameter
transport-protocol = "RTP"
profile = "AVP"
lower-transport = "TCP" | "UDP"
parameter = ( "unicast" | "multicast" )
| ";" "destination" [ "=" address ]
| ";" "interleaved" "=" channel [ "-" channel ]
| ";" "append"
| ";" "ttl" "=" ttl
| ";" "layers" "=" 1_DIGIT
| ";" "port" "=" port [ "-" port ]
| ";" "client_port" "=" port [ "-" port ]
| ";" "server_port" "=" port [ "-" port ]
| ";" "ssrc" "=" ssrc
| ";" "mode" = <"> 1#mode <">
ttl = 1_3(DIGIT)
port = 1_5(DIGIT)
ssrc = 8_8(HEX)
channel = 1_3(DIGIT)
address = host
mode = <"> *Method <"> | Method

gem does not parse ssrc and mode

The great god, river's lake emergency, RTSP concurrency issues, pressure test has been to find the solution, to solve.Description please see inside.

Hi, simulate multi-user access RTSP server MP4 files, hope that through the TCP client visit, at present has been prompt "block in the setup", please help see what reason, have set up several parameter values, don't know if it caused by your behavior.

RTP packets inside, set the parameters of the main is to put the client_port changed to 554
Set transport_protocol into TCP

RTSP not closing files

When I do:

rtsp = RTSP::Client.new('rtsp://192.168.88.13/media/video2')
rtsp = nil

When I look at open files, the file is never closed. This causes the system to show too many open files error after a while when reading from many sources:

$ lsof -n | grep -i rtp
ruby      99606 Hackeron   18u     REG                1,2          0 47716079 /private/var/folders/jz/tbfhr91s2p53sx93zbbxb9jw0000gn/T/rtp_capture.raw20160408-99606-1c2kusy

Any ideas how to make sure the file is closed?

NameError: uninitialized constant RTSP::Client

Hi there, I ran gem install rtsp followed by this:

[1] pry(main)> require 'rtsp'
=> true
[5] pry(main)> ls RTSP
constants: BASE_VERSION  RELEASE  SNAPSHOT  VERSION
RTSP.methods: release_version?  snapshot_version?
[7] pry(main)> cd RTSP
[8] pry(RTSP):1> VERSION
=> "0.4.5"
[9] pry(RTSP):1> RTSP::Client.new
NameError: uninitialized constant RTSP::Client
from (pry):6:in `__binding__'

Any ideas?

`find_all' for nil:NilClass in /lib/rtsp/client.rb:451:in `aggregate_control_track'

When I try to run the describe method, I see the following:

[5] pry(main)> rtsp = RTSP::Client.new('rtsp://192.168.88.11/')
=> #<RTSP::Client:0x000000028d0070
 @capturer=
  #<RTP::Receiver:0x000000028d7fa0
   @broadcast_type=:unicast,
   @listener=nil,
   @packet_timestamps=[],
   @payload_data=[],
   @rtp_file=#<File:/tmp/rtp_capture.raw20150627-26597-1g0flgj>,
   @rtp_port=9000,
   @sequence_list=[],
   @strip_headers=false,
   @transport_protocol=:UDP>,
 @connection=#<struct Struct::Connection server_url="rtsp://192.168.88.11/", timeout=30, socket=#<TCPSocket:fd 11>, do_capture=true, interleave=false>,
 @cseq=1,
 @play_thread=nil,
 @server_uri=#<URI::Generic:0x000000028d7618 URL:rtsp://192.168.88.11:554/>,
 @session={},
 @session_state=:init>
[6] pry(main)> rtsp.desbribe
NoMethodError: undefined method `desbribe' for #<RTSP::Client:0x000000028d0070>
from (pry):5:in `__pry__'
[7] pry(main)> rtsp.describe
[2015-06-27 17:35:04 +0100] Sending DESCRIBE to rtsp://192.168.88.11:554/
[2015-06-27 17:35:04 +0100] DESCRIBE rtsp://192.168.88.11:554/ RTSP/1.0
[2015-06-27 17:35:04 +0100] CSeq: 1
[2015-06-27 17:35:04 +0100] User-Agent: RubyRTSP/0.4.1 (Ruby 2.0.0-p645)
[2015-06-27 17:35:04 +0100] Accept: application/sdp
[2015-06-27 17:35:04 +0100] 
[2015-06-27 17:35:04 +0100] Received response:
[2015-06-27 17:35:04 +0100] RTSP/1.0 200 OK
[2015-06-27 17:35:04 +0100] CSeq: 1
[2015-06-27 17:35:04 +0100] Server: HuangHe/1.0.0
[2015-06-27 17:35:04 +0100] Date: Sat, 27 Jun 2015 17:47:50 GMT
[2015-06-27 17:35:04 +0100] Content-Type: application/sdp
[2015-06-27 17:35:04 +0100] Content-Base: rtsp://192.168.88.11/
[2015-06-27 17:35:04 +0100] Content-Length: 285
[2015-06-27 17:35:04 +0100] 
[2015-06-27 17:35:04 +0100] v=0
[2015-06-27 17:35:04 +0100] o=StreamingServer 3433055887 1435427270319700 IN IP4 192.168.88.11
[2015-06-27 17:35:04 +0100] s=
[2015-06-27 17:35:04 +0100] e=NONE
[2015-06-27 17:35:04 +0100] c=IN IP4 0.0.0.0
[2015-06-27 17:35:04 +0100] t=0 0
[2015-06-27 17:35:04 +0100] m=video 0 RTP/AVP 96
[2015-06-27 17:35:04 +0100] b=AS:70
[2015-06-27 17:35:04 +0100] a=control:trackID=1
[2015-06-27 17:35:04 +0100] a=rtpmap:96 H264/90000
[2015-06-27 17:35:04 +0100] a=fmtp:96 profile-level-id=42e02a;packetization-mode=1;sprop-parameter-sets=Z0LgKtoBkAlx,aM4wpIA=
NoMethodError: undefined method `find_all' for nil:NilClass
from /var/lib/gems/2.0.0/gems/rtsp-0.4.1/lib/rtsp/client.rb:451:in `aggregate_control_track'

Raise 4xx and 5xx errors instead of RTSP::Error

All RTSP errors currently result in a RTSP::Error. Look to some other common Ruby libraries (net-http, savon, rest-client, rack, etc) for how they handle this case, pick one, and follow suit.

Also, be sure to let clients turn off these raises--perhaps they won't want to end execution of their app on an error.

undefined method `log_class_name=' for RTP::Logger:Class

Ever since I version bumped to the latest version of rtp and rtsp, I'm getting:

undefined method `log_class_name=' for RTP::Logger:Class
/home/deployer/asd/shared/bundle/ruby/2.1.0/gems/rtp-0.1.5/lib/rtp/receiver.rb:5:in `require_relative'
/home/deployer/asd/shared/bundle/ruby/2.1.0/gems/rtp-0.1.5/lib/rtp/receiver.rb:5:in `<top (required)>'
/home/deployer/asd/shared/bundle/ruby/2.1.0/gems/rtsp-0.4.5/lib/rtsp/client.rb:4:in `require'
/home/deployer/asd/shared/bundle/ruby/2.1.0/gems/rtsp-0.4.5/lib/rtsp/client.rb:4:in `<top (required)>'

All I have to do to trigger this error is:

require 'rtsp/client'

Any ideas?

Does not parse SETUP response: session

Session is not parsed.

From RFC:
Session = "Session" ":" session-id [ ";" "timeout" "=" delta-seconds ]
but only Session = "Session" ":" session-id is expected

Session should be parsed. Now it uses it without parsing it, which causes exceptions.

Custom client can't receive anything after the first reply

Hi,
I know this is nearly a dead library, but it allow me to code a quick and dirty test client.

And I seems to have a strange problem : after having recieived and processed a reply to the first options method, the socket recvfrom will receive nothing and will fire a timeout error.

Could you help me to solve this problem ?

Passing in stream file results in Bad file descriptor

I have a cuke test that, when extracting from steps, looks something like:

def save_streamed_file(file_to_save, save_to_directory)
  capture_dir = File.expand_path(save_to_directory)

  unless File.directory? capture_dir
    FileUtils.mkdir capture_dir
  end

  FileUtils.cp(file_to_save, capture_dir)
end

@streamed_file = Tempfile.new("sarix_streamed_file")
rtsp_url = "#{@sarix.ip_address}#{@sarix.rtsp_stream_path}"

@rtsp_client = RTSP::Client.new(rtsp_url) do |connection, capturer|
  capturer.rtp_file = @streamed_file
end

@rtsp_client.describe
@rtsp_client.setup(@rtsp_client.media_control_tracks.first)

begin
  @rtsp_client.play(@rtsp_client.aggregate_control_track)
  @logger.debug "Starting stream capturing for #{duration} second(s)..."
  sleep duration.to_i
ensure
  @logger.debug "Tearing down RTSP stream..."
  @rtsp_client.teardown(@rtsp_client.aggregate_control_track)
end

if @config[:save_capture_to_file]
  save_streamed_file(@streamed_file, @config[:capture_directory])
end

Running this returns:

[Sep 19 13:14:06]:ERROR:       Bad file descriptor (Errno::EBADF)
[Sep 19 13:14:06]:ERROR:       /Users/sloveless/.rvm/gems/ruby-1.9.2-p290/gems/rtsp-0.1.2/lib/rtsp/capturer.rb:77:in `recvfrom'
[Sep 19 13:14:06]:ERROR:       /Users/sloveless/.rvm/gems/ruby-1.9.2-p290/gems/rtsp-0.1.2/lib/rtsp/capturer.rb:77:in `run'
[Sep 19 13:14:06]:ERROR:       /Users/sloveless/.rvm/gems/ruby-1.9.2-p290/gems/rtsp-0.1.2/lib/rtsp/client.rb:297:in `block (2 levels) in play'

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.