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

📄 rtspclient.cpp

📁 H.264 RTSP 串流(live 555)視窗版本
💻 CPP
📖 第 1 页 / 共 5 页
字号:
/**********This library is free software; you can redistribute it and/or modify it underthe terms of the GNU Lesser General Public License as published by theFree Software Foundation; either version 2.1 of the License, or (at youroption) any later version. (See <http://www.gnu.org/copyleft/lesser.html>.)This library is distributed in the hope that it will be useful, but WITHOUTANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESSFOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License formore details.You should have received a copy of the GNU Lesser General Public Licensealong with this library; if not, write to the Free Software Foundation, Inc.,51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA**********/// "liveMedia"// Copyright (c) 1996-2010 Live Networks, Inc.  All rights reserved.// A generic RTSP client// Implementation#include "RTSPClient.hh"#include "RTSPCommon.hh"#include "Base64.hh"#include "Locale.hh"#include <GroupsockHelper.hh>#include "our_md5.h"////////// RTSPClient implementation //////////RTSPClient* RTSPClient::createNew(UsageEnvironment& env, char const* rtspURL,				  int verbosityLevel,				  char const* applicationName,				  portNumBits tunnelOverHTTPPortNum) {  return new RTSPClient(env, rtspURL,			verbosityLevel, applicationName, tunnelOverHTTPPortNum);}unsigned RTSPClient::sendDescribeCommand(responseHandler* responseHandler, Authenticator* authenticator) {  if (authenticator != NULL) fCurrentAuthenticator = *authenticator;  return sendRequest(new RequestRecord(++fCSeq, "DESCRIBE", responseHandler));}unsigned RTSPClient::sendOptionsCommand(responseHandler* responseHandler, Authenticator* authenticator) {  if (authenticator != NULL) fCurrentAuthenticator = *authenticator;  return sendRequest(new RequestRecord(++fCSeq, "OPTIONS", responseHandler));}unsigned RTSPClient::sendAnnounceCommand(char const* sdpDescription, responseHandler* responseHandler, Authenticator* authenticator) {  if (authenticator != NULL) fCurrentAuthenticator = *authenticator;  return sendRequest(new RequestRecord(++fCSeq, "ANNOUNCE", responseHandler, NULL, NULL, False, 0.0, 0.0, 0.0, sdpDescription));}unsigned RTSPClient::sendSetupCommand(MediaSubsession& subsession, responseHandler* responseHandler,                                      Boolean streamOutgoing, Boolean streamUsingTCP, Boolean forceMulticastOnUnspecified,				      Authenticator* authenticator) {  if (fTunnelOverHTTPPortNum != 0) streamUsingTCP = True; // RTSP-over-HTTP tunneling uses TCP (by definition)  if (authenticator != NULL) fCurrentAuthenticator = *authenticator;  u_int32_t booleanFlags = 0;  if (streamUsingTCP) booleanFlags |= 0x1;  if (streamOutgoing) booleanFlags |= 0x2;  if (forceMulticastOnUnspecified) booleanFlags |= 0x4;  return sendRequest(new RequestRecord(++fCSeq, "SETUP", responseHandler, NULL, &subsession, booleanFlags));}unsigned RTSPClient::sendPlayCommand(MediaSession& session, responseHandler* responseHandler,                                     double start, double end, float scale,                                     Authenticator* authenticator) {  if (authenticator != NULL) fCurrentAuthenticator = *authenticator;  return sendRequest(new RequestRecord(++fCSeq, "PLAY", responseHandler, &session, NULL, 0, start, end, scale));}unsigned RTSPClient::sendPlayCommand(MediaSubsession& subsession, responseHandler* responseHandler,                                     double start, double end, float scale,                                     Authenticator* authenticator) {  if (authenticator != NULL) fCurrentAuthenticator = *authenticator;  return sendRequest(new RequestRecord(++fCSeq, "PLAY", responseHandler, NULL, &subsession, 0, start, end, scale));}unsigned RTSPClient::sendPauseCommand(MediaSession& session, responseHandler* responseHandler, Authenticator* authenticator) {  if (authenticator != NULL) fCurrentAuthenticator = *authenticator;  return sendRequest(new RequestRecord(++fCSeq, "PAUSE", responseHandler, &session));}unsigned RTSPClient::sendPauseCommand(MediaSubsession& subsession, responseHandler* responseHandler, Authenticator* authenticator) {  if (authenticator != NULL) fCurrentAuthenticator = *authenticator;  return sendRequest(new RequestRecord(++fCSeq, "PAUSE", responseHandler, NULL, &subsession));}unsigned RTSPClient::sendRecordCommand(MediaSession& session, responseHandler* responseHandler, Authenticator* authenticator) {  if (authenticator != NULL) fCurrentAuthenticator = *authenticator;  return sendRequest(new RequestRecord(++fCSeq, "RECORD", responseHandler, &session));}unsigned RTSPClient::sendRecordCommand(MediaSubsession& subsession, responseHandler* responseHandler, Authenticator* authenticator) {  if (authenticator != NULL) fCurrentAuthenticator = *authenticator;  return sendRequest(new RequestRecord(++fCSeq, "RECORD", responseHandler, NULL, &subsession));}unsigned RTSPClient::sendTeardownCommand(MediaSession& session, responseHandler* responseHandler, Authenticator* authenticator) {  if (authenticator != NULL) fCurrentAuthenticator = *authenticator;  return sendRequest(new RequestRecord(++fCSeq, "TEARDOWN", responseHandler, &session));}unsigned RTSPClient::sendTeardownCommand(MediaSubsession& subsession, responseHandler* responseHandler, Authenticator* authenticator) {  if (authenticator != NULL) fCurrentAuthenticator = *authenticator;  return sendRequest(new RequestRecord(++fCSeq, "TEARDOWN", responseHandler, NULL, &subsession));}unsigned RTSPClient::sendSetParameterCommand(MediaSession& session, responseHandler* responseHandler,                                             char const* parameterName, char const* parameterValue,                                             Authenticator* authenticator) {  if (authenticator != NULL) fCurrentAuthenticator = *authenticator;  char* paramString = new char[strlen(parameterName) + strlen(parameterValue) + 10];  sprintf(paramString, "%s: %s\r\n", parameterName, parameterValue);  unsigned result = sendRequest(new RequestRecord(++fCSeq, "SET_PARAMETER", responseHandler, &session, NULL, False, 0.0, 0.0, 0.0, paramString));  delete[] paramString;  return result;}unsigned RTSPClient::sendGetParameterCommand(MediaSession& session, responseHandler* responseHandler, char const* parameterName,                                             Authenticator* authenticator) {  if (authenticator != NULL) fCurrentAuthenticator = *authenticator;  // We assume that:  //    parameterName is NULL means: Send no body in the request.  //    parameterName is "" means: Send only \r\n in the request body.    //    parameterName is non-empty means: Send "<parameterName>\r\n" as the request body.    unsigned parameterNameLen = parameterName == NULL ? 0 : strlen(parameterName);  char* paramString = new char[parameterNameLen + 3]; // the 3 is for \r\n + the '\0' byte  if (parameterName == NULL) {    paramString[0] = '\0';  } else {    sprintf(paramString, "%s\r\n", parameterName);  }  unsigned result = sendRequest(new RequestRecord(++fCSeq, "GET_PARAMETER", responseHandler, &session, NULL, False, 0.0, 0.0, 0.0, paramString));  delete[] paramString;  return result;}Boolean RTSPClient::changeResponseHandler(unsigned cseq, responseHandler* newResponseHandler) {   // Look for the matching request record in each of our 'pending requests' queues:  RequestRecord* request;  if ((request = fRequestsAwaitingConnection.findByCSeq(cseq)) != NULL      || (request = fRequestsAwaitingHTTPTunneling.findByCSeq(cseq)) != NULL      || (request = fRequestsAwaitingResponse.findByCSeq(cseq)) != NULL) {    request->handler() = newResponseHandler;    return True;  }  return False;}Boolean RTSPClient::lookupByName(UsageEnvironment& env,				 char const* instanceName,				 RTSPClient*& resultClient) {  resultClient = NULL; // unless we succeed  Medium* medium;  if (!Medium::lookupByName(env, instanceName, medium)) return False;  if (!medium->isRTSPClient()) {    env.setResultMsg(instanceName, " is not a RTSP client");    return False;  }  resultClient = (RTSPClient*)medium;  return True;}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>]@"    // (Note that this code fails if <password> contains '@' or '/', but    // given that these characters can also appear in <etc>, there seems to    // be no way of unambiguously parsing that situation.)    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;}void RTSPClient::setUserAgentString(char const* userAgentName) {  if (userAgentName == NULL) return;  // Change the existing user agent header string:  char const* const formatStr = "User-Agent: %s\r\n";  unsigned const headerSize = strlen(formatStr) + strlen(userAgentName);  delete[] fUserAgentHeaderStr;  fUserAgentHeaderStr = new char[headerSize];  sprintf(fUserAgentHeaderStr, formatStr, userAgentName);  fUserAgentHeaderStrLen = strlen(fUserAgentHeaderStr);}unsigned RTSPClient::responseBufferSize = 20000; // default value; you can reassign this in your application if you need toRTSPClient::RTSPClient(UsageEnvironment& env, char const* rtspURL,		       int verbosityLevel, char const* applicationName,		       portNumBits tunnelOverHTTPPortNum)  : Medium(env),    fVerbosityLevel(verbosityLevel), fTunnelOverHTTPPortNum(tunnelOverHTTPPortNum),    fUserAgentHeaderStr(NULL), fUserAgentHeaderStrLen(0), fInputSocketNum(-1), fOutputSocketNum(-1), fServerAddress(0), fCSeq(1),    fBaseURL(NULL), fTCPStreamIdCount(0), fLastSessionId(NULL), fSessionTimeoutParameter(0),    fSessionCookieCounter(0), fHTTPTunnelingConnectionIsPending(False) {  setBaseURL(rtspURL);  fResponseBuffer = new char[responseBufferSize+1];  resetResponseBuffer();  // Set the "User-Agent:" header to use in each request:  char const* const libName = "LIVE555 Streaming Media v";  char const* const libVersionStr = LIVEMEDIA_LIBRARY_VERSION_STRING;  char const* libPrefix; char const* libSuffix;  if (applicationName == NULL || applicationName[0] == '\0') {    applicationName = libPrefix = libSuffix = "";  } else {    libPrefix = " (";    libSuffix = ")";  }  unsigned userAgentNameSize    = strlen(applicationName) + strlen(libPrefix) + strlen(libName) + strlen(libVersionStr) + strlen(libSuffix) + 1;

⌨️ 快捷键说明

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