You can create an ServerMediaSession
from an SDP file and add it to an RTSPServer
.
#include "liveMedia.hh"
#include "BasicUsageEnvironment.hh"
class SDPMediaSubsession: public ServerMediaSubsession
{
public:
static SDPMediaSubsession* createNew(UsageEnvironment& env, MediaSubsession* subsession) { return new SDPMediaSubsession(env, subsession); }
protected:
SDPMediaSubsession(UsageEnvironment& env, MediaSubsession* subsession) : ServerMediaSubsession(env), m_subsession(subsession) {};
virtual ~SDPMediaSubsession() {};
protected:
virtual char const* sdpLines() { return m_subsession->savedSDPLines(); }
virtual void getStreamParameters(unsigned clientSessionId, netAddressBits clientAddress, Port const& clientRTPPort, Port const& clientRTCPPort, int tcpSocketNum, unsigned char rtpChannelId, unsigned char rtcpChannelId,
netAddressBits& destinationAddress, u_int8_t& destinationTTL, Boolean& isMulticast, Port& serverRTPPort, Port& serverRTCPPort, void*& streamToken)
{
destinationAddress = m_subsession->connectionEndpointAddress();
isMulticast = IsMulticastAddress(destinationAddress);
serverRTPPort = m_subsession->clientPortNum();
serverRTCPPort = m_subsession->clientPortNum()+1;
}
virtual void startStream(unsigned clientSessionId, void* streamToken, TaskFunc* rtcpRRHandler, void* rtcpRRHandlerClientData, unsigned short& rtpSeqNum, unsigned& rtpTimestamp, ServerRequestAlternativeByteHandler* serverRequestAlternativeByteHandler, void* serverRequestAlternativeByteHandlerClientData) {}
protected:
MediaSubsession* m_subsession;
};
class SDPRTSPServer: public RTSPServer
{
public:
static SDPRTSPServer* createNew(UsageEnvironment& env, Port ourPort, UserAuthenticationDatabase* authDatabase = NULL, unsigned reclamationTestSeconds = 65)
{
int ourSocket = setUpOurSocket(env, ourPort);
if (ourSocket == -1) return NULL;
return new SDPRTSPServer(env, ourSocket, ourPort, authDatabase, reclamationTestSeconds);
}
protected:
SDPRTSPServer(UsageEnvironment& env, int ourSocket, Port ourPort, UserAuthenticationDatabase* authDatabase, unsigned reclamationTestSeconds)
: RTSPServer(env, ourSocket, ourPort, authDatabase, reclamationTestSeconds) {}
protected:
virtual ServerMediaSession* lookupServerMediaSession(char const* streamName, Boolean isFirstLookupInSession)
{
ServerMediaSession* sms = RTSPServer::lookupServerMediaSession(streamName);
if (sms == NULL)
{
FILE* file = fopen(streamName, "r");
if (file != NULL)
{
sms = ServerMediaSession::createNew(envir(), streamName);
fseek(file, 0, SEEK_END);
long size = ftell(file);
fseek(file, 0, SEEK_SET);
char sdp[size];
fread(sdp,size,1,file);
fclose(file);
MediaSession* session = MediaSession::createNew(envir(), sdp);
MediaSubsessionIterator iter(*session);
MediaSubsession* subsession = NULL;
while ((subsession = iter.next()) != NULL)
{
sms->addSubsession(SDPMediaSubsession::createNew(envir(),subsession));
}
addServerMediaSession(sms);
}
}
return sms;
}
};
int main(int argc, char** argv)
{
TaskScheduler* scheduler = BasicTaskScheduler::createNew();
BasicUsageEnvironment* env = BasicUsageEnvironment::createNew(*scheduler);
RTSPServer* rtspServer = SDPRTSPServer::createNew(*env, 8554);
if (rtspServer == NULL)
{
*env << "Failed to create RTSP server: " << env->getResultMsg() << "\n";
exit(1);
}
env->taskScheduler().doEventLoop();
return 0;
}
This RTSPServer will create a session reading SDP file specified by the url without sending any RTP/RTCP streams.
It will give access to the SDP files available in the running directory of the RTSP server (like live555MediaServer does for video files).
For instance rtsp://<server>:8554/cam1.sdp
will give access to the stream described in cam1.sdp