1 | /* --------------------------------------------------------------------------- |
2 | ** This software is in the public domain, furnished "as is", without technical |
3 | ** support, and with no warranty, express or implied, as to its usefulness for |
4 | ** any purpose. |
5 | ** |
6 | ** HTTPServer.h |
7 | ** |
8 | ** V4L2 RTSP streamer |
9 | ** |
10 | ** HTTP server that serves HLS & MPEG-DASH playlist and segments |
11 | ** |
12 | ** -------------------------------------------------------------------------*/ |
13 | |
14 | |
15 | #include "RTSPServer.hh" |
16 | #include "RTSPCommon.hh" |
17 | |
18 | // --------------------------------------------------------- |
19 | // Extend RTSP server to add support for HLS and MPEG-DASH |
20 | // --------------------------------------------------------- |
21 | class HTTPServer : public RTSPServer |
22 | { |
23 | |
24 | class HTTPClientConnection : public RTSPServer::RTSPClientConnection |
25 | { |
26 | public: |
27 | HTTPClientConnection(RTSPServer& ourServer, int clientSocket, struct sockaddr_in clientAddr) |
28 | : RTSPServer::RTSPClientConnection(ourServer, clientSocket, clientAddr), fTCPSink(NULL), fStreamToken(NULL), fSubsession(NULL), fSource(NULL) { |
29 | } |
30 | virtual ~HTTPClientConnection(); |
31 | |
32 | private: |
33 | |
34 | void (const char* contentType, unsigned int contentLength); |
35 | void streamSource(FramedSource* source); |
36 | void streamSource(const std::string & content); |
37 | ServerMediaSubsession* getSubsesion(const char* urlSuffix); |
38 | bool sendFile(char const* urlSuffix); |
39 | bool sendM3u8PlayList(char const* urlSuffix); |
40 | bool sendMpdPlayList(char const* urlSuffix); |
41 | virtual void handleHTTPCmd_StreamingGET(char const* urlSuffix, char const* fullRequestStr); |
42 | virtual void handleCmd_notFound(); |
43 | static void afterStreaming(void* clientData); |
44 | |
45 | private: |
46 | static u_int32_t fClientSessionId; |
47 | TCPStreamSink* fTCPSink; |
48 | void* fStreamToken; |
49 | ServerMediaSubsession* fSubsession; |
50 | FramedSource* fSource; |
51 | }; |
52 | |
53 | public: |
54 | static HTTPServer* createNew(UsageEnvironment& env, Port rtspPort, UserAuthenticationDatabase* authDatabase, unsigned reclamationTestSeconds, unsigned int hlsSegment, const std::string webroot) |
55 | { |
56 | HTTPServer* httpServer = NULL; |
57 | int ourSocket = setUpOurSocket(env, rtspPort); |
58 | if (ourSocket != -1) |
59 | { |
60 | httpServer = new HTTPServer(env, ourSocket, rtspPort, authDatabase, reclamationTestSeconds, hlsSegment, webroot); |
61 | } |
62 | return httpServer; |
63 | } |
64 | |
65 | HTTPServer(UsageEnvironment& env, int ourSocket, Port rtspPort, UserAuthenticationDatabase* authDatabase, unsigned reclamationTestSeconds, unsigned int hlsSegment, const std::string & webroot) |
66 | : RTSPServer(env, ourSocket, rtspPort, authDatabase, reclamationTestSeconds), m_hlsSegment(hlsSegment), m_webroot(webroot) |
67 | { |
68 | if ( (!m_webroot.empty()) && (*m_webroot.rend() != '/') ) { |
69 | m_webroot += "/" ; |
70 | } |
71 | } |
72 | |
73 | RTSPServer::RTSPClientConnection* createNewClientConnection(int clientSocket, struct sockaddr_in clientAddr) |
74 | { |
75 | return new HTTPClientConnection(*this, clientSocket, clientAddr); |
76 | } |
77 | |
78 | private: |
79 | const unsigned int m_hlsSegment; |
80 | std::string m_webroot; |
81 | }; |
82 | |
83 | |