我想从一个文件做RTSP流,所以我使用live 555库。在活555测试目录"testMpeg2TransportStreamer"程序流TS格式文件,我做的是什么,我把整个代码线程当客户端请求流线程开始工作,当客户说不要流然后线程关闭关闭线程上我也写了代码中::关闭(rtsp服务器)的指针,所以关闭rtsp服务器,这对第一个流和不流请求很不错但不流请求后当客户说我调试了代码,发现它无法创建rtsp服务器。然后我使用了另一种方法,即在第一个STREAM请求中只创建一次rtsp服务器,而不是在整个程序退出之前关闭它,但这也失败了。有人能建议其他的方法吗我的代码如下:-
#define TRANSPORT_PACKET_SIZE 188
#define TRANSPORT_PACKETS_PER_NETWORK_PACKET 7
#define IMPLEMENT_RTSP_SERVER
// To stream using "source-specific multicast" (SSM), uncomment the following:
//#define USE_SSM 1
#ifdef USE_SSM
Boolean const isSSM = True;
#else
Boolean const isSSM = False;
#endif
/********************Global variable***************************/
UsageEnvironment* env=NULL;
FramedSource* videoSource;
RTPSink* videoSink;
DeviceSourceFICard* fileSource;
FICardDeviceParameters fi_params;
HANDLE g_hRtpComThread;
DWORD g_dwRtpComThreadID;
char g_ExitEventLoop;
void play(); // forward
RTSPServer* rtspServer=NULL;
ServerMediaSession* sms;
int initLm555Settings(void)
{
scheduler = BasicTaskScheduler::createNew();
env = BasicUsageEnvironment::createNew(*scheduler);
destinationAddressStr//make it global
#ifdef USE_SSM
= "232.255.42.42";
#else
= "239.255.42.42";
const unsigned short rtpPortNum = 18888;//make it global
rtpPortNum1=rtpPortNum;
const unsigned short rtcpPortNum = rtpPortNum+1;
const unsigned char ttl = 7;
struct in_addr destinationAddress;
destinationAddress.s_addr = our_inet_addr(destinationAddressStr);
const Port rtpPort(rtpPortNum);
const Port rtcpPort(rtcpPortNum);
Groupsock rtpGroupsock(*env, destinationAddress, rtpPort, ttl);
rtpGroupsock.multicastSendOnly();
Groupsock rtcpGroupsock(*env, destinationAddress, rtcpPort, ttl);
rtcpGroupsock.multicastSendOnly();
#ifdef USE_SSM
rtpGroupsock.multicastSendOnly();
rtcpGroupsock.multicastSendOnly();
#endif
g_ExitEventLoop = 0;
videoSink =
SimpleRTPSink::createNew(*env, &rtpGroupsock, 33, 90000, "video", "MP2T",
1, True, False /*no 'M' bit*/);
setSendBufferTo(*env, rtpGroupsock.socketNum(), 1024 * 1024);
setSendBufferTo(*env, rtpGroupsock.socketNum(), 1024 * 1024);
// Create (and start) a 'RTCP instance' for this RTP sink:
const unsigned estimatedSessionBandwidth = 5000; // in kbps; for RTCP b/w share
const unsigned maxCNAMElen = 100;
unsigned char CNAME[maxCNAMElen+1];
gethostname((char*)CNAME, maxCNAMElen);
CNAME[maxCNAMElen] = ' '; // just in case
RTCPInstance* rtcp =
RTCPInstance::createNew(*env, &rtcpGroupsock,
estimatedSessionBandwidth, CNAME,
videoSink, NULL /* we're a server */, isSSM);
UserAuthenticationDatabase* authDB = NULL;
portNumBits rtspServerPortNum = 554;
unsigned reclamationTestSeconds=65U;
rtspServer = RTSPServer::createNew(*env,rtspServerPortNum, authDB, reclamationTestSeconds);
if (rtspServer == NULL)
{
*env << "Failed to create RTSP server: " <<env->getResultMsg()<<"n";
rtspServerPortNum = 8554;
rtspServer = RTSPServer::createNew(*env,rtspServerPortNum);
if (rtspServer == NULL)
{
return 0;
}
Boolean const inputStreamIsRawUDP = False;
char const* descriptionString={"Session streamed by "testOnDemandRT""};
sms=ServerMediaSession::createNew(*env, streamName, streamName,descriptionString);
sms->addSubsession(MPEG2TransportUDPServerMediaSubsession::createNew(*env,destinationAddressStr,rtpPortNum1,inputStreamIsRawUDP));
rtspServer->addServerMediaSession(sms);
char* url = rtspServer->rtspURL(sms);
*env << "Play this stream using the URL "" << url << ""n";
delete[] url;
if (rtspServer->setUpTunnelingOverHTTP(sport) || rtspServer->setUpTunnelingOverHTTP(sport) || rtspServer->setUpTunnelingOverHTTP(sport))
{
out<<"nnn(We use port "<<rtspServer->httpServerPortNum()<<" for optional RTSP-over-HTTP tunneling.)n";
}
else
{
pDailyLogger->LogInfoString("(RTSP-over-HTTP tunneling is not available.)");
cout<<"nnn(RTSP-over-HTTP tunneling is not available.)";
}
play();
env->taskScheduler().doEventLoop(&g_ExitEventLoop);
Medium::close(rtspServer);
Medium::close(rtcp);
Medium::close(videoSink);
rtpGroupsock.removeAllDestinations();
rtcpGroupsock.removeAllDestinations();
env->reclaim();
delete scheduler;
pDailyLogger->LogDebugString("OUT::initLm555Settings Thread");
return 0; // only to prevent compiler warning
}
void afterPlaying(void* /*clientData*/) {
*env << "...done reading from filen";
videoSink->stopPlaying();
Medium::close(videoSource);
play();
}
void play() {
// Open the input file as a 'byte-stream file source':
fi_params.nFICardFrameSize = TRANSPORT_PACKETS_PER_NETWORK_PACKET * TRANSPORT_PACKET_SIZE;
fi_params.pfnGetRTPPayload = GetRTPPayload;
fi_params.socketNum = videoSink->groupsockBeingUsed().socketNum();
DeviceParameters temp;
fileSource = DeviceSourceFICard::createNew(*env, fi_params, temp);
if (fileSource == NULL) {
*env << "Unable to open Foresight card as a byte-stream file sourcen";
exit(1);
}
FramedSource* videoES = fileSource;
videoSource = MPEG1or2VideoStreamDiscreteFramer::createNew(*env, videoES);
*env << "Beginning to read from file...n";
videoSink->startPlaying(*videoSource, afterPlaying, videoSink);
}
void StartRTPProcess(void)
{
g_hRtpComThread = CreateThread((LPSECURITY_ATTRIBUTES) NULL, 0,
(LPTHREAD_START_ROUTINE)initLm555Settings, 0, 0, &g_dwRtpComThreadID);
if(g_hRtpComThread) SetThreadPriority(g_hRtpComThread, THREAD_PRIORITY_LOWEST/*THREAD_PRIORITY_NORMAL*/);
}
int StopRTProcess(void)
{
g_ExitEventLoop = 1;
g_ExitEventLoop = 0;
g_hRtpComThread = 0;
g_dwRtpComThreadID = 0;
}
Sir StopRTProcess()被调用时,我得到不流消息,我错过了什么,请告诉
可能您的RTSP服务器套接字没有被关闭。关闭媒体后,删除媒体对象和RTSPServer对象。