| 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 | |