00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "liveMedia.hh"
00021 #include "BasicUsageEnvironment.hh"
00022
00023 char const* progName;
00024 UsageEnvironment* env;
00025
00026
00027 int verbosityLevel = 0;
00028 Boolean streamRTPOverTCP = False;
00029 portNumBits tunnelOverHTTPPortNum = 0;
00030 char* username = NULL;
00031 char* password = NULL;
00032
00033 void usage() {
00034 *env << "Usage: " << progName
00035 << " [-v|-V]"
00036 << " [-t|-T <http-port>]"
00037 << " [-u <username> <password>]"
00038 << " <rtsp-url-1> ... <rtsp-url-n>\n";
00039 exit(1);
00040 }
00041
00042 int main(int argc, char** argv) {
00043
00044
00045 OutPacketBuffer::maxSize = 100000;
00046
00047
00048 TaskScheduler* scheduler = BasicTaskScheduler::createNew();
00049 env = BasicUsageEnvironment::createNew(*scheduler);
00050
00051 *env << "LIVE555 Proxy Server\n"
00052 << "\t(LIVE555 Streaming Media library version "
00053 << LIVEMEDIA_LIBRARY_VERSION_STRING << ")\n\n";
00054
00055
00056 progName = argv[0];
00057 if (argc < 2) usage();
00058 while (argc > 1) {
00059
00060 char* const opt = argv[1];
00061 if (opt[0] != '-') break;
00062
00063 switch (opt[1]) {
00064 case 'v': {
00065 verbosityLevel = 1;
00066 break;
00067 }
00068
00069 case 'V': {
00070 verbosityLevel = 2;
00071 break;
00072 }
00073
00074 case 't': {
00075
00076
00077 streamRTPOverTCP = True;
00078 break;
00079 }
00080
00081 case 'T': {
00082
00083 if (argc > 3 && argv[2][0] != '-') {
00084
00085 if (sscanf(argv[2], "%hu", &tunnelOverHTTPPortNum) == 1
00086 && tunnelOverHTTPPortNum > 0) {
00087 ++argv; --argc;
00088 break;
00089 }
00090 }
00091
00092
00093 usage();
00094 break;
00095 }
00096
00097 case 'u': {
00098 if (argc < 4) usage();
00099 username = argv[2];
00100 password = argv[3];
00101 argv += 2; argc -= 2;
00102 break;
00103 }
00104
00105 default: {
00106 usage();
00107 break;
00108 }
00109 }
00110
00111 ++argv; --argc;
00112 }
00113 if (argc < 2) usage();
00114
00115 int i;
00116 for (i = 1; i < argc; ++i) {
00117 if (strncmp(argv[i], "rtsp://", 7) != 0) usage();
00118 }
00119
00120 if (streamRTPOverTCP) {
00121 if (tunnelOverHTTPPortNum > 0) {
00122 *env << "The -t and -T options cannot both be used!\n";
00123 usage();
00124 } else {
00125 tunnelOverHTTPPortNum = (portNumBits)(~0);
00126 }
00127 }
00128
00129 UserAuthenticationDatabase* authDB = NULL;
00130 #ifdef ACCESS_CONTROL
00131
00132 authDB = new UserAuthenticationDatabase;
00133 authDB->addUserRecord("username1", "password1");
00134
00135
00136 #endif
00137
00138
00139
00140 RTSPServer* rtspServer;
00141 portNumBits rtspServerPortNum = 554;
00142 rtspServer = RTSPServer::createNew(*env, rtspServerPortNum, authDB);
00143 if (rtspServer == NULL) {
00144 rtspServerPortNum = 8554;
00145 rtspServer = RTSPServer::createNew(*env, rtspServerPortNum, authDB);
00146 }
00147 if (rtspServer == NULL) {
00148 *env << "Failed to create RTSP server: " << env->getResultMsg() << "\n";
00149 exit(1);
00150 }
00151
00152
00153 for (i = 1; i < argc; ++i) {
00154 char const* proxiedStreamURL = argv[i];
00155 char streamName[30];
00156 if (argc == 2) {
00157 sprintf(streamName, "%s", "proxyStream");
00158 } else {
00159 sprintf(streamName, "proxyStream-%d", i);
00160 }
00161 ServerMediaSession* sms
00162 = ProxyServerMediaSession::createNew(*env, rtspServer,
00163 proxiedStreamURL, streamName,
00164 username, password, tunnelOverHTTPPortNum, verbosityLevel);
00165 rtspServer->addServerMediaSession(sms);
00166
00167 char* proxyStreamURL = rtspServer->rtspURL(sms);
00168 *env << "RTSP stream, proxying the stream \"" << proxiedStreamURL << "\"\n";
00169 *env << "\tPlay this stream using the URL: " << proxyStreamURL << "\n";
00170 delete[] proxyStreamURL;
00171 }
00172
00173
00174
00175
00176
00177 if (rtspServer->setUpTunnelingOverHTTP(80) || rtspServer->setUpTunnelingOverHTTP(8000) || rtspServer->setUpTunnelingOverHTTP(8080)) {
00178 *env << "\n(We use port " << rtspServer->httpServerPortNum() << " for optional RTSP-over-HTTP tunneling.)\n";
00179 } else {
00180 *env << "\n(RTSP-over-HTTP tunneling is not available.)\n";
00181 }
00182
00183
00184 env->taskScheduler().doEventLoop();
00185
00186 return 0;
00187 }