Advertisement
Guest User

Untitled

a guest
Jul 29th, 2017
81
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 8.65 KB | None | 0 0
  1. env->taskScheduler().doEventLoop();
  2.  
  3. #include "liveMedia.hh"
  4. #include "BasicUsageEnvironment.hh"
  5.  
  6. #include "logger.h"
  7. using namespace ModernCppCI;
  8.  
  9. char const* progName;
  10. UsageEnvironment* env;
  11. UserAuthenticationDatabase* authDB = NULL;
  12. UserAuthenticationDatabase* authDBForREGISTER = NULL;
  13.  
  14. // Default values of command-line parameters:
  15. int verbosityLevel = 0;
  16. Boolean streamRTPOverTCP = False;
  17. portNumBits tunnelOverHTTPPortNum = 0;
  18. portNumBits rtspServerPortNum = 554;
  19. char* username = NULL;
  20. char* password = NULL;
  21. Boolean proxyREGISTERRequests = False;
  22. char* usernameForREGISTER = NULL;
  23. char* passwordForREGISTER = NULL;
  24.  
  25. static RTSPServer* createRTSPServer(Port port) {
  26. if (proxyREGISTERRequests) {
  27. return RTSPServerWithREGISTERProxying::createNew(*env, port, authDB, authDBForREGISTER, 65, streamRTPOverTCP, verbosityLevel);
  28. } else {
  29. return RTSPServer::createNew(*env, port, authDB);
  30. }
  31. }
  32.  
  33.  
  34.  
  35. void usage(Logger log) {
  36. log.error( "nUsage: {} <Options>"
  37. "nn ** Options:"
  38. "nt[-v|-V]: Verbose | More verbose output"
  39. "nt[-t|-T <http-port>]: Stream over TCP | HTTP"
  40. "nt[-p <rtspServer-port>]: Specify server port number"
  41. "nt[-u <username> <password>]: User/Pass for login if the back-end requires authentication"
  42. "nt[-R] [-U <username-for-REGISTER> <password-for-REGISTER>]: Register for the next authentication"
  43. "nt<rtsp-url-1> ... <rtsp-url-n>: RTSP links input for restreamn"
  44. ,progName);
  45. exit(1);
  46. }
  47.  
  48. int main(int argc, char** argv) {
  49. Logger::level(LogLevel::trace);
  50. Logger log{__func__};
  51.  
  52. // Increase the maximum size of video frames that we can 'proxy' without truncation.
  53. // (Such frames are unreasonably large; the back-end servers should really not be sending frames this large!)
  54. OutPacketBuffer::maxSize = 100000; // bytes
  55.  
  56. // Begin by setting up our usage environment:
  57. TaskScheduler* scheduler = BasicTaskScheduler::createNew();
  58. env = BasicUsageEnvironment::createNew(*scheduler);
  59.  
  60. log.info("LIVE555 Proxy Server - version {}n", LIVEMEDIA_LIBRARY_VERSION_STRING);
  61.  
  62. // Check command-line arguments: optional parameters, then one or more rtsp:// URLs (of streams to be proxied):
  63. progName = argv[0];
  64. if (argc < 2) usage(log);
  65. while (argc > 1) {
  66. // Process initial command-line options (beginning with "-"):
  67. char* const opt = argv[1];
  68. if (opt[0] != '-') break; // the remaining parameters are assumed to be "rtsp://" URLs
  69.  
  70. switch (opt[1]) {
  71. case 'v': { // verbose output
  72. verbosityLevel = 1;
  73. break;
  74. }
  75.  
  76. case 'V': { // more verbose output
  77. verbosityLevel = 2;
  78. break;
  79. }
  80.  
  81. case 't': {
  82. // Stream RTP and RTCP over the TCP 'control' connection.
  83. // (This is for the 'back end' (i.e., proxied) stream only.)
  84. streamRTPOverTCP = True;
  85. break;
  86. }
  87.  
  88. case 'T': {
  89. // Stream RTP and RTCP over a HTTP connection
  90. if (argc > 2 && argv[2][0] != '-') {
  91. // The next argument is the HTTP server port number:
  92. if (sscanf(argv[2], "%hu", &tunnelOverHTTPPortNum) == 1 && tunnelOverHTTPPortNum > 0) {
  93. ++argv; --argc;
  94. break;
  95. }
  96. }
  97.  
  98. // If we get here, the option was specified incorrectly:
  99. usage(log);
  100. break;
  101. }
  102.  
  103. case 'p': {
  104. // specify a rtsp server port number
  105. if (argc > 2 && argv[2][0] != '-') {
  106. // The next argument is the rtsp server port number:
  107. if (sscanf(argv[2], "%hu", &rtspServerPortNum) == 1 && rtspServerPortNum > 0) {
  108. ++argv; --argc;
  109. break;
  110. }
  111. }
  112.  
  113. // If we get here, the option was specified incorrectly:
  114. usage(log);
  115. break;
  116. }
  117.  
  118. case 'u': { // specify a username and password (to be used if the 'back end' (i.e., proxied) stream requires authentication)
  119. if (argc < 4) usage(log); // there's no argv[3] (for the "password")
  120. username = argv[2];
  121. password = argv[3];
  122. argv += 2; argc -= 2;
  123. break;
  124. }
  125.  
  126. case 'U': { // specify a username and password to use to authenticate incoming "REGISTER" commands
  127. if (argc < 4) usage(log); // there's no argv[3] (for the "password")
  128. usernameForREGISTER = argv[2];
  129. passwordForREGISTER = argv[3];
  130.  
  131. if (authDBForREGISTER == NULL) authDBForREGISTER = new UserAuthenticationDatabase;
  132. authDBForREGISTER->addUserRecord(usernameForREGISTER, passwordForREGISTER);
  133. argv += 2; argc -= 2;
  134. break;
  135. }
  136.  
  137. case 'R': { // Handle incoming "REGISTER" requests by proxying the specified stream:
  138. proxyREGISTERRequests = True;
  139. break;
  140. }
  141.  
  142. default: {
  143. usage(log);
  144. break;
  145. }
  146. }
  147.  
  148. ++argv; --argc;
  149. }
  150. if (argc < 2 && !proxyREGISTERRequests) usage(log); // there must be at least one "rtsp://" URL at the end
  151.  
  152. // Make sure that the remaining arguments appear to be "rtsp://" URLs:
  153. int i;
  154. for (i = 1; i < argc; ++i) {
  155. if (strncmp(argv[i], "rtsp://", 7) != 0) usage(log);
  156. }
  157.  
  158. // Do some additional checking for invalid command-line argument combinations:
  159. if (authDBForREGISTER != NULL && !proxyREGISTERRequests) {
  160. log.error("The '-U <username> <password>' option can be used only with -Rn");
  161. usage(log);
  162. }
  163.  
  164. if (streamRTPOverTCP) {
  165. if (tunnelOverHTTPPortNum > 0) {
  166. log.error("The -t and -T options cannot both be used!n");
  167. usage(log);
  168. }
  169. else {
  170. tunnelOverHTTPPortNum = (portNumBits)(~0); // hack to tell "ProxyServerMediaSession" to stream over TCP, but not using HTTP
  171. }
  172. }
  173.  
  174. #ifdef ACCESS_CONTROL
  175. // To implement client access control to the RTSP server, do the following:
  176. authDB = new UserAuthenticationDatabase;
  177. authDB->addUserRecord("username1", "password1"); // replace these with real strings
  178. // Repeat this line with each <username>, <password> that you wish to allow access to the server.
  179. #endif
  180.  
  181. // Create the RTSP server. Try first with the configured port number,
  182. // and then with the default port number (554) if different,
  183. // and then with the alternative port number (8554):
  184. RTSPServer* rtspServer;
  185. rtspServer = createRTSPServer(rtspServerPortNum);
  186. if (rtspServer == NULL) {
  187. if (rtspServerPortNum != 554) {
  188. log.error("Unable to create a RTSP server with port number {}: {}n", rtspServerPortNum, env->getResultMsg());
  189. log.trace("Trying instead with the standard port numbers (554 and 8554)...n");
  190.  
  191. rtspServerPortNum = 554;
  192. rtspServer = createRTSPServer(rtspServerPortNum);
  193. }
  194. }
  195.  
  196. if (rtspServer == NULL) {
  197. rtspServerPortNum = 8554;
  198. rtspServer = createRTSPServer(rtspServerPortNum);
  199. }
  200.  
  201. if (rtspServer == NULL) {
  202. log.error("Failed to create RTSP server: {}n", env->getResultMsg());
  203. exit(1);
  204. }
  205.  
  206. // Create a proxy for each "rtsp://" URL specified on the command line:
  207. for (i = 1; i < argc; ++i) {
  208. char const* proxiedStreamURL = argv[i];
  209. char streamName[30];
  210. if (argc == 2) {
  211. sprintf(streamName, "%s", "proxyStream"); // there's just one stream; give it this name
  212. }
  213. else {
  214. sprintf(streamName, "proxyStream-%d", i); // there's more than one stream; distinguish them by name
  215. }
  216. ServerMediaSession* sms = ProxyServerMediaSession::createNew( *env, rtspServer,
  217. proxiedStreamURL, streamName,
  218. username, password,
  219. tunnelOverHTTPPortNum, verbosityLevel);
  220. rtspServer->addServerMediaSession(sms);
  221.  
  222. char* proxyStreamURL = rtspServer->rtspURL(sms);
  223. log.trace("RTSP stream source: {}n", proxiedStreamURL);
  224. log.trace("Play this stream using the URL: {}n", proxyStreamURL);
  225. delete[] proxyStreamURL;
  226. }
  227.  
  228. if (proxyREGISTERRequests) {
  229. log.info("Incoming "REGISTER" requests is handled on port {}n", rtspServerPortNum);
  230. }
  231.  
  232. // Also, attempt to create a HTTP server for RTSP-over-HTTP tunneling.
  233. // Try first with the default HTTP port (80), and then with the alternative HTTP
  234. // port numbers (8000 and 8080).
  235.  
  236. if (rtspServer->setUpTunnelingOverHTTP(80) || rtspServer->setUpTunnelingOverHTTP(8000) || rtspServer->setUpTunnelingOverHTTP(8080)) {
  237. log.info("Port {} is used for optional RTSP-over-HTTP tunneling", rtspServer->httpServerPortNum());
  238. }
  239. else {
  240. log.trace("nRTSP-over-HTTP tunneling is not available");
  241. }
  242.  
  243. // Now, enter the event loop:
  244. env->taskScheduler().doEventLoop(); // does not return
  245.  
  246. return 0; // only to prevent compiler warning
  247. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement