⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rtspclient.cpp

📁 流媒体传输协议的实现代码,非常有用.可以支持rtsp mms等流媒体传输协议
💻 CPP
📖 第 1 页 / 共 5 页
字号:
    // Look for a "Session:" header (to set our session id), and    // a "Transport: " header (to set the server address/port)    // For now, ignore other headers.    char* lineStart;    char* sessionId = new char[fResponseBufferSize]; // ensures we have enough space    while (1) {      lineStart = nextLineStart;      if (lineStart == NULL) break;      nextLineStart = getLine(lineStart);      if (sscanf(lineStart, "Session: %[^;]", sessionId) == 1) {	subsession.sessionId = strDup(sessionId);	delete[] fLastSessionId; fLastSessionId = strDup(sessionId);	continue;      }      char* serverAddressStr;      portNumBits serverPortNum;      unsigned char rtpChannelId, rtcpChannelId;      if (parseTransportResponse(lineStart,				 serverAddressStr, serverPortNum,				 rtpChannelId, rtcpChannelId)) {	delete[] subsession.connectionEndpointName();	subsession.connectionEndpointName() = serverAddressStr;	subsession.serverPortNum = serverPortNum;	subsession.rtpChannelId = rtpChannelId;	subsession.rtcpChannelId = rtcpChannelId;	continue;      }    }     delete[] sessionId;    if (subsession.sessionId == NULL) {      envir().setResultMsg("\"Session:\" header is missing in the response");      break;    }    if (streamUsingTCP) {      // Tell the subsession to receive RTP (and send/receive RTCP)      // over the RTSP stream:      if (subsession.rtpSource() != NULL)	subsession.rtpSource()->setStreamSocket(fInputSocketNum,						subsession.rtpChannelId);      if (subsession.rtcpInstance() != NULL)	subsession.rtcpInstance()->setStreamSocket(fInputSocketNum,						   subsession.rtcpChannelId);    } else {      // Normal case.      // Set the RTP and RTCP sockets' destination address and port      // from the information in the SETUP response:       subsession.setDestinations(fServerAddress);    }    delete[] cmd;    return True;  } while (0);  delete[] cmd;  return False;}static char* createScaleString(float scale, float currentScale) {  char buf[100];  if (scale == 1.0f && currentScale == 1.0f) {    // This is the default value; we don't need a "Scale:" header:    buf[0] = '\0';  } else {    sprintf(buf, "Scale: %f\r\n", scale);  }  return strDup(buf);}      static char* createRangeString(float start, float end) {  char buf[100];  if (start < 0) {    // We're resuming from a PAUSE; there's no "Range:" header at all    buf[0] = '\0';  } else if (end < 0) {    // There's no end time:    sprintf(buf, "Range: npt=%.3f-\r\n", start);  } else {    // There's both a start and an end time; include them both in the "Range:" hdr    sprintf(buf, "Range: npt=%.3f-%.3f\r\n", start, end);  }  return strDup(buf);}      static char const* NoSessionErr = "No RTSP session is currently in progress\n";Boolean RTSPClient::playMediaSession(MediaSession& session,				     float start, float end, float scale) {#ifdef SUPPORT_REAL_RTSP  if (session.isRealNetworksRDT) {    // This is a RealNetworks stream; set the "Subscribe" parameter before proceeding:    char* streamRuleString = RealGetSubscribeRuleString(&session);    setMediaSessionParameter(session, "Subscribe", streamRuleString);    delete[] streamRuleString;  }#endif  char* cmd = NULL;  do {    // First, make sure that we have a RTSP session in progress    if (fLastSessionId == NULL) {      envir().setResultMsg(NoSessionErr);      break;    }    // Send the PLAY command:    // First, construct an authenticator string:    char* authenticatorStr      = createAuthenticatorString(&fCurrentAuthenticator, "PLAY", fBaseURL);    // And then a "Scale:" string:    char* scaleStr = createScaleString(scale, session.scale());    // And then a "Range:" string:    char* rangeStr = createRangeString(start, end);    char* const cmdFmt =      "PLAY %s RTSP/1.0\r\n"      "CSeq: %d\r\n"      "Session: %s\r\n"      "%s"      "%s"      "%s"      "%s"      "\r\n";    unsigned cmdSize = strlen(cmdFmt)      + strlen(fBaseURL)      + 20 /* max int len */      + strlen(fLastSessionId)      + strlen(scaleStr)      + strlen(rangeStr)      + strlen(authenticatorStr)      + fUserAgentHeaderStrSize;    cmd = new char[cmdSize];    sprintf(cmd, cmdFmt,	    fBaseURL,	    ++fCSeq,	    fLastSessionId,	    scaleStr,	    rangeStr,	    authenticatorStr,	    fUserAgentHeaderStr);    delete[] scaleStr;    delete[] rangeStr;    delete[] authenticatorStr;    if (!sendRequest(cmd, "PLAY")) break;    // Get the response from the server:    unsigned bytesRead; unsigned responseCode;    char* firstLine; char* nextLineStart;    if (!getResponse("PLAY", bytesRead, responseCode, firstLine, nextLineStart)) break;    // Look for various headers that we understand:    char* lineStart;    while (1) {      lineStart = nextLineStart;      if (lineStart == NULL) break;      nextLineStart = getLine(lineStart);      if (parseScaleHeader(lineStart, session.scale())) break;    }    delete[] cmd;    return True;  } while (0);  delete[] cmd;  return False;}Boolean RTSPClient::playMediaSubsession(MediaSubsession& subsession,					float start, float end, float scale,					Boolean hackForDSS) {  char* cmd = NULL;  do {    // First, make sure that we have a RTSP session in progress    if (subsession.sessionId == NULL) {      envir().setResultMsg(NoSessionErr);      break;    }    // Send the PLAY command:    // First, construct an authenticator string:    char* authenticatorStr      = createAuthenticatorString(&fCurrentAuthenticator, "PLAY", fBaseURL);    // And then a "Scale:" string:    char* scaleStr = createScaleString(scale, subsession.scale());    // And then a "Range:" string:    char* rangeStr = createRangeString(start, end);    char* const cmdFmt =      "PLAY %s%s%s RTSP/1.0\r\n"      "CSeq: %d\r\n"      "Session: %s\r\n"      "%s"      "%s"      "%s"      "%s"      "\r\n";    char const *prefix, *separator, *suffix;    constructSubsessionURL(subsession, prefix, separator, suffix);    if (hackForDSS || fServerIsKasenna) {      // When "PLAY" is used to inject RTP packets into a DSS      // (violating the RTSP spec, btw; "RECORD" should have been used)      // the DSS can crash (or hang) if the '/trackid=...' portion of      // the URL is present.      separator = suffix = "";    }    unsigned cmdSize = strlen(cmdFmt)      + strlen(prefix) + strlen(separator) + strlen(suffix)      + 20 /* max int len */      + strlen(subsession.sessionId)      + strlen(scaleStr)      + strlen(rangeStr)      + strlen(authenticatorStr)      + fUserAgentHeaderStrSize;    cmd = new char[cmdSize];    sprintf(cmd, cmdFmt,	    prefix, separator, suffix,	    ++fCSeq,	    subsession.sessionId,	    scaleStr,	    rangeStr,	    authenticatorStr,	    fUserAgentHeaderStr);    delete[] scaleStr;    delete[] rangeStr;    delete[] authenticatorStr;    if (!sendRequest(cmd, "PLAY")) break;    // Get the response from the server:    unsigned bytesRead; unsigned responseCode;    char* firstLine; char* nextLineStart;    if (!getResponse("PLAY", bytesRead, responseCode, firstLine, nextLineStart)) break;    // Look for various headers that we understand:    char* lineStart;    while (1) {      lineStart = nextLineStart;      if (lineStart == NULL) break;      nextLineStart = getLine(lineStart);      if (parseRTPInfoHeader(lineStart,			     subsession.rtpInfo.trackId,			     subsession.rtpInfo.seqNum,			     subsession.rtpInfo.timestamp)) {	continue;      }      if (parseScaleHeader(lineStart, subsession.scale())) continue;    }    delete[] cmd;    return True;  } while (0);  delete[] cmd;  return False;}Boolean RTSPClient::pauseMediaSession(MediaSession& session) {  char* cmd = NULL;  do {    // First, make sure that we have a RTSP session in progress    if (fLastSessionId == NULL) {      envir().setResultMsg(NoSessionErr);      break;    }    // Send the PAUSE command:    // First, construct an authenticator string:    char* authenticatorStr      = createAuthenticatorString(&fCurrentAuthenticator, "PAUSE", fBaseURL);    char* const cmdFmt =      "PAUSE %s RTSP/1.0\r\n"      "CSeq: %d\r\n"      "Session: %s\r\n"      "%s"      "%s"      "\r\n";    unsigned cmdSize = strlen(cmdFmt)      + strlen(fBaseURL)      + 20 /* max int len */      + strlen(fLastSessionId)      + strlen(authenticatorStr)      + fUserAgentHeaderStrSize;    cmd = new char[cmdSize];    sprintf(cmd, cmdFmt,	    fBaseURL,	    ++fCSeq,	    fLastSessionId,	    authenticatorStr,	    fUserAgentHeaderStr);    delete[] authenticatorStr;    if (!sendRequest(cmd, "PAUSE")) break;    if (fTCPStreamIdCount == 0) { // When TCP streaming, don't look for a response      // Get the response from the server:      unsigned bytesRead; unsigned responseCode;      char* firstLine; char* nextLineStart;      if (!getResponse("PAUSE", bytesRead, responseCode, firstLine, nextLineStart)) break;    }    delete[] cmd;    return True;  } while (0);  delete[] cmd;  return False;}Boolean RTSPClient::pauseMediaSubsession(MediaSubsession& subsession) {  char* cmd = NULL;  do {    // First, make sure that we have a RTSP session in progress    if (subsession.sessionId == NULL) {      envir().setResultMsg(NoSessionErr);      break;    }        // Send the PAUSE command:        // First, construct an authenticator string:    char* authenticatorStr      = createAuthenticatorString(&fCurrentAuthenticator, "PAUSE", fBaseURL);        char* const cmdFmt =      "PAUSE %s%s%s RTSP/1.0\r\n"      "CSeq: %d\r\n"      "Session: %s\r\n"      "%s"      "%s"      "\r\n";        char const *prefix, *separator, *suffix;    constructSubsessionURL(subsession, prefix, separator, suffix);    if (fServerIsKasenna) separator = suffix = "";    unsigned cmdSize = strlen(cmdFmt)      + strlen(prefix) + strlen(separator) + strlen(suffix)      + 20 /* max int len */      + strlen(subsession.sessionId)      + strlen(authenticatorStr)      + fUserAgentHeaderStrSize;    cmd = new char[cmdSize];    sprintf(cmd, cmdFmt,	    prefix, separator, suffix,	    ++fCSeq,	    subsession.sessionId,	    authenticatorStr,	    fUserAgentHeaderStr);    delete[] authenticatorStr;        if (!sendRequest(cmd, "PAUSE")) break;        if (fTCPStreamIdCount == 0) { // When TCP streaming, don't look for a response      // Get the response from the server:      unsigned bytesRead; unsigned responseCode;      char* firstLine; char* nextLineStart;      if (!getResponse("PAUSE", bytesRead, responseCode, firstLine, nextLineStart)) break;    }          delete[] cmd;    return True;  } while (0);    delete[] cmd;  return False;}Boolean RTSPClient::recordMediaSubsession(MediaSubsession& subsession) {  char* cmd = NULL;  do {    // First, make sure that we have a RTSP session in progress    if (subsession.sessionId == NULL) {      envir().setResultMsg(NoSessionErr);      break;    }    // Send the RECORD command:    // First, construct an authenticator string:    char* authenticatorStr      = createAuthenticatorString(&fCurrentAuthenticator,				  "RECORD", fBaseURL);    char* const cmdFmt =      "RECORD %s%s%s RTSP/1.0\r\n"      "CSeq: %d\r\n"      "Session: %s\r\n"      "Range: npt=0-\r\n"      "%s"      "%s"      "\r\n";    char const *prefix, *separator, *suffix;    constructSubsessionURL(subsession, prefix, separator, suffix);    unsigned cmdSize = strlen(cmdFmt)      + strlen(prefix) + strlen(separator) + strlen(suffix)      + 20 /* max int len */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -