[Live-devel] MP3 file stream crashes

Matthew Hale matthew at scansoft.co.za
Tue Aug 29 02:10:52 PDT 2023


 Hi,

I'm having a problem with a MP3 RTSP stream. I've subclassed
OnDemandServerMediaSubsession to create a subsession based on the
testMP3Streamer.cpp using the MPEG1or2AudioRTPSink and MP3FileSource. I'm
also using the RTSPServer and ServerMediaSession. The crash is after the
PLAY request due to a socket error (10038) on the select() in
BasicTaskScheduler::SingleStep().

I thought I was probably doing something wrong so I tried some sample code
I found online (attached), but it is also crashing with the same error for
the MP3 stream but the WAV file streams fine. I tried with the latest
version of Live555 and that didn't work either. I have also created a live
mic stream subsession that is working so I'm sure this is to do with the
MP3 file subsession specifically.

I'm opening the streams with VLC. Building Live555 with vcpkg on Windows.

I'd appreciate any insight to what I might be missing, thank you.


Kind regards,



*Matthew Hale*


*Web: www.scansoft.co.za <http://www.scansoft.co.za/>*
*Tel:  +27 21 913 8664*

*Cell: +27 76 118 4748*
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.live555.com/pipermail/live-devel/attachments/20230829/f7ba3c6b/attachment.htm>
-------------- next part --------------
#include "liveMedia.hh"

#include "BasicUsageEnvironment.hh"

#pragma comment(lib, "ws2_32.lib")

UsageEnvironment * env;

Boolean reuseFirstSource = False;

static void announceStream(RTSPServer * rtspServer, ServerMediaSession * sms, char const * streamName, char const * inputFileName);  // forward

int main(int argc, char ** argv)
{
	// Begin by setting up our usage environment:
	TaskScheduler * scheduler = BasicTaskScheduler::createNew();
	env = BasicUsageEnvironment::createNew(*scheduler);

	UserAuthenticationDatabase * authDB = NULL;
#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 the above with each <username>, <password> that you wish to allow
	// access to the server.
#endif

	// Create the RTSP server:
#ifdef SERVER_USE_TLS
	// Serve RTSPS: RTSP over a TLS connection:
	RTSPServer * rtspServer = RTSPServer::createNew(*env, 322, authDB);
#else
	// Serve regular RTSP (over a TCP connection):
	RTSPServer * rtspServer = RTSPServer::createNew(*env, 8554, authDB);
#endif
	if (rtspServer == NULL)
	{
		*env << "Failed to create RTSP server: " << env->getResultMsg() << "\n";
		exit(1);
	}
#ifdef SERVER_USE_TLS
#	ifndef STREAM_USING_SRTP
#		define STREAM_USING_SRTP True
#	endif
	rtspServer->setTLSState(PATHNAME_TO_CERTIFICATE_FILE, PATHNAME_TO_PRIVATE_KEY_FILE, STREAM_USING_SRTP);
#endif

	char const * descriptionString = "Session streamed by \"testOnDemandRTSPServer\"";

	// A MP3 audio stream (actually, any MPEG-1 or 2 audio file will work):
	// To stream using 'ADUs' rather than raw MP3 frames, uncomment the following:
	//#define STREAM_USING_ADUS 1
	// To also reorder ADUs before streaming, uncomment the following:
	//#define INTERLEAVE_ADUS 1
	// (For more information about ADUs and interleaving,
	//  see <http://www.live555.com/rtp-mp3/>)
	{
		char const * streamName = "mp3AudioTest";
		char const * inputFileName = "test.mp3";
		ServerMediaSession * sms = ServerMediaSession::createNew(*env, streamName, streamName, descriptionString, true);
		Boolean useADUs = False;
		Interleaving * interleaving = NULL;
#ifdef STREAM_USING_ADUS
		useADUs = True;
#	ifdef INTERLEAVE_ADUS
		unsigned char interleaveCycle[] = { 0, 2, 1, 3 };  // or choose your own...
		unsigned const interleaveCycleSize = (sizeof interleaveCycle) / (sizeof(unsigned char));
		interleaving = new Interleaving(interleaveCycleSize, interleaveCycle);
#	endif
#endif
		sms->addSubsession(MP3AudioFileServerMediaSubsession::createNew(*env, inputFileName, reuseFirstSource, useADUs, interleaving));
		rtspServer->addServerMediaSession(sms);

		announceStream(rtspServer, sms, streamName, inputFileName);
	}

	// A WAV audio stream:
	{
		char const * streamName = "wavAudioTest";
		char const * inputFileName = "test.wav";
		ServerMediaSession * sms = ServerMediaSession::createNew(*env, streamName, streamName, descriptionString, true);
		// To convert 16-bit PCM data to 8-bit u-law, prior to streaming,
		// change the following to True:
		Boolean convertToULaw = False;
		sms->addSubsession(WAVAudioFileServerMediaSubsession ::createNew(*env, inputFileName, reuseFirstSource, convertToULaw));
		rtspServer->addServerMediaSession(sms);

		announceStream(rtspServer, sms, streamName, inputFileName);
	}

	// 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).

#ifdef SERVER_USE_TLS
	// (Attempt to) use the default HTTPS port (443) instead:
	char const * httpProtocolStr = "HTTPS";
	if (rtspServer->setUpTunnelingOverHTTP(443))
	{
#else
	char const * httpProtocolStr = "HTTP";
	if (rtspServer->setUpTunnelingOverHTTP(80) || rtspServer->setUpTunnelingOverHTTP(8000) || rtspServer->setUpTunnelingOverHTTP(8080))
	{
#endif
		*env << "\n(We use port " << rtspServer->httpServerPortNum() << " for optional RTSP-over-" << httpProtocolStr << " tunneling.)\n";
	}
	else
	{
		*env << "\n(RTSP-over-" << httpProtocolStr << " tunneling is not available.)\n";
	}

	env->taskScheduler().doEventLoop();  // does not return

	return 0;  // only to prevent compiler warning
}

static void announceStream(RTSPServer * rtspServer, ServerMediaSession * sms, char const * streamName, char const * inputFileName)
{
	UsageEnvironment & env = rtspServer->envir();

	env << "\n\"" << streamName << "\" stream, from the file \"" << inputFileName << "\"\n";
	// announceURL(rtspServer, sms);
	env << "Play this stream using the URL ";

	char * url = rtspServer->ipv4rtspURL(sms);
	env << "\"" << url << "\"";
	delete[] url;
	env << "\n";
}


More information about the live-devel mailing list