Capturing RTSP streams to file


RTSP is Real Time Streaming Protocol that is documented in RFC 2326. Some reasonably good background information is available on the webpage of Henning Schulzrinne. Multicast people also created a specification for a really simple RTSP client with a reasonably good description of a client/server interaction.

My /etc/services lists the following ports as registered with IANA:

stany@gilva:~[01:18 AM]$ grep rtsp /etc/services 
rtsps           322/udp     # RTSPS
rtsps           322/tcp     # RTSPS
rtsp            554/udp     # Real Time Stream Control Protocol
rtsp            554/tcp     # Real Time Stream Control Protocol
rtsp-alt        8554/udp     # RTSP Alternate (see port 554)
rtsp-alt        8554/tcp     # RTSP Alternate (see port 554)
stany@gilva:~[01:18 AM]$ 

RTSP is used by a number of applications, on mbone (where one can watch all sorts of streams, including NASA TV), and on normal IPv4 networks. Vast majority of mbone streams I saw myself encapslate MPEG1 or MP3 data, however MPEG2 support is showing up more and more commonly. People who are not connected to mbone see rtsp URLs as parts of RealAudio/RealVideo streams (Provided, for example, by BBC), and QuickTime streams.

Why would one want to “record” these streams?

There are many cases when this might be desirable – for example one might not have speedy connection to internet, yet want to watch media content provided in high resolution. Occasional high speed connectivity to the internet is a possibility too – for example I can stop by a coffee shop that has wi fi, and have full high speed internet connectivity. So a question arises, how does one capture a stream contents to a file, to watch offline? Sadly, clients that are provided to view/listen to the RTSP streams don’t support capture of data at all (Real Player) or saving of the stream to file requires a “Pro” version of the software and can be disabled by the server (QuickTime Player).

RealMedia Streams

One of the options might be rtspget which is an add-on to xine. I’ve compiled xine under 10.4.1, with just ./configure –prefix=/opt/gnu –with-included-gettext –with-x, however if this is the first time you are building xine, you might need to actually “make install” contrary to instructions on the Ian Collier’s page. In order to buiild, rtspget would want a whole bunch of xine includes that are spread all over, yet get dropped into {PREFIX}/include/xine/ by the install script (In other words you can’t just give -I{path} option to gcc, as the location of includes is different in the tree then in the installed location rtspget expects. And yes, you can edit the source, if you want to). Any way, assumption here is that you know what you are doing, and given some time, and maybe a choice word or three it xine-lib would eventually build, and rtspget would eventually compile.

In my tests, rtspget would be able to negotiate the connection with BBC’s streaming servers, that are Real Media based, and download the streams. Resulting downloads were identified by the file(1) command to indeed be Real media files. No go with the QuickTime streams at all, and the downloaded files were not showing anything in the Real Player 10. On this page (And don’t ask me why engineering at Purdue University insists on HTTPS protocol, as I don’t know either) I saw reference to this, that seemed to indicate the file still plays normaly in xine. So maybe there is something wonky somewhere, and warrants further testing.

Besides this “small” problem with rtspget, a couple of others are present. It sends fixed User-Agent, GUID and StartTime to the servers, and that might cause problems in the future, as servers might be modified to recognize that signature, and deny rtspget access to the media:

stany@gilva:~/src/rtsp[01:59 AM]$ strings rtspget
rtsp: bad mrl: %s
User-Agent: RealMedia Player Version (linux-2.0-libc6-i386-gcc2.95)
rtsp: failed to connect to '%s'
CSeq: 1
ClientChallenge: 9e26d33f2984236010ef6253fb1887f7
PlayerStarttime: [28/03/2003:22:50:23 00:00]
CompanyID: KnKV4M4I/B2FjJ1TToLycw==
GUID: 00000000-0000-0000-0000-000000000000
RegionData: 0
ClientID: Linux_2.4_6.0.9.1235_play32_RN01_EN_586
stany@gilva:~/src/rtsp[02:00 AM]$

Something to keep in mind. This user agent string is not in the actual rtspget source code but in librtsp in xine source code (from ./xine-lib-1.0.1/src/input/librtsp/rtsp.c):

  if (user_agent)
    s->user_agent=strdup("User-Agent: RealMedia Player Version (linux-2.0-libc6-i386-gcc2.95)");

  /* now lets send an options request. */
  rtsp_schedule_field(s, "CSeq: 1");
  rtsp_schedule_field(s, s->user_agent);
  rtsp_schedule_field(s, "ClientChallenge: 9e26d33f2984236010ef6253fb1887f7");
  rtsp_schedule_field(s, "PlayerStarttime: [28/03/2003:22:50:23 00:00]");
  rtsp_schedule_field(s, "CompanyID: KnKV4M4I/B2FjJ1TToLycw==");
  rtsp_schedule_field(s, "GUID: 00000000-0000-0000-0000-000000000000");
  rtsp_schedule_field(s, "RegionData: 0");
  rtsp_schedule_field(s, "ClientID: Linux_2.4_6.0.9.1235_play32_RN01_EN_586");
  /*rtsp_schedule_field(s, "Pragma: initiate-session");*/
  rtsp_request_options(s, NULL);

  return s;

This leads me to believe that anything linked against xine’s librtsp would have that user agent, etc combination (That someone just captured on the wire while investigating the way RealPlayer establishes a session). Note to myself: Investigate #define RTSP_RECORDING 16 and the rest of server capabilities in xine-lib-1.0.1/src/input/librtsp/rtsp.c)

QuickTime Streams

Another option seems to be vlc. You would want the latest version of it (vlc-0.8.2test2 at the writing time), and you’d want to keep in mind that vlc doesn’t at this time deal with H.264 files properly yet.

Here are the instructions:

  • Locate the stream you want to download. You can generally start watching in QuickTime player, get info, make sure that the stream you are getting is not H.264, but MPEG4, etc, and, if you have a license key for QuickTime Pro version, save the file to disk. If you are lucky, and the content owner didn’t restrict saving, QuickTime Pro would do just that. However, if content owner restricted the saving feature, QT would offer to save the file for you any way. This would be a bit of a misnomer, as that action will generated a small file with an embedded rtsp URL, not actually save the actual file, and you would need internet connection in order watch it again.

    At this point you can use strings on the file to extract the rtsp string. If you don’t have pro license, getting info on the file you are streaming would give you rtsp path as well, however occasionally it seems like it is a path to a container file that contains the actual path, not to the media itself. Warrants further investigation.

  • open VLC
  • File -> Open Network.
  • Set URL to the rtsp URL you obtained already in the first step
  • Check Advanced output
  • Click Settings
  • Click Browse, choose a name to save the file as
  • Set Encapsulation method to QuickTime. Encapsulation method seems to make a minor difference – when set to quicktime as opposed to the default mpeg_ts, it seemingly started to pixellate less. I don’t know if anything changes in the output of the file.
  • Cleck Play locally if you want to watch while it downloads. Note that MPEG4 files as played in VLC would appear with “blocky” pixellisation. If you manage to save the file, open it in QuickTime, and all that blockiness would go away, as QT does a better job rendering MPEG4
  • Click OK
  • Click OK
  • Wait 🙂

As a test I’ve used a link to Shakira’s full video from Sony’s web site (As Joshie used to say, “Boobies!”).

End result:

stany@gilva:~/tmp[02:19 AM]$ file vlc-output.ts
vlc-output.ts: Apple QuickTime movie file (moov)

Renamed the above file to .mov, opened and played it in QT 7 with no problems, and QT reported the file as mpeg4 video, AAC audio.

Windows Media Files

Lastly, for the sake of completeness, Windows Media files. They don’t use RTSP:// protocol, but something called MMS.
SDP Multimedia has more information and a download client for Windows.
mmsclient deals with files that are not continuous (ie movie clips), however in my tests against the CBC radio streams doesn’t quite work. And yes, I, too, have no idea what “dbl” is, as it’s not a command on either Solaris or Mac OS X. (As an aside, while linking under Solaris, you want to tell gcc to link against libnsl and libsocket: gcc -g -O2 -Wall -o mmsclient client.o -lnsl -lsocket Mac OS X Just Works). CBC radio stream for Ottawa, high quality, is at mms:// at the time of this writing. Also note that the version mmsclient broadcast is also hardcoded to Media Player 7 in client.c:

  sprintf (str, "3403NSPlayer/; {33715801-BAB3-9D85-24E9-03B903282
70A}; Host: %s",

This might limit what media it can save, as now a days pretty much everything in Windows world depends on WMP 9.0 and up, as it has DRM support.

MP3/Shoutcast Streams

For that you just want streamripper.

Avenues of further investigation

Darwin Streaming Server, freely available as both source and binary from Apple, has Darwing Streaming Proxy, which, after a fair bit of ignoring wrong documentation, it is possible to get to work. DSS-5.0.3 doesn’t compile out of the box under Tiger, and seems like misses -lcrypt somewhere. However build process uses Xcode (which I adhor), and I have no idea how to convince it to work, so I gave in and downloaded the binary. I am not sure that it’s written in ANSI C, which is also a problem. Idea would be to convince it to fopen() and save the data to the file as it passes through the proxy.

Also, more reading of the simplified RTSP client specification is probably warranted.

stany@iskra:~[03:11am]$  telnet 554
Connected to
Escape character is '^]'.
DESCRIBE rtsp:// RTSP/1.0
Cseq: 1

RTSP/1.0 302 Found
Server: DSS/ (Build/452.22.3; Platform/Linux; Release/Panther; Update/3GPP; )
Cseq: 1
Location: rtsp://

Connection to closed by foreign host.