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

📄 rtspclient.cpp

📁 流媒体传输协议的实现代码,非常有用.可以支持rtsp mms等流媒体传输协议
💻 CPP
📖 第 1 页 / 共 5 页
字号:
      + 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, "RECORD")) break;    // Get the response from the server:    unsigned bytesRead; unsigned responseCode;    char* firstLine; char* nextLineStart;    if (!getResponse("RECORD", bytesRead, responseCode, firstLine, nextLineStart)) break;    delete[] cmd;    return True;  } while (0);  delete[] cmd;  return False;}Boolean RTSPClient::setMediaSessionParameter(MediaSession& /*session*/,					     char const* parameterName,					     char const* parameterValue) {  char* cmd = NULL;  do {    // First, make sure that we have a RTSP session in progress    if (fLastSessionId == NULL) {      envir().setResultMsg(NoSessionErr);      break;    }    // Send the SET_PARAMETER command:    // First, construct an authenticator string:    char* authenticatorStr      = createAuthenticatorString(&fCurrentAuthenticator,				  "SET_PARAMETER", fBaseURL);    char* const cmdFmt =      "SET_PARAMETER %s RTSP/1.0\r\n"      "CSeq: %d\r\n"      "Session: %s\r\n"      "%s"      "%s"      "%s: %s\r\n"      "\r\n";    unsigned cmdSize = strlen(cmdFmt)      + strlen(fBaseURL)      + 20 /* max int len */      + strlen(fLastSessionId)      + strlen(authenticatorStr)      + fUserAgentHeaderStrSize      + strlen(parameterName) + strlen(parameterValue);    cmd = new char[cmdSize];    sprintf(cmd, cmdFmt,	    fBaseURL,	    ++fCSeq,	    fLastSessionId,	    authenticatorStr,	    fUserAgentHeaderStr,	    parameterName, parameterValue);    delete[] authenticatorStr;    if (!sendRequest(cmd, "SET_PARAMETER")) break;    // Get the response from the server:    unsigned bytesRead; unsigned responseCode;    char* firstLine; char* nextLineStart;    if (!getResponse("SET_PARAMETER", bytesRead, responseCode, firstLine, nextLineStart)) break;    delete[] cmd;    return True;  } while (0);  delete[] cmd;  return False;}Boolean RTSPClient::teardownMediaSession(MediaSession& /*session*/) {  char* cmd = NULL;  do {    // First, make sure that we have a RTSP session in progreee    if (fLastSessionId == NULL) {      envir().setResultMsg(NoSessionErr);      break;    }    // Send the TEARDOWN command:    // First, construct an authenticator string:    char* authenticatorStr      = createAuthenticatorString(&fCurrentAuthenticator,				  "TEARDOWN", fBaseURL);    char* const cmdFmt =      "TEARDOWN %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, "TEARDOWN")) 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("TEARDOWN", bytesRead, responseCode, firstLine, nextLineStart)) break;            delete[] fLastSessionId; fLastSessionId = NULL;      // we're done with this session    }          delete[] cmd;    return True;  } while (0);  delete[] cmd;  return False;}Boolean RTSPClient::teardownMediaSubsession(MediaSubsession& subsession) {  char* cmd = NULL;  do {    // First, make sure that we have a RTSP session in progreee    if (subsession.sessionId == NULL) {      envir().setResultMsg(NoSessionErr);      break;    }    // Send the TEARDOWN command:    // First, construct an authenticator string:    char* authenticatorStr      = createAuthenticatorString(&fCurrentAuthenticator,				  "TEARDOWN", fBaseURL);    char* const cmdFmt =      "TEARDOWN %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);    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, "TEARDOWN")) 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("TEARDOWN", bytesRead, responseCode, firstLine, nextLineStart)) break;    }          delete[] (char*)subsession.sessionId;    subsession.sessionId = NULL;    // we're done with this session    delete[] cmd;    return True;  } while (0);  delete[] cmd;  return False;}Boolean RTSPClient::openConnectionFromURL(char const* url) {  do {    // Set this as our base URL:    delete[] fBaseURL; fBaseURL = strDup(url); if (fBaseURL == NULL) break;    // Begin by parsing the URL:    NetAddress destAddress;    portNumBits urlPortNum;    char const* urlSuffix;    if (!parseRTSPURL(envir(), url, destAddress, urlPortNum, &urlSuffix)) break;    portNumBits destPortNum      = fTunnelOverHTTPPortNum == 0 ? urlPortNum : fTunnelOverHTTPPortNum;        if (fInputSocketNum < 0) {      // We don't yet have a TCP socket.  Set one up (blocking) now:      fInputSocketNum = fOutputSocketNum	= setupStreamSocket(envir(), 0, False /* =>blocking */);      if (fInputSocketNum < 0) break;          // Connect to the remote endpoint:      struct sockaddr_in remoteName;      remoteName.sin_family = AF_INET;      remoteName.sin_port = htons(destPortNum);      remoteName.sin_addr.s_addr = fServerAddress	= *(unsigned*)(destAddress.data());      if (connect(fInputSocketNum, (struct sockaddr*)&remoteName, sizeof remoteName)	  != 0) {	envir().setResultErrMsg("connect() failed: ");	break;      }            if (fTunnelOverHTTPPortNum != 0 && !setupHTTPTunneling(urlSuffix)) break;    }    return True;   } while (0);  fDescribeStatusCode = 1;  resetTCPSockets();  return False;}Boolean RTSPClient::parseRTSPURL(UsageEnvironment& env, char const* url,				 NetAddress& address,				 portNumBits& portNum,				 char const** urlSuffix) {  do {    // Parse the URL as "rtsp://<address>:<port>/<etc>"    // (with ":<port>" and "/<etc>" optional)    // Also, skip over any "<username>[:<password>]@" preceding <address>    char const* prefix = "rtsp://";    unsigned const prefixLength = 7;    if (_strncasecmp(url, prefix, prefixLength) != 0) {      env.setResultMsg("URL is not of the form \"", prefix, "\"");      break;    }    unsigned const parseBufferSize = 100;    char parseBuffer[parseBufferSize];    char const* from = &url[prefixLength];    // Skip over any "<username>[:<password>]@"    char const* from1 = from;    while (*from1 != '\0' && *from1 != '/') {      if (*from1 == '@') {	from = ++from1;	break;      }      ++from1;    }    char* to = &parseBuffer[0];    unsigned i;    for (i = 0; i < parseBufferSize; ++i) {      if (*from == '\0' || *from == ':' || *from == '/') {	// We've completed parsing the address	*to = '\0';	break;      }      *to++ = *from++;    }    if (i == parseBufferSize) {      env.setResultMsg("URL is too long");      break;    }    NetAddressList addresses(parseBuffer);    if (addresses.numAddresses() == 0) {      env.setResultMsg("Failed to find network address for \"",		       parseBuffer, "\"");      break;    }    address = *(addresses.firstAddress());    portNum = 554; // default value    char nextChar = *from;    if (nextChar == ':') {      int portNumInt;      if (sscanf(++from, "%d", &portNumInt) != 1) {	env.setResultMsg("No port number follows ':'");	break;      }      if (portNumInt < 1 || portNumInt > 65535) {	env.setResultMsg("Bad port number");	break;      }      portNum = (portNumBits)portNumInt;      while (*from >= '0' && *from <= '9') ++from; // skip over port number    }    // The remainder of the URL is the suffix:    if (urlSuffix != NULL) *urlSuffix = from;    return True;  } while (0);  return False;}Boolean RTSPClient::parseRTSPURLUsernamePassword(char const* url,						 char*& username,						 char*& password) {  username = password = NULL; // by default  do {    // Parse the URL as "rtsp://<username>[:<password>]@<whatever>"    char const* prefix = "rtsp://";    unsigned const prefixLength = 7;    if (_strncasecmp(url, prefix, prefixLength) != 0) break;    // Look for the ':' and '@':    unsigned usernameIndex = prefixLength;    unsigned colonIndex = 0, atIndex = 0;    for (unsigned i = usernameIndex; url[i] != '\0' && url[i] != '/'; ++i) {      if (url[i] == ':' && colonIndex == 0) {	colonIndex = i;      } else if (url[i] == '@') {	atIndex = i;	break; // we're done      }    }    if (atIndex == 0) break; // no '@' found    char* urlCopy = strDup(url);    urlCopy[atIndex] = '\0';    if (colonIndex > 0) {      urlCopy[colonIndex] = '\0';      password = strDup(&urlCopy[colonIndex+1]);    } else {      password = strDup("");    }    username = strDup(&urlCopy[usernameIndex]);    delete[] urlCopy;    return True;  } while (0);  return False;}static const char base64Char[] ="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";static char* base64Encode(char const* orig) {  if (orig == NULL) return NULL;  unsigned const origLength = strlen(orig);  unsigned const numOrig24BitValues = origLength/3;  Boolean havePadding = origLength > numOrig24BitValues*3;  Boolean havePadding2 = origLength == numOrig24BitValues*3 + 2;  unsigned const numResultBytes = 4*(numOrig24BitValues + havePadding);  char* result = new char[numResultBytes+1]; // allow for trailing '\0'    // Map each full group of 3 input bytes into 4 output base-64 characters:  unsigned i;  for (i = 0; i < numOrig24BitValues; ++i) {    result[4*i+0] = base64Char[(orig[3*i]>>2)&0x3F];    result[4*i+1] = base64Char[(((orig[3*i]&0x3)<<4) | (orig[3*i+1]>>4))&0x3F];    result[4*i+2] = base64Char[((orig[3*i+1]<<2) | (orig[3*i+2]>>6))&0x3F];    result[4*i+3] = base64Char[orig[3*i+2]&0x3F];  }  // Now, take padding into account.  (Note: i == numOrig24BitValues)  if (havePadding) {    result[4*i+0] = base64Char[(orig[3*i]>>2)&0x3F];    result[4*i+1] = base64Char[(((orig[3*i]&0x3)<<4) | (orig[3*i+1]>>4))&0x3F];    if (havePadding2) {      result[4*i+2] = base64Char[(orig[3*i+1]<<2)&0x3F];    } else {      result[4*i+2] = '=';    }    result[4*i+3] = '=';  }  result[numResultBytes] = '\0';  return result;}char*RTSPClient::createAuthenticatorString(Authenticator const* authenticator,				      char const* cmd, char const* url) {  if (authenticator != NULL && authenticator->realm() != NULL      && authenticator->username() != NULL && authenticator->password() != NULL) {    // We've been provided a filled-in authenticator, so use it:    char* authenticatorStr;    if (authenticator->nonce() != NULL) { // Digest authentication      char* const authFmt =	"Authorization: Digest username=\"%s\", realm=\"%s\", "	"nonce=\"%s\", uri=\"%s\", response=\"%s\"\r\n";

⌨️ 快捷键说明

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