Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- env->taskScheduler().doEventLoop();
- #include "liveMedia.hh"
- #include "BasicUsageEnvironment.hh"
- #include "logger.h"
- using namespace ModernCppCI;
- char const* progName;
- UsageEnvironment* env;
- UserAuthenticationDatabase* authDB = NULL;
- UserAuthenticationDatabase* authDBForREGISTER = NULL;
- // Default values of command-line parameters:
- int verbosityLevel = 0;
- Boolean streamRTPOverTCP = False;
- portNumBits tunnelOverHTTPPortNum = 0;
- portNumBits rtspServerPortNum = 554;
- char* username = NULL;
- char* password = NULL;
- Boolean proxyREGISTERRequests = False;
- char* usernameForREGISTER = NULL;
- char* passwordForREGISTER = NULL;
- static RTSPServer* createRTSPServer(Port port) {
- if (proxyREGISTERRequests) {
- return RTSPServerWithREGISTERProxying::createNew(*env, port, authDB, authDBForREGISTER, 65, streamRTPOverTCP, verbosityLevel);
- } else {
- return RTSPServer::createNew(*env, port, authDB);
- }
- }
- void usage(Logger log) {
- log.error( "nUsage: {} <Options>"
- "nn ** Options:"
- "nt[-v|-V]: Verbose | More verbose output"
- "nt[-t|-T <http-port>]: Stream over TCP | HTTP"
- "nt[-p <rtspServer-port>]: Specify server port number"
- "nt[-u <username> <password>]: User/Pass for login if the back-end requires authentication"
- "nt[-R] [-U <username-for-REGISTER> <password-for-REGISTER>]: Register for the next authentication"
- "nt<rtsp-url-1> ... <rtsp-url-n>: RTSP links input for restreamn"
- ,progName);
- exit(1);
- }
- int main(int argc, char** argv) {
- Logger::level(LogLevel::trace);
- Logger log{__func__};
- // Increase the maximum size of video frames that we can 'proxy' without truncation.
- // (Such frames are unreasonably large; the back-end servers should really not be sending frames this large!)
- OutPacketBuffer::maxSize = 100000; // bytes
- // Begin by setting up our usage environment:
- TaskScheduler* scheduler = BasicTaskScheduler::createNew();
- env = BasicUsageEnvironment::createNew(*scheduler);
- log.info("LIVE555 Proxy Server - version {}n", LIVEMEDIA_LIBRARY_VERSION_STRING);
- // Check command-line arguments: optional parameters, then one or more rtsp:// URLs (of streams to be proxied):
- progName = argv[0];
- if (argc < 2) usage(log);
- while (argc > 1) {
- // Process initial command-line options (beginning with "-"):
- char* const opt = argv[1];
- if (opt[0] != '-') break; // the remaining parameters are assumed to be "rtsp://" URLs
- switch (opt[1]) {
- case 'v': { // verbose output
- verbosityLevel = 1;
- break;
- }
- case 'V': { // more verbose output
- verbosityLevel = 2;
- break;
- }
- case 't': {
- // Stream RTP and RTCP over the TCP 'control' connection.
- // (This is for the 'back end' (i.e., proxied) stream only.)
- streamRTPOverTCP = True;
- break;
- }
- case 'T': {
- // Stream RTP and RTCP over a HTTP connection
- if (argc > 2 && argv[2][0] != '-') {
- // The next argument is the HTTP server port number:
- if (sscanf(argv[2], "%hu", &tunnelOverHTTPPortNum) == 1 && tunnelOverHTTPPortNum > 0) {
- ++argv; --argc;
- break;
- }
- }
- // If we get here, the option was specified incorrectly:
- usage(log);
- break;
- }
- case 'p': {
- // specify a rtsp server port number
- if (argc > 2 && argv[2][0] != '-') {
- // The next argument is the rtsp server port number:
- if (sscanf(argv[2], "%hu", &rtspServerPortNum) == 1 && rtspServerPortNum > 0) {
- ++argv; --argc;
- break;
- }
- }
- // If we get here, the option was specified incorrectly:
- usage(log);
- break;
- }
- case 'u': { // specify a username and password (to be used if the 'back end' (i.e., proxied) stream requires authentication)
- if (argc < 4) usage(log); // there's no argv[3] (for the "password")
- username = argv[2];
- password = argv[3];
- argv += 2; argc -= 2;
- break;
- }
- case 'U': { // specify a username and password to use to authenticate incoming "REGISTER" commands
- if (argc < 4) usage(log); // there's no argv[3] (for the "password")
- usernameForREGISTER = argv[2];
- passwordForREGISTER = argv[3];
- if (authDBForREGISTER == NULL) authDBForREGISTER = new UserAuthenticationDatabase;
- authDBForREGISTER->addUserRecord(usernameForREGISTER, passwordForREGISTER);
- argv += 2; argc -= 2;
- break;
- }
- case 'R': { // Handle incoming "REGISTER" requests by proxying the specified stream:
- proxyREGISTERRequests = True;
- break;
- }
- default: {
- usage(log);
- break;
- }
- }
- ++argv; --argc;
- }
- if (argc < 2 && !proxyREGISTERRequests) usage(log); // there must be at least one "rtsp://" URL at the end
- // Make sure that the remaining arguments appear to be "rtsp://" URLs:
- int i;
- for (i = 1; i < argc; ++i) {
- if (strncmp(argv[i], "rtsp://", 7) != 0) usage(log);
- }
- // Do some additional checking for invalid command-line argument combinations:
- if (authDBForREGISTER != NULL && !proxyREGISTERRequests) {
- log.error("The '-U <username> <password>' option can be used only with -Rn");
- usage(log);
- }
- if (streamRTPOverTCP) {
- if (tunnelOverHTTPPortNum > 0) {
- log.error("The -t and -T options cannot both be used!n");
- usage(log);
- }
- else {
- tunnelOverHTTPPortNum = (portNumBits)(~0); // hack to tell "ProxyServerMediaSession" to stream over TCP, but not using HTTP
- }
- }
- #ifdef ACCESS_CONTROL
- // To implement client access control to the RTSP server, do the following:
- authDB = new UserAuthenticationDatabase;
- authDB->addUserRecord("username1", "password1"); // replace these with real strings
- // Repeat this line with each <username>, <password> that you wish to allow access to the server.
- #endif
- // Create the RTSP server. Try first with the configured port number,
- // and then with the default port number (554) if different,
- // and then with the alternative port number (8554):
- RTSPServer* rtspServer;
- rtspServer = createRTSPServer(rtspServerPortNum);
- if (rtspServer == NULL) {
- if (rtspServerPortNum != 554) {
- log.error("Unable to create a RTSP server with port number {}: {}n", rtspServerPortNum, env->getResultMsg());
- log.trace("Trying instead with the standard port numbers (554 and 8554)...n");
- rtspServerPortNum = 554;
- rtspServer = createRTSPServer(rtspServerPortNum);
- }
- }
- if (rtspServer == NULL) {
- rtspServerPortNum = 8554;
- rtspServer = createRTSPServer(rtspServerPortNum);
- }
- if (rtspServer == NULL) {
- log.error("Failed to create RTSP server: {}n", env->getResultMsg());
- exit(1);
- }
- // Create a proxy for each "rtsp://" URL specified on the command line:
- for (i = 1; i < argc; ++i) {
- char const* proxiedStreamURL = argv[i];
- char streamName[30];
- if (argc == 2) {
- sprintf(streamName, "%s", "proxyStream"); // there's just one stream; give it this name
- }
- else {
- sprintf(streamName, "proxyStream-%d", i); // there's more than one stream; distinguish them by name
- }
- ServerMediaSession* sms = ProxyServerMediaSession::createNew( *env, rtspServer,
- proxiedStreamURL, streamName,
- username, password,
- tunnelOverHTTPPortNum, verbosityLevel);
- rtspServer->addServerMediaSession(sms);
- char* proxyStreamURL = rtspServer->rtspURL(sms);
- log.trace("RTSP stream source: {}n", proxiedStreamURL);
- log.trace("Play this stream using the URL: {}n", proxyStreamURL);
- delete[] proxyStreamURL;
- }
- if (proxyREGISTERRequests) {
- log.info("Incoming "REGISTER" requests is handled on port {}n", rtspServerPortNum);
- }
- // Also, attempt to create a HTTP server for RTSP-over-HTTP tunneling.
- // Try first with the default HTTP port (80), and then with the alternative HTTP
- // port numbers (8000 and 8080).
- if (rtspServer->setUpTunnelingOverHTTP(80) || rtspServer->setUpTunnelingOverHTTP(8000) || rtspServer->setUpTunnelingOverHTTP(8080)) {
- log.info("Port {} is used for optional RTSP-over-HTTP tunneling", rtspServer->httpServerPortNum());
- }
- else {
- log.trace("nRTSP-over-HTTP tunneling is not available");
- }
- // Now, enter the event loop:
- env->taskScheduler().doEventLoop(); // does not return
- return 0; // only to prevent compiler warning
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement