3

I'm accessing a video server with Live555 that is streaming to another program. I want to send rtsp PAUSE and PLAY commands to the video server to stop streaming to any other program. Is this possible? My code does not seem to do anything. I can connect to the server and the server verifies that I have received a full PAUSE command:

VideoServer.h

//must make this store session so we can access the session in the static
//callbacks 
class MyRTSPClient: public RTSPClient{
protected:
  MyRTSPClient(UsageEnvironment& env, char const* rtspURL,
    int verbosityLevel, char const* applicationName, portNumBits tunnelOverHTTPPortNum):
  RTSPClient(env, rtspURL, verbosityLevel, applicationName, tunnelOverHTTPPortNum)
    {

    }

public:

  MediaSession* session_;

  bool sessionStarted_;

  static MyRTSPClient* createNew(UsageEnvironment& env, char const* rtspURL,
                                     int verbosityLevel = 0,
                                     char const* applicationName = NULL,
                                     portNumBits tunnelOverHTTPPortNum = 0) 
    {
      return new MyRTSPClient(env, rtspURL, verbosityLevel, applicationName,     tunnelOverHTTPPortNum);
      }

};


class VideoServer
{

public:

  VideoServer();


private:
  TaskScheduler* scheduler_;
  UsageEnvironment* env_;
  MyRTSPClient* rtspClient_;
  char eventLoopWatchVariable;

  //Asynchronously start the connection
  void StartConnection();

  static void callbackDESCRIBE(RTSPClient* rtspClient, int resultCode, char* resultString);

  static void callbackPAUSEPLAY(RTSPClient* rtspClient, int resultCode, char* resultString);
};

VideoServer.cpp

VideoServer::VideoServer()
{
  eventLoopWatchVariable = 0;
  scheduler_ = BasicTaskScheduler::createNew();
  env_ = BasicUsageEnvironment::createNew(*scheduler_);

  //create rtsp client with default params and our url and environment
  rtspClient_ = MyRTSPClient::createNew(*env_, 
      MINI_HARV_AXIS_RTSP_URL, 4, "jtalon5");

  //call description to initialize the session

  if (rtspClient_ == NULL) {
    std::cout << "Failed to create a RTSP client for URL \"" << 
    MINI_HARV_AXIS_RTSP_URL << std::endl;
    return;
  }
  std::cout << "made the client!" << std::endl;
  // Next, send a RTSP "DESCRIBE" command, to get a SDP description for the stream.
  // Note that this command - like all RTSP commands - is sent asynchronously; we do    not block, waiting for a response.
  // Instead, the following function call returns immediately, and we handle the RTSP response later, from within the event loop:
  rtspClient_->sendDescribeCommand(callbackDESCRIBE); 

  //start doEventLoop in separate thread so it is not blocking
  boost::thread thr1(&MiniHarvAxisInterface::StartConnection, this);

}

void VideoServer::StartConnection()
{
  env_->taskScheduler().doEventLoop(&eventLoopWatchVariable);
}

void MiniHarvAxisInterface::callbackDESCRIBE(RTSPClient* rtspClient, int resultCode, char* resultString) 
{
  std::cout << "describe" << resultString << std::endl;
  UsageEnvironment& env = rtspClient->envir();

  char* const sdpDescription = resultString;
  ((MyRTSPClient*)rtspClient)->session_ = MediaSession::createNew(env, sdpDescription);
  ((MyRTSPClient*)rtspClient)->sessionStarted_ = true;

  if(((MyRTSPClient*)rtspClient)->session_ == NULL)
    std::cout << "did not create session" << std::endl;
  else
    std::cout << "created session" << std::endl;

  rtspClient->sendPauseCommand(*((MyRTSPClient*)rtspClient)->session_, &callbackPAUSEPLAY);
}

void MiniHarvAxisInterface::callbackPAUSEPLAY(RTSPClient* rtspClient, int resultCode, char* resultString)
{
  //do nothing
}

It seems as if I can only pause and play a stream that I create in this process. Is this the case using Live555?

Moshe Katz
  • 15,992
  • 7
  • 69
  • 116
jadams
  • 33
  • 1
  • 4

1 Answers1

0

Yes this is possible in Live555.

By default Live555 does nothing unless you redefine the pauseStream function (see comment in pauseStream function in Live555 source below):

// default implementation: do nothing

You must create your own session class and you must redefine the pauseStream function as shown in the example below:

Your media session .h file should look something like:

#include <MediaSubsession.hh>
class YOURMediaSubsession: public MediaSubsession {

... //You can leave this empty if you like

private:

...

  virtual void pauseStream(unsigned /*clientSessionId*/,void* /*streamToken*/);
};

Your media session .cpp file should look something like:

#include <YOURMediaSubsession.hh>
void YOURMediaSubsession::pauseStream(unsigned /*clientSessionId*/,
                    void* /*streamToken*/) {
  // default implementation: do nothing
}

The you can add whatever you like in this function, whether it may be stopping/terminating all streams, or getting the encoder to keep encoding and the same frame to give the illusion of having the stream paused for a pre-set amount of time is all up to you.

Note that I can see in your code that you are using a default MediaSession class as shown in your code here:

((MyRTSPClient*)rtspClient)->session_ = MediaSession::createNew(env, sdpDescription);

You will need to construct your own YOURMediaSubsession class based on the MediaSession class to redefine the pauseStream function as shown above then YOU do the pausing, not live555. It should look more like:

((MyRTSPClient*)rtspClient)->session_ = YOURMediaSubsession::createNew(env, sdpDescription);
ALM865
  • 1,078
  • 13
  • 21