proxyServer/live555ProxyServer.cpp

Go to the documentation of this file.
00001 /**********
00002 This library is free software; you can redistribute it and/or modify it under
00003 the terms of the GNU Lesser General Public License as published by the
00004 Free Software Foundation; either version 2.1 of the License, or (at your
00005 option) any later version. (See <http://www.gnu.org/copyleft/lesser.html>.)
00006 
00007 This library is distributed in the hope that it will be useful, but WITHOUT
00008 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
00009 FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for
00010 more details.
00011 
00012 You should have received a copy of the GNU Lesser General Public License
00013 along with this library; if not, write to the Free Software Foundation, Inc.,
00014 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA
00015 **********/
00016 // Copyright (c) 1996-2013, Live Networks, Inc.  All rights reserved
00017 // LIVE555 Proxy Server
00018 // main program
00019 
00020 #include "liveMedia.hh"
00021 #include "BasicUsageEnvironment.hh"
00022 
00023 char const* progName;
00024 UsageEnvironment* env;
00025 
00026 // Default values of command-line parameters:
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   // Increase the maximum size of video frames that we can 'proxy' without truncation.
00044   // (Such frames are unreasonably large; the back-end servers should really not be sending frames this large!)
00045   OutPacketBuffer::maxSize = 100000; // bytes
00046 
00047   // Begin by setting up our usage environment:
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   // Check command-line arguments: optional parameters, then one or more rtsp:// URLs (of streams to be proxied):
00056   progName = argv[0];
00057   if (argc < 2) usage();
00058   while (argc > 1) {
00059     // Process initial command-line options (beginning with "-"):
00060     char* const opt = argv[1];
00061     if (opt[0] != '-') break; // the remaining parameters are assumed to be "rtsp://" URLs
00062 
00063     switch (opt[1]) {
00064     case 'v': { // verbose output
00065       verbosityLevel = 1;
00066       break;
00067     }
00068 
00069     case 'V': { // more verbose output
00070       verbosityLevel = 2;
00071       break;
00072     }
00073 
00074     case 't': {
00075       // Stream RTP and RTCP over the TCP 'control' connection.
00076       // (This is for the 'back end' (i.e., proxied) stream only.)
00077       streamRTPOverTCP = True;
00078       break;
00079     }
00080 
00081     case 'T': {
00082       // stream RTP and RTCP over a HTTP connection
00083       if (argc > 3 && argv[2][0] != '-') {
00084         // The next argument is the HTTP server port number:                                                                       
00085         if (sscanf(argv[2], "%hu", &tunnelOverHTTPPortNum) == 1
00086             && tunnelOverHTTPPortNum > 0) {
00087           ++argv; --argc;
00088           break;
00089         }
00090       }
00091 
00092       // If we get here, the option was specified incorrectly:
00093       usage();
00094       break;
00095     }
00096 
00097     case 'u': { // specify a username and password (to be used if the 'back end' (i.e., proxied) stream requires authentication)
00098       if (argc < 4) usage(); // there's no argv[3] (for the "password")
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(); // there must be at least one "rtsp://" URL at the end 
00114   // Make sure that the remaining arguments appear to be "rtsp://" URLs:
00115   int i;
00116   for (i = 1; i < argc; ++i) {
00117     if (strncmp(argv[i], "rtsp://", 7) != 0) usage();
00118   }
00119   // Do some additional checking for invalid command-line argument combinations:
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); // hack to tell "ProxyServerMediaSession" to stream over TCP, but not using HTTP
00126     }
00127   }
00128 
00129   UserAuthenticationDatabase* authDB = NULL;
00130 #ifdef ACCESS_CONTROL
00131   // To implement client access control to the RTSP server, do the following:
00132   authDB = new UserAuthenticationDatabase;
00133   authDB->addUserRecord("username1", "password1"); // replace these with real strings
00134   // Repeat the above with each <username>, <password> that you wish to allow
00135   // access to the server.
00136 #endif
00137 
00138   // Create the RTSP server.  Try first with the default port number (554),
00139   // and then with the alternative port number (8554):
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   // Create a proxy for each "rtsp://" URL specified on the command line:
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"); // there's just one stream; give it this name
00158     } else {
00159       sprintf(streamName, "proxyStream-%d", i); // there's more than one stream; distinguish them by name
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   // Also, attempt to create a HTTP server for RTSP-over-HTTP tunneling.
00174   // Try first with the default HTTP port (80), and then with the alternative HTTP
00175   // port numbers (8000 and 8080).
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   // Now, enter the event loop:
00184   env->taskScheduler().doEventLoop(); // does not return
00185 
00186   return 0; // only to prevent compiler warning
00187 }

Generated on Mon Apr 29 13:28:03 2013 for live by  doxygen 1.5.2