mirror of
https://github.com/mpromonet/v4l2rtspserver
synced 2024-11-17 21:25:40 +00:00
allow to configure HLS segment duration
This commit is contained in:
parent
8f13c27aa0
commit
a0706df4fe
@ -155,7 +155,7 @@ class HLSServerMediaSubsession : public UnicastServerMediaSubsession
|
||||
outputBuffer.append((const char*)m_buffer, frameSize);
|
||||
|
||||
// remove old buffers
|
||||
while (m_outputBuffers.size()>5)
|
||||
while (m_outputBuffers.size()>3)
|
||||
{
|
||||
m_outputBuffers.erase(m_outputBuffers.begin());
|
||||
}
|
||||
@ -220,13 +220,13 @@ class HLSServerMediaSubsession : public UnicastServerMediaSubsession
|
||||
};
|
||||
|
||||
public:
|
||||
static HLSServerMediaSubsession* createNew(UsageEnvironment& env, StreamReplicator* replicator, const std::string& format)
|
||||
static HLSServerMediaSubsession* createNew(UsageEnvironment& env, StreamReplicator* replicator, const std::string& format, unsigned int sliceDuration)
|
||||
{
|
||||
return new HLSServerMediaSubsession(env,replicator,format);
|
||||
return new HLSServerMediaSubsession(env, replicator, format, sliceDuration);
|
||||
}
|
||||
|
||||
protected:
|
||||
HLSServerMediaSubsession(UsageEnvironment& env, StreamReplicator* replicator, const std::string& format)
|
||||
HLSServerMediaSubsession(UsageEnvironment& env, StreamReplicator* replicator, const std::string& format, unsigned int sliceDuration)
|
||||
: UnicastServerMediaSubsession(env, replicator, format)
|
||||
{
|
||||
// Create a source
|
||||
@ -234,7 +234,7 @@ class HLSServerMediaSubsession : public UnicastServerMediaSubsession
|
||||
FramedSource* videoSource = createSource(env, source, format);
|
||||
|
||||
// Start Playing the HLS Sink
|
||||
m_hlsSink = HLSSink::createNew(env, OutPacketBuffer::maxSize, 10);
|
||||
m_hlsSink = HLSSink::createNew(env, OutPacketBuffer::maxSize, sliceDuration);
|
||||
m_hlsSink->startPlaying(*videoSource, NULL, NULL);
|
||||
}
|
||||
virtual ~HLSServerMediaSubsession()
|
||||
|
62
src/main.cpp
62
src/main.cpp
@ -88,19 +88,22 @@ class HLSServer : public RTSPServer
|
||||
void sendPlayList(char const* urlSuffix)
|
||||
{
|
||||
ServerMediaSubsession* subsession = this->getSubsesion(urlSuffix);
|
||||
if (subsession == NULL) {
|
||||
if (subsession == NULL)
|
||||
{
|
||||
handleHTTPCmd_notSupported();
|
||||
return;
|
||||
}
|
||||
|
||||
float duration = subsession->duration();
|
||||
if (duration <= 0.0) {
|
||||
if (duration <= 0.0)
|
||||
{
|
||||
handleHTTPCmd_notSupported();
|
||||
return;
|
||||
}
|
||||
|
||||
unsigned int startTime = subsession->getCurrentNPT(NULL);
|
||||
unsigned sliceDuration = 10;
|
||||
HLSServer* hlsServer = (HLSServer*)(&fOurServer);
|
||||
unsigned sliceDuration = hlsServer->m_hlsSegment;
|
||||
std::ostringstream os;
|
||||
os << "#EXTM3U\r\n"
|
||||
<< "#EXT-X-ALLOW-CACHE:YES\r\n"
|
||||
@ -140,14 +143,12 @@ class HLSServer : public RTSPServer
|
||||
return;
|
||||
}
|
||||
|
||||
char* streamName = strDup(urlSuffix);
|
||||
streamName[questionMarkPos-urlSuffix] = '\0';
|
||||
|
||||
do {
|
||||
ServerMediaSubsession* subsession = this->getSubsesion(streamName);
|
||||
if (subsession == NULL) {
|
||||
std::string streamName(urlSuffix, questionMarkPos-urlSuffix);
|
||||
ServerMediaSubsession* subsession = this->getSubsesion(streamName.c_str());
|
||||
if (subsession == NULL)
|
||||
{
|
||||
handleHTTPCmd_notSupported();
|
||||
break;
|
||||
return;
|
||||
}
|
||||
|
||||
// Call "getStreamParameters()" to create the stream's source. (Because we're not actually streaming via RTP/RTCP, most
|
||||
@ -165,10 +166,11 @@ class HLSServer : public RTSPServer
|
||||
u_int64_t numBytes = 0;
|
||||
subsession->seekStream(fClientSessionId, streamToken, dOffsetInSeconds, 0.0, numBytes);
|
||||
|
||||
if (numBytes == 0) {
|
||||
if (numBytes == 0)
|
||||
{
|
||||
// For some reason, we do not know the size of the requested range. We can't handle this request:
|
||||
handleHTTPCmd_notSupported();
|
||||
break;
|
||||
return;
|
||||
}
|
||||
|
||||
// send response header
|
||||
@ -176,9 +178,7 @@ class HLSServer : public RTSPServer
|
||||
|
||||
// stream body
|
||||
this->streamSource(subsession->getStreamSource(streamToken));
|
||||
} while(0);
|
||||
|
||||
delete[] streamName;
|
||||
}
|
||||
}
|
||||
|
||||
@ -200,19 +200,28 @@ class HLSServer : public RTSPServer
|
||||
};
|
||||
|
||||
public:
|
||||
static HLSServer* createNew(UsageEnvironment& env, Port rtspPort, UserAuthenticationDatabase* authDatabase, unsigned reclamationTestSeconds) {
|
||||
static HLSServer* createNew(UsageEnvironment& env, Port rtspPort, UserAuthenticationDatabase* authDatabase, unsigned reclamationTestSeconds, unsigned int hlsSegment)
|
||||
{
|
||||
HLSServer* hlsServer = NULL;
|
||||
int ourSocket = setUpOurSocket(env, rtspPort);
|
||||
if (ourSocket == -1) return NULL;
|
||||
return new HLSServer(env, ourSocket, rtspPort, authDatabase, reclamationTestSeconds);
|
||||
if (ourSocket != -1)
|
||||
{
|
||||
hlsServer = new HLSServer(env, ourSocket, rtspPort, authDatabase, reclamationTestSeconds, hlsSegment);
|
||||
}
|
||||
return hlsServer;
|
||||
}
|
||||
|
||||
HLSServer(UsageEnvironment& env, int ourSocket, Port rtspPort, UserAuthenticationDatabase* authDatabase, unsigned reclamationTestSeconds)
|
||||
: RTSPServer(env, ourSocket, rtspPort, authDatabase, reclamationTestSeconds) {
|
||||
HLSServer(UsageEnvironment& env, int ourSocket, Port rtspPort, UserAuthenticationDatabase* authDatabase, unsigned reclamationTestSeconds, unsigned int hlsSegment)
|
||||
: RTSPServer(env, ourSocket, rtspPort, authDatabase, reclamationTestSeconds), m_hlsSegment(hlsSegment)
|
||||
{
|
||||
}
|
||||
|
||||
RTSPServer::RTSPClientConnection* createNewClientConnection(int clientSocket, struct sockaddr_in clientAddr) {
|
||||
RTSPServer::RTSPClientConnection* createNewClientConnection(int clientSocket, struct sockaddr_in clientAddr)
|
||||
{
|
||||
return new HLSClientConnection(*this, clientSocket, clientAddr);
|
||||
}
|
||||
|
||||
const unsigned int m_hlsSegment;
|
||||
};
|
||||
|
||||
#include <stdio.h>
|
||||
@ -255,10 +264,10 @@ void sighandler(int n)
|
||||
// -----------------------------------------
|
||||
// create RTSP server
|
||||
// -----------------------------------------
|
||||
RTSPServer* createRTSPServer(UsageEnvironment& env, unsigned short rtspPort, unsigned short rtspOverHTTPPort, int timeout)
|
||||
RTSPServer* createRTSPServer(UsageEnvironment& env, unsigned short rtspPort, unsigned short rtspOverHTTPPort, int timeout, unsigned int hlsSegment)
|
||||
{
|
||||
UserAuthenticationDatabase* authDB = NULL;
|
||||
RTSPServer* rtspServer = HLSServer::createNew(env, rtspPort, authDB, timeout);
|
||||
RTSPServer* rtspServer = HLSServer::createNew(env, rtspPort, authDB, timeout, hlsSegment);
|
||||
if (rtspServer != NULL)
|
||||
{
|
||||
// set http tunneling
|
||||
@ -329,10 +338,11 @@ int main(int argc, char** argv)
|
||||
bool repeatConfig = true;
|
||||
int timeout = 65;
|
||||
bool muxTS = false;
|
||||
unsigned int hlsSegment = 10;
|
||||
|
||||
// decode parameters
|
||||
int c = 0;
|
||||
while ((c = getopt (argc, argv, "v::Q:O:" "I:P:p:m:u:M:ct:T" "rsfF:W:H:" "h")) != -1)
|
||||
while ((c = getopt (argc, argv, "v::Q:O:" "I:P:p:m:u:M:ct:TS:" "rsfF:W:H:" "h")) != -1)
|
||||
{
|
||||
switch (c)
|
||||
{
|
||||
@ -349,6 +359,7 @@ int main(int argc, char** argv)
|
||||
case 'c': repeatConfig = false; break;
|
||||
case 't': timeout = atoi(optarg); break;
|
||||
case 'T': muxTS = true; break;
|
||||
case 'S': hlsSegment = atoi(optarg); muxTS=true; break;
|
||||
// V4L2
|
||||
case 'r': useMmap = false; break;
|
||||
case 's': useThread = false; break;
|
||||
@ -377,6 +388,7 @@ int main(int argc, char** argv)
|
||||
std::cout << "\t -c : don't repeat config (default repeat config before IDR frame)" << std::endl;
|
||||
std::cout << "\t -t secs : RTCP expiration timeout (default " << timeout << ")" << std::endl;
|
||||
std::cout << "\t -T : send Transport Stream instead of elementary Stream" << std::endl;
|
||||
std::cout << "\t -S : HLS segment duration (enable HLS streaming and TS muxing)" << std::endl;
|
||||
std::cout << "\t V4L2 options :" << std::endl;
|
||||
std::cout << "\t -r : V4L2 capture using read interface (default use memory mapped buffers)" << std::endl;
|
||||
std::cout << "\t -s : V4L2 capture using live555 mainloop (default use a reader thread)" << std::endl;
|
||||
@ -429,7 +441,7 @@ int main(int argc, char** argv)
|
||||
unsigned char ttl = 5;
|
||||
|
||||
// create RTSP server
|
||||
RTSPServer* rtspServer = createRTSPServer(*env, rtspPort, rtspOverHTTPPort, timeout);
|
||||
RTSPServer* rtspServer = createRTSPServer(*env, rtspPort, rtspOverHTTPPort, timeout, hlsSegment);
|
||||
if (rtspServer == NULL)
|
||||
{
|
||||
LOG(ERROR) << "Failed to create RTSP server: " << env->getResultMsg();
|
||||
@ -522,7 +534,7 @@ int main(int argc, char** argv)
|
||||
// Create Unicast Session
|
||||
if (muxTS)
|
||||
{
|
||||
addSession(rtspServer, baseUrl+url, HLSServerMediaSubsession::createNew(*env,replicator,rtpFormat));
|
||||
addSession(rtspServer, baseUrl+url, HLSServerMediaSubsession::createNew(*env,replicator,rtpFormat, hlsSegment));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user