An RTSP server can deliver several media streams simultaneously and independently of each other. The server listens for connection requests on a TCP/IP port. An RTSP client (like the LEAD RTSP Source filter) will connect and issue RTSP commands to the server. The most common commands are:
DESCRIBE - get information about a certain media stream
SETUP - prepare to stream a certain media stream
PLAY - play a media stream
PAUSE - pause a media stream. The server does not send data anymore but keeps the stream alive for a certain amount of time (usually 60 sec)
OPTIONS - get more information or set a non-standard option. Also used to keep the stream alive
TEARDOWN - free resources associated with a certain stream. Most servers do this automatically for streams that have not been playing for a certain amount of time (usually 60 sec)
A server needs to respond to each of these commands.
We use the term "media stream" because the media being streamed can be a file or a live stream. The live stream can be from a capture device, or an MPEG-2 Transport stream received over a UDP port, or an RTSP stream from another server. The stream can also be from a DVD image (pretty much anything that can be used to create an output file can also be used as a source media stream for an RTSP folder).
Typically, an RTSP server streams all of the files from a certain folder. Not all the compressions are supported by the RTSP streaming technology, so in some cases the files with incompatible compressions might need to be transcoded on the fly.
Currently, the LEAD RTSP Sink filter supports H264, H265 video compressions and AAC audio compression. Files with different video or audio compressions would have to recompress the video, the audio or both video and audio.
See the "RFC 2326 - Real Time Streaming Protocol (RTSP)" standard for more information on the RTSP specification.
RTSP servers provide a way to restrict access to content to unauthorized users. RTSP servers can optionally use authentication to allow access only to authorized users. The authentication can be Basic or Digest. In either mode, the users would have to enter a user name and password before they can access a media stream. You can use the different authentication methods and give different access rights to each media stream. Or you can make it simple and give the same access rights to any media stream.
LEADTOOLS Multimedia contains some high level objects that make it very easy to implement an RTSP server:
IltmmRTSPServer Interface (API) or
RTSPServer class (.NET).
Each of these objects allow you to stream all the files from one or more folders. You just need to pick the source folders, customize some parameters like security settings and the timeout, and start listening for connections on a certain TCP/IP address and port. These modules will then stream any file with a corresponding filename that it finds on disk. It will also support .LNK files, which make it possible to redirect files outside the folders in question. So the real media can be outside the source folder, but the .LNK will have to be inside the folder.
Example:
Suppose you want an RTSP server that streams all of the files from "c:\MyFiles", and you want the server to listen on address 127.0.0.1 at port 554 (default RTSP port). The C++ code for a simple server would look like this:
void SetupRTSPServer()
{
IltmmRTSPServer *pServer;
// create the server instance
HRESULT hr = CoCreateInstance(CLSID_LMRTSPServer, NULL, CLSCTX_ALL, IID_ILMRTSPServer, (void**)&pServer);
// handle the error. Error checking is suppressed here for brevity
// specify c:\MyFiles as the source folder
pServer->put_SourceFolder(0, L"c:\\MyFiles"); // you can just pass a wide char string if the server is in the same EXE
// will listen on 127.0.0.1
pServer->put_TargetAddress(L"127.0.0.1");
// start listening on port 554
pServer->StartServer(554);
}
This server would handle all of the RTSP URLs of this format:
rtsp://127.0.0.1/RelativeURL
As requests to stream the file "c:\MyFiles\RelativeURL". Here are some examples of files you might want to stream and their corresponding URLs:
Try to connect with the LEAD RTSP Source and stream c:\MyFiles\file1.mpg filter using this URL:
rtsp://127.0.0.1/file1.mpg
When the LEAD RTSP server receives this URL, it will look for file1.mpg in all the source folders. In our case, there is only one folder, so it will look for c:\MyFiles\file1.mpg.
You can use the same server to also stream from a live video capture device. All you have to do is run a capture from the video and audio capture that you have and write to a DVR file that you store in c:\Myfiles. The simplest way is to run the DVR demo and set the output file to be something like c:\MyFiles\LiveCapture2.lbl. In this case, you would use the RTSP Source filter to stream the following URL:
rtsp://127.0.0.1/LiveCapture2.lbl
Run the MPEG-2 Transport stream and set its DVR settings to use c:\MyFiles\UDPStream3.lbl. And then use this URL in the RTSP Source filter:
rtsp://127.0.0.1/UDPStream3.lbl
The server will automatically search in subfolders if a subfolder was specified in the RTSP URL. For example, you might want to keep the DVR files in different subfolders or you just want to reduce the number of files in the root folders.
If you want to stream the file c:\MyFiles\MySubfolder\file4.avi, then you would use this RTSP URL:
rtsp://127.0.0.1/MySubfolder/file4.avi
Note that in this case, the backslash from the source filename is translated into a forward slash in the RTSP URL.
Let's say you want to stream a file you have on another disk "f:\abc\def.mkv". In this case, you can just create a link called c:\MyFiles\MyLink5.lnk and make it point to f:\abc\def.mkv. You would then use this URL:
rtsp://127.0.0.1/MySubfolder/MyLink5.lnk
This applies to DVDs as well, so you can create a link to d:\VIDEO_TS\VIDEO_TS.IFO called "c:\MyFiles\MyDvd5.lnk" and stream it using this URL:
rtsp://127.0.0.1/MySubfolder/MyDvd5.lnk
In this case, you need to keep in mind that the DVD will be recompressed on the fly and that DVDs take some time to start converting. So you might need to specify a timeout on the RTSP URL to instruct the RTSP filter to wait for the DVD to start converting, This URL would tell it to wait 10s before giving up with a timeout:
rtsp://127.0.0.1/MySubfolder/MyDvd5.lnk?Timeout=10
When the high level RTSP objects are streaming a growing DVR file, they will start streaming from the live position. This enables you to implement live streaming with the RTSP server. In this case, all the clients are seeing pretty much the same video, regardless of how long ago they connected to the RTSP server.
If you are streaming a DVR file that is not growing anymore, the clients will start playing the video from the beginning of the DVR buffer.
The high level RTSP objects provide automatic recompression using the LEAD H264 Encoder and LEAD AAC Encoder if the source video or audio are not using compatible compressions. They also provide a way to specify the compression settings to be used with the H264 encoder and AAC Encoder. These settings would override the current settings for the H264 and AAC Encoders when they are used to recompress the files on the fly.
If you desire to implement your RTSP server using the LEAD RTSP Sink filter directly, you will need to understand the relationship between the various RTSP Server interfaces. You will also need to have some knowledge of the RTSP protocol. The LEAD RTSP Sink will do most of the hard work, but you need to be aware of the structure of RTSP commands and of the most important parts of these commands.
The LEAD RTSP Sink filter will typically act in two different roles:
As a server, in which case it waits for RTSP clients to connect and send commands. In this case, you get the ILMRTSPServer interface from it. And you don't need to add it to a DirectShow graph - you just need the ILMRTSPServer interface.
As a sink, in which case it will send data to one RTSP client in response to commands received from another LEAD RTSP Sink acting as a server. This filter will be the sink in a convert or capture object and you will need to get the ILMRTSPServerSession interface from it.
Interface |
Who implements it |
What it does |
This is the main server interface. It keeps track of the ILMRTSPServerMedia interfaces that will handle all the client requests. The Server will go through all the ILMRTSPServerMedia interfaces and ask each of them if they can handle the RTSP command. The first ILMRTSPServerMedia interface that indicates it can handle the command will have to handle it. |
||
You |
This interface is responsible for handling the RTSP command for compatible media. You can use the ILMRTSPCommandParser and ILMRTSPResponseBuilder interfaces provided by the LEAD RTSP Sink filter to parse RTSP commands. |
For example, if you are asked to stream a file from a certain folder, this interface should parse the RTSP url using the ILMRTSPCommandParser interface to determine which file should satisfy the request.
When you detect an RTSP DESCRIBE command for a media stream you can serve, the ILMRTSPServerMedia interface (implemented in your object) is responsible for sending a response describing whether the stream has video, audio and the characteristics for each available stream (compression, width/height for video, audio sampling rate, etc). The LEAD RTSP Sink filter will provide support for adding information through the ILMRTSPServerSession interface describing the video and audio streams in the file. But you should add the other information like the file duration, information fields, etc. So you will need to add some response fields using the ILMRTSPResponseBuilder interface and then call the ILMRTSPServerSession interface to fill the remaining fields.
If the DESCRIBE command is for a stream or file you cannot serve, you can return an error and the ILMRTSPServer interface will ask next ILMRTSPServerMedia interface in the list whether it can support the URL. It will continue doing so until it finds a ILMRTSPServerMedia interface that can handle the URL. If nobody can handle it, the describe command will fail and the ILMRTSPServer interface will send an error code to the RTSP source client.
When you detect an RTSP SETUP command without a session field, the ILMRTSPServerMedia is responsible for creating a ILMRTSPServerSession object and keeping it in the list of active sessions (A session is somewhat similar to a client connection). The LEAD RTSP Sink filter will provide the ILMRTSPServerSession interface and will typically be the sink in a convert or capture graph. So if the URL indicates the intent to stream a file, you might do the following:
create a convert object
set the source filename to the file that should be streamed
select which streams should be rendered based on the stream indicated by the RTSP SETUP command
set the target format to RTSP
set the target filename to the server URL address
query the target object in the graph for the ILMRTSPServerSession interface
ask the server to generate a unique session ID by calling ILMRTSPServer::GenerateNewSessionID
set the session ID in the ILMRTSPServerSession by setting the ILMRTSPServerSession::SessionID property
add the ILMRTSPServerSession interface to the list of sessions maintained by your server media object. Make sure you have a way to retrieve the convert object using the session ID.
pass the setup command to the ILMRTSPServerSession interface for further processing
When you detect an RTSP SETUP command with a session field, you will need to do the following:
find the object with the correct session ID
render the additional stream indicated by the SETUP command
pass the setup command to the ILMRTSPServerSession interface for further processing
The ILMRTSPServerMedia will handle the RTSP PLAY command you will need to do the following:
find the object with the correct session ID
tell the graph associated with a ILMRTSPServerSession to start converting/capturing.
pass the play command to the ILMRTSPServerSession interface for further processing
The ILMRTSPServerMedia will handle the RTSP PAUSE command
find the object with the correct session ID
tell the graph associated with a ILMRTSPServerSession to pause the conversion/capture
pass the pause command to the ILMRTSPServerSession interface for further processing
The ILMRTSPServerMedia will handle the RTSP TEARDOWN command you will need to do the following:
find the object with the correct session ID
pass the teardown command to the ILMRTSPServerSession interface for further processing
free the graph associated with a ILMRTSPServerSession to start converting/capturing.
You should handle the various notifications passed to ILMRTSPServerMedia::OnNotification, which will indicate whether
a client timed out (in which case you should find the corresponding session and free it)
whether the media was removed from the server list (this happens if you remove it programmatically). In this case, you should free all the associated sessions
server has been stopped. In this case, you should free all the associated sessions
This interface will be implemented by the LEAD RTSP Sink filter that will do the actual sending of the data to the RTSP client. All you have to do is set up the convert or capture object that will do the actual streaming to have a LEAD RTSP Sink and obtain the ILMRTSPServerSession interface from it. You should then keep this convert/capture object in the list of active sessions.
The server will pass this interface whenever it receives an RTSP command from the client. This interface should be used to find out which stream is requested, what RTSP command was received (DESCRIBE, SETUP, PLAY, PAUSE, TEARDOWN) and command parameters.
You will need to find which file/media should be streamed by examining the command URL.
The command parameters contain important information also. For example, the session parameter tells you which session should execute the command. Also, for a file you might have an interval which tells you to stream a portion, rather than the whole file.
The server will pass this interface when it receives an RTSP command from the client. This interface should be used to build the RTSP response. It is important to be familiar with the RTSP protocol so you know how the response should look and how to set the various error codes whenever something goes wrong.
Particular care should be taken with the DESCRIBE command, which contains a description of the media. You should fill the response parameters regarding the server not accessible to the sink (the "v=", "o=" and "s=" parameters). Please see "RFC 2326 - Real Time Streaming Protocol (RTSP)" specification for more information. For example, this sequence might be enough:
ILMRTSPResponseBuilder *pBuilder;
hr = pBuilder->put_ContentType(L'application/sdp');
hr = AddContent(pBuilder, L'v=0');
hr = AddContent(pBuilder, L'o=- 0 0 IN IP4 127.0.0.1');
hr = AddContent(pBuilder, L's=Test session');
hr = AddContent(pBuilder, L'a=range:npt=0-'); // indicate that we are playing the whole file/stream
hr = pDescribeSession->HandleCommand(pServer, pParser, pBuilder, socket); /* where pDescribeSession is a pointer to an ILMRTSPServerSession interface from a LEAD RTSP Sink filter. The filter should be a sink in a graph in which the media requested is the source */
In the above example, the pDescribeSession->HandleCommand call will fill the rest of the response with the media compression information (the "m=" parameters and "a=" fields regarding the audio/video streams in the file).
Use IFileSinkFilter::SetFileName to set the address to be used by the filter. The same address will be used whether the filter acts as a server or a sink. When you add the filter as a sink to a convert object, set the target filename to the loopback address ("rtsp://localhost" or "rtsp://127.0.0.1"). The IP address in this URL will be overwritten by the IP address set on the server.
Note that when you use the LEAD RTSP Sink as a sink in a capture graph, it is most likely that only one client will be able to view the stream because DirectShow capture devices can rarely be used in multiple capture graphs. This is why it is best to capture to a DVR file (and stream that DVR file whenever you want to implement a live stream).
Streaming a DVR file is also recommended for restreaming an MPEG-2 Transport UDP stream, since the LEAD MPEG-2 Transport UDP Source filter uses DVR files to store data.