00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "liveMedia.hh"
00022 #include "BasicUsageEnvironment.hh"
00023
00024 UsageEnvironment* env;
00025
00026
00027
00028
00029 Boolean reuseFirstSource = False;
00030
00031
00032
00033
00034 Boolean iFramesOnly = False;
00035
00036 static void announceStream(RTSPServer* rtspServer, ServerMediaSession* sms,
00037 char const* streamName, char const* inputFileName);
00038
00039 static char newMatroskaDemuxWatchVariable;
00040 static MatroskaFileServerDemux* demux;
00041 static void onMatroskaDemuxCreation(MatroskaFileServerDemux* newDemux, void* ) {
00042 demux = newDemux;
00043 newMatroskaDemuxWatchVariable = 1;
00044 }
00045
00046 int main(int argc, char** argv) {
00047
00048 TaskScheduler* scheduler = BasicTaskScheduler::createNew();
00049 env = BasicUsageEnvironment::createNew(*scheduler);
00050
00051 UserAuthenticationDatabase* authDB = NULL;
00052 #ifdef ACCESS_CONTROL
00053
00054 authDB = new UserAuthenticationDatabase;
00055 authDB->addUserRecord("username1", "password1");
00056
00057
00058 #endif
00059
00060
00061 RTSPServer* rtspServer = RTSPServer::createNew(*env, 8554, authDB);
00062 if (rtspServer == NULL) {
00063 *env << "Failed to create RTSP server: " << env->getResultMsg() << "\n";
00064 exit(1);
00065 }
00066
00067 char const* descriptionString
00068 = "Session streamed by \"testOnDemandRTSPServer\"";
00069
00070
00071
00072
00073
00074
00075
00076 {
00077 char const* streamName = "mpeg4ESVideoTest";
00078 char const* inputFileName = "test.m4e";
00079 ServerMediaSession* sms
00080 = ServerMediaSession::createNew(*env, streamName, streamName,
00081 descriptionString);
00082 sms->addSubsession(MPEG4VideoFileServerMediaSubsession
00083 ::createNew(*env, inputFileName, reuseFirstSource));
00084 rtspServer->addServerMediaSession(sms);
00085
00086 announceStream(rtspServer, sms, streamName, inputFileName);
00087 }
00088
00089
00090 {
00091 char const* streamName = "h264ESVideoTest";
00092 char const* inputFileName = "test.264";
00093 ServerMediaSession* sms
00094 = ServerMediaSession::createNew(*env, streamName, streamName,
00095 descriptionString);
00096 sms->addSubsession(H264VideoFileServerMediaSubsession
00097 ::createNew(*env, inputFileName, reuseFirstSource));
00098 rtspServer->addServerMediaSession(sms);
00099
00100 announceStream(rtspServer, sms, streamName, inputFileName);
00101 }
00102
00103
00104 {
00105 char const* streamName = "mpeg1or2AudioVideoTest";
00106 char const* inputFileName = "test.mpg";
00107
00108 ServerMediaSession* sms
00109 = ServerMediaSession::createNew(*env, streamName, streamName,
00110 descriptionString);
00111 MPEG1or2FileServerDemux* demux
00112 = MPEG1or2FileServerDemux::createNew(*env, inputFileName, reuseFirstSource);
00113 sms->addSubsession(demux->newVideoServerMediaSubsession(iFramesOnly));
00114 sms->addSubsession(demux->newAudioServerMediaSubsession());
00115 rtspServer->addServerMediaSession(sms);
00116
00117 announceStream(rtspServer, sms, streamName, inputFileName);
00118 }
00119
00120
00121 {
00122 char const* streamName = "mpeg1or2ESVideoTest";
00123 char const* inputFileName = "testv.mpg";
00124
00125 ServerMediaSession* sms
00126 = ServerMediaSession::createNew(*env, streamName, streamName,
00127 descriptionString);
00128 sms->addSubsession(MPEG1or2VideoFileServerMediaSubsession
00129 ::createNew(*env, inputFileName, reuseFirstSource, iFramesOnly));
00130 rtspServer->addServerMediaSession(sms);
00131
00132 announceStream(rtspServer, sms, streamName, inputFileName);
00133 }
00134
00135
00136
00137
00138
00139
00140
00141
00142 {
00143 char const* streamName = "mp3AudioTest";
00144 char const* inputFileName = "test.mp3";
00145 ServerMediaSession* sms
00146 = ServerMediaSession::createNew(*env, streamName, streamName,
00147 descriptionString);
00148 Boolean useADUs = False;
00149 Interleaving* interleaving = NULL;
00150 #ifdef STREAM_USING_ADUS
00151 useADUs = True;
00152 #ifdef INTERLEAVE_ADUS
00153 unsigned char interleaveCycle[] = {0,2,1,3};
00154 unsigned const interleaveCycleSize
00155 = (sizeof interleaveCycle)/(sizeof (unsigned char));
00156 interleaving = new Interleaving(interleaveCycleSize, interleaveCycle);
00157 #endif
00158 #endif
00159 sms->addSubsession(MP3AudioFileServerMediaSubsession
00160 ::createNew(*env, inputFileName, reuseFirstSource,
00161 useADUs, interleaving));
00162 rtspServer->addServerMediaSession(sms);
00163
00164 announceStream(rtspServer, sms, streamName, inputFileName);
00165 }
00166
00167
00168 {
00169 char const* streamName = "wavAudioTest";
00170 char const* inputFileName = "test.wav";
00171 ServerMediaSession* sms
00172 = ServerMediaSession::createNew(*env, streamName, streamName,
00173 descriptionString);
00174
00175
00176 Boolean convertToULaw = False;
00177 sms->addSubsession(WAVAudioFileServerMediaSubsession
00178 ::createNew(*env, inputFileName, reuseFirstSource, convertToULaw));
00179 rtspServer->addServerMediaSession(sms);
00180
00181 announceStream(rtspServer, sms, streamName, inputFileName);
00182 }
00183
00184
00185 {
00186 char const* streamName = "amrAudioTest";
00187 char const* inputFileName = "test.amr";
00188 ServerMediaSession* sms
00189 = ServerMediaSession::createNew(*env, streamName, streamName,
00190 descriptionString);
00191 sms->addSubsession(AMRAudioFileServerMediaSubsession
00192 ::createNew(*env, inputFileName, reuseFirstSource));
00193 rtspServer->addServerMediaSession(sms);
00194
00195 announceStream(rtspServer, sms, streamName, inputFileName);
00196 }
00197
00198
00199 {
00200 char const* streamName = "vobTest";
00201 char const* inputFileName = "test.vob";
00202 ServerMediaSession* sms
00203 = ServerMediaSession::createNew(*env, streamName, streamName,
00204 descriptionString);
00205
00206 MPEG1or2FileServerDemux* demux
00207 = MPEG1or2FileServerDemux::createNew(*env, inputFileName, reuseFirstSource);
00208 sms->addSubsession(demux->newVideoServerMediaSubsession(iFramesOnly));
00209 sms->addSubsession(demux->newAC3AudioServerMediaSubsession());
00210 rtspServer->addServerMediaSession(sms);
00211
00212 announceStream(rtspServer, sms, streamName, inputFileName);
00213 }
00214
00215
00216 {
00217 char const* streamName = "mpeg2TransportStreamTest";
00218 char const* inputFileName = "test.ts";
00219 char const* indexFileName = "test.tsx";
00220 ServerMediaSession* sms
00221 = ServerMediaSession::createNew(*env, streamName, streamName,
00222 descriptionString);
00223 sms->addSubsession(MPEG2TransportFileServerMediaSubsession
00224 ::createNew(*env, inputFileName, indexFileName, reuseFirstSource));
00225 rtspServer->addServerMediaSession(sms);
00226
00227 announceStream(rtspServer, sms, streamName, inputFileName);
00228 }
00229
00230
00231 {
00232 char const* streamName = "aacAudioTest";
00233 char const* inputFileName = "test.aac";
00234 ServerMediaSession* sms
00235 = ServerMediaSession::createNew(*env, streamName, streamName,
00236 descriptionString);
00237 sms->addSubsession(ADTSAudioFileServerMediaSubsession
00238 ::createNew(*env, inputFileName, reuseFirstSource));
00239 rtspServer->addServerMediaSession(sms);
00240
00241 announceStream(rtspServer, sms, streamName, inputFileName);
00242 }
00243
00244
00245 {
00246
00247 OutPacketBuffer::maxSize = 300000;
00248
00249 char const* streamName = "dvVideoTest";
00250 char const* inputFileName = "test.dv";
00251 ServerMediaSession* sms
00252 = ServerMediaSession::createNew(*env, streamName, streamName,
00253 descriptionString);
00254 sms->addSubsession(DVVideoFileServerMediaSubsession
00255 ::createNew(*env, inputFileName, reuseFirstSource));
00256 rtspServer->addServerMediaSession(sms);
00257
00258 announceStream(rtspServer, sms, streamName, inputFileName);
00259 }
00260
00261
00262 {
00263 char const* streamName = "ac3AudioTest";
00264 char const* inputFileName = "test.ac3";
00265 ServerMediaSession* sms
00266 = ServerMediaSession::createNew(*env, streamName, streamName,
00267 descriptionString);
00268
00269 sms->addSubsession(AC3AudioFileServerMediaSubsession
00270 ::createNew(*env, inputFileName, reuseFirstSource));
00271
00272 rtspServer->addServerMediaSession(sms);
00273
00274 announceStream(rtspServer, sms, streamName, inputFileName);
00275 }
00276
00277
00278 {
00279 char const* streamName = "matroskaFileTest";
00280 char const* inputFileName = "test.mkv";
00281 ServerMediaSession* sms
00282 = ServerMediaSession::createNew(*env, streamName, streamName,
00283 descriptionString);
00284
00285 newMatroskaDemuxWatchVariable = 0;
00286 MatroskaFileServerDemux::createNew(*env, inputFileName, onMatroskaDemuxCreation, NULL);
00287 env->taskScheduler().doEventLoop(&newMatroskaDemuxWatchVariable);
00288
00289 Boolean sessionHasTracks = False;
00290 ServerMediaSubsession* smss;
00291 while ((smss = demux->newServerMediaSubsession()) != NULL) {
00292 sms->addSubsession(smss);
00293 sessionHasTracks = True;
00294 }
00295 if (sessionHasTracks) {
00296 rtspServer->addServerMediaSession(sms);
00297 }
00298
00299
00300 announceStream(rtspServer, sms, streamName, inputFileName);
00301 }
00302
00303
00304
00305 {
00306 char const* streamName = "webmFileTest";
00307 char const* inputFileName = "test.webm";
00308 ServerMediaSession* sms
00309 = ServerMediaSession::createNew(*env, streamName, streamName,
00310 descriptionString);
00311
00312 newMatroskaDemuxWatchVariable = 0;
00313 MatroskaFileServerDemux::createNew(*env, inputFileName, onMatroskaDemuxCreation, NULL);
00314 env->taskScheduler().doEventLoop(&newMatroskaDemuxWatchVariable);
00315
00316 Boolean sessionHasTracks = False;
00317 ServerMediaSubsession* smss;
00318 while ((smss = demux->newServerMediaSubsession()) != NULL) {
00319 sms->addSubsession(smss);
00320 sessionHasTracks = True;
00321 }
00322 if (sessionHasTracks) {
00323 rtspServer->addServerMediaSession(sms);
00324 }
00325
00326
00327 announceStream(rtspServer, sms, streamName, inputFileName);
00328 }
00329
00330
00331 {
00332 char const* streamName = "mpeg2TransportStreamFromUDPSourceTest";
00333 char const* inputAddressStr = "239.255.42.42";
00334
00335
00336 portNumBits const inputPortNum = 1234;
00337
00338 Boolean const inputStreamIsRawUDP = False;
00339 ServerMediaSession* sms
00340 = ServerMediaSession::createNew(*env, streamName, streamName,
00341 descriptionString);
00342 sms->addSubsession(MPEG2TransportUDPServerMediaSubsession
00343 ::createNew(*env, inputAddressStr, inputPortNum, inputStreamIsRawUDP));
00344 rtspServer->addServerMediaSession(sms);
00345
00346 char* url = rtspServer->rtspURL(sms);
00347 *env << "\n\"" << streamName << "\" stream, from a UDP Transport Stream input source \n\t(";
00348 if (inputAddressStr != NULL) {
00349 *env << "IP multicast address " << inputAddressStr << ",";
00350 } else {
00351 *env << "unicast;";
00352 }
00353 *env << " port " << inputPortNum << ")\n";
00354 *env << "Play this stream using the URL \"" << url << "\"\n";
00355 delete[] url;
00356 }
00357
00358
00359
00360
00361
00362 if (rtspServer->setUpTunnelingOverHTTP(80) || rtspServer->setUpTunnelingOverHTTP(8000) || rtspServer->setUpTunnelingOverHTTP(8080)) {
00363 *env << "\n(We use port " << rtspServer->httpServerPortNum() << " for optional RTSP-over-HTTP tunneling.)\n";
00364 } else {
00365 *env << "\n(RTSP-over-HTTP tunneling is not available.)\n";
00366 }
00367
00368 env->taskScheduler().doEventLoop();
00369
00370 return 0;
00371 }
00372
00373 static void announceStream(RTSPServer* rtspServer, ServerMediaSession* sms,
00374 char const* streamName, char const* inputFileName) {
00375 char* url = rtspServer->rtspURL(sms);
00376 UsageEnvironment& env = rtspServer->envir();
00377 env << "\n\"" << streamName << "\" stream, from the file \""
00378 << inputFileName << "\"\n";
00379 env << "Play this stream using the URL \"" << url << "\"\n";
00380 delete[] url;
00381 }