diff --git a/trunk/conf/full.conf b/trunk/conf/full.conf
index 78911b92f..a639e2675 100644
--- a/trunk/conf/full.conf
+++ b/trunk/conf/full.conf
@@ -159,6 +159,7 @@ stream_caster {
# the caster type of stream, the casters:
# mpegts_over_udp, MPEG-TS over UDP caster.
# rtsp, Real Time Streaming Protocol (RTSP).
+ # flv, FLV over HTTP POST.
caster mpegts_over_udp;
# the output rtmp url.
# for mpegts_over_udp caster, the typically output url:
@@ -195,6 +196,12 @@ stream_caster {
rtp_port_min 57200;
rtp_port_max 57300;
}
+stream_caster {
+ enabled off;
+ caster flv;
+ output rtmp://127.0.0.1/[app]/[stream];
+ listen 8936;
+}
#############################################################################################
# RTMP/HTTP VHOST sections
diff --git a/trunk/configure b/trunk/configure
index 067c91ca4..7f8727442 100755
--- a/trunk/configure
+++ b/trunk/configure
@@ -175,7 +175,8 @@ if [ $SRS_EXPORT_LIBRTMP_PROJECT = NO ]; then
"srs_app_json" "srs_app_ingest" "srs_app_ffmpeg" "srs_app_utility" "srs_app_dvr" "srs_app_edge"
"srs_app_kbps" "srs_app_heartbeat" "srs_app_empty" "srs_app_http_client"
"srs_app_recv_thread" "srs_app_security" "srs_app_statistic" "srs_app_hds"
- "srs_app_mpegts_udp" "srs_app_rtsp" "srs_app_listener" "srs_app_async_call")
+ "srs_app_mpegts_udp" "srs_app_rtsp" "srs_app_listener" "srs_app_async_call"
+ "srs_app_caster_flv")
DEFINES=""
# add each modules for app
for SRS_MODULE in ${SRS_MODULES[*]}; do
diff --git a/trunk/ide/srs_upp/srs_upp.upp b/trunk/ide/srs_upp/srs_upp.upp
index 424a3bbd3..e302bb98b 100755
--- a/trunk/ide/srs_upp/srs_upp.upp
+++ b/trunk/ide/srs_upp/srs_upp.upp
@@ -69,6 +69,8 @@ file
../../src/app/srs_app_async_call.cpp,
../../src/app/srs_app_bandwidth.hpp,
../../src/app/srs_app_bandwidth.cpp,
+ ../../src/app/srs_app_caster_flv.hpp,
+ ../../src/app/srs_app_caster_flv.cpp,
../../src/app/srs_app_conn.hpp,
../../src/app/srs_app_conn.cpp,
../../src/app/srs_app_config.hpp,
diff --git a/trunk/ide/srs_vs2010/srs.vcxproj b/trunk/ide/srs_vs2010/srs.vcxproj
index c9050517a..f7d0a9ff1 100755
--- a/trunk/ide/srs_vs2010/srs.vcxproj
+++ b/trunk/ide/srs_vs2010/srs.vcxproj
@@ -85,6 +85,7 @@
+
@@ -165,6 +166,7 @@
+
@@ -213,4 +215,4 @@
-
\ No newline at end of file
+
diff --git a/trunk/ide/srs_xcode/srs_xcode.xcodeproj/project.pbxproj b/trunk/ide/srs_xcode/srs_xcode.xcodeproj/project.pbxproj
index 15522b837..94b678670 100644
--- a/trunk/ide/srs_xcode/srs_xcode.xcodeproj/project.pbxproj
+++ b/trunk/ide/srs_xcode/srs_xcode.xcodeproj/project.pbxproj
@@ -75,6 +75,7 @@
3C1232ED1AAEA70F00CE8F6C /* libhttp_parser.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 3C1232EC1AAEA70F00CE8F6C /* libhttp_parser.a */; };
3C1EE6AE1AB1055800576EE9 /* srs_app_hds.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3C1EE6AC1AB1055800576EE9 /* srs_app_hds.cpp */; };
3C1EE6D71AB1367D00576EE9 /* README.md in Sources */ = {isa = PBXBuildFile; fileRef = 3C1EE6D61AB1367D00576EE9 /* README.md */; };
+ 3C28EDDF1AF5C43F00A3AEAC /* srs_app_caster_flv.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3C28EDDD1AF5C43F00A3AEAC /* srs_app_caster_flv.cpp */; };
3C36DB5B1ABD1CB90066CCAF /* srs_lib_bandwidth.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3C36DB551ABD1CB90066CCAF /* srs_lib_bandwidth.cpp */; };
3C36DB5C1ABD1CB90066CCAF /* srs_lib_simple_socket.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3C36DB571ABD1CB90066CCAF /* srs_lib_simple_socket.cpp */; };
3C36DB5D1ABD1CB90066CCAF /* srs_librtmp.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3C36DB591ABD1CB90066CCAF /* srs_librtmp.cpp */; };
@@ -318,6 +319,8 @@
3C1EE6D41AB1367D00576EE9 /* DONATIONS.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = DONATIONS.txt; path = ../../../DONATIONS.txt; sourceTree = ""; };
3C1EE6D51AB1367D00576EE9 /* LICENSE */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = LICENSE; path = ../../../LICENSE; sourceTree = ""; };
3C1EE6D61AB1367D00576EE9 /* README.md */ = {isa = PBXFileReference; explicitFileType = net.daringfireball.markdown; fileEncoding = 4; name = README.md; path = ../../../README.md; sourceTree = ""; wrapsLines = 0; };
+ 3C28EDDD1AF5C43F00A3AEAC /* srs_app_caster_flv.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = srs_app_caster_flv.cpp; path = ../../../src/app/srs_app_caster_flv.cpp; sourceTree = ""; };
+ 3C28EDDE1AF5C43F00A3AEAC /* srs_app_caster_flv.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = srs_app_caster_flv.hpp; path = ../../../src/app/srs_app_caster_flv.hpp; sourceTree = ""; };
3C36DB551ABD1CB90066CCAF /* srs_lib_bandwidth.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = srs_lib_bandwidth.cpp; path = ../../../src/libs/srs_lib_bandwidth.cpp; sourceTree = ""; };
3C36DB561ABD1CB90066CCAF /* srs_lib_bandwidth.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = srs_lib_bandwidth.hpp; path = ../../../src/libs/srs_lib_bandwidth.hpp; sourceTree = ""; };
3C36DB571ABD1CB90066CCAF /* srs_lib_simple_socket.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = srs_lib_simple_socket.cpp; path = ../../../src/libs/srs_lib_simple_socket.cpp; sourceTree = ""; };
@@ -511,6 +514,8 @@
3C12324B1AAE81CE00CE8F6C /* app */ = {
isa = PBXGroup;
children = (
+ 3C28EDDD1AF5C43F00A3AEAC /* srs_app_caster_flv.cpp */,
+ 3C28EDDE1AF5C43F00A3AEAC /* srs_app_caster_flv.hpp */,
3CD88B3D1ACA9C58000359E0 /* srs_app_async_call.cpp */,
3CD88B3E1ACA9C58000359E0 /* srs_app_async_call.hpp */,
3C12324C1AAE81D900CE8F6C /* srs_app_bandwidth.cpp */,
@@ -908,6 +913,7 @@
3C1232261AAE814D00CE8F6C /* srs_kernel_flv.cpp in Sources */,
3C663F1A1AB0155100286D8B /* srs_rtmp_dump.c in Sources */,
3CE6CD311AE4AFB800706E07 /* srs_main_ingest_hls.cpp in Sources */,
+ 3C28EDDF1AF5C43F00A3AEAC /* srs_app_caster_flv.cpp in Sources */,
3C1232241AAE814D00CE8F6C /* srs_kernel_error.cpp in Sources */,
3C1232441AAE81A400CE8F6C /* srs_rtmp_handshake.cpp in Sources */,
3C1232291AAE814D00CE8F6C /* srs_kernel_stream.cpp in Sources */,
diff --git a/trunk/src/app/srs_app_caster_flv.cpp b/trunk/src/app/srs_app_caster_flv.cpp
new file mode 100644
index 000000000..e57d0a044
--- /dev/null
+++ b/trunk/src/app/srs_app_caster_flv.cpp
@@ -0,0 +1,104 @@
+/*
+The MIT License (MIT)
+
+Copyright (c) 2013-2015 SRS(simple-rtmp-server)
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of
+this software and associated documentation files (the "Software"), to deal in
+the Software without restriction, including without limitation the rights to
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+the Software, and to permit persons to whom the Software is furnished to do so,
+subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/
+
+#include
+
+#ifdef SRS_AUTO_STREAM_CASTER
+
+#include
+using namespace std;
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+SrsAppCasterFlv::SrsAppCasterFlv(SrsConfDirective* c)
+{
+ http_mux = new SrsHttpServeMux();
+ output = _srs_config->get_stream_caster_output(c);
+}
+
+SrsAppCasterFlv::~SrsAppCasterFlv()
+{
+}
+
+int SrsAppCasterFlv::initialize()
+{
+ int ret = ERROR_SUCCESS;
+
+ if ((ret = http_mux->handle("/", this)) != ERROR_SUCCESS) {
+ return ret;
+ }
+
+ return ret;
+}
+
+int SrsAppCasterFlv::on_tcp_client(st_netfd_t stfd)
+{
+ int ret = ERROR_SUCCESS;
+
+ SrsHttpConn* conn = new SrsHttpConn(this, stfd, http_mux);
+ conns.push_back(conn);
+
+ if ((ret = conn->start()) != ERROR_SUCCESS) {
+ return ret;
+ }
+
+ return ret;
+}
+
+void SrsAppCasterFlv::remove(SrsConnection* c)
+{
+ std::vector::iterator it;
+ if ((it = std::find(conns.begin(), conns.end(), c)) != conns.end()) {
+ conns.erase(it);
+ }
+}
+#define SRS_HTTP_FLV_STREAM_BUFFER 4096
+int SrsAppCasterFlv::serve_http(ISrsHttpResponseWriter* w, SrsHttpMessage* r)
+{
+ int ret = ERROR_SUCCESS;
+
+ srs_info("flv: handle request at %s", r->path().c_str());
+
+ char* buffer = new char[SRS_HTTP_FLV_STREAM_BUFFER];
+ SrsAutoFree(char, buffer);
+
+ ISrsHttpResponseReader* rr = r->body_reader();
+ while (!rr->eof()) {
+ int nb_read = 0;
+ if ((ret = rr->read(buffer, SRS_HTTP_FLV_STREAM_BUFFER, &nb_read)) != ERROR_SUCCESS) {
+ return ret;
+ }
+ srs_trace("flv: read %dB from %s", nb_read, r->path().c_str());
+ }
+
+ return ret;
+}
+
+#endif
diff --git a/trunk/src/app/srs_app_caster_flv.hpp b/trunk/src/app/srs_app_caster_flv.hpp
new file mode 100644
index 000000000..fb092f5b2
--- /dev/null
+++ b/trunk/src/app/srs_app_caster_flv.hpp
@@ -0,0 +1,72 @@
+/*
+The MIT License (MIT)
+
+Copyright (c) 2013-2015 SRS(simple-rtmp-server)
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of
+this software and associated documentation files (the "Software"), to deal in
+the Software without restriction, including without limitation the rights to
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+the Software, and to permit persons to whom the Software is furnished to do so,
+subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/
+
+#ifndef SRS_APP_CASTER_FLV_HPP
+#define SRS_APP_CASTER_FLV_HPP
+
+/*
+#include
+*/
+
+#include
+
+#include
+#include
+
+#ifdef SRS_AUTO_STREAM_CASTER
+
+class SrsConfDirective;
+class SrsHttpServeMux;
+class SrsHttpConn;
+
+#include
+#include
+#include
+#include
+
+class SrsAppCasterFlv : virtual public ISrsTcpHandler
+ , virtual public IConnectionManager, virtual public ISrsHttpHandler
+{
+private:
+ std::string output;
+ SrsHttpServeMux* http_mux;
+ std::vector conns;
+public:
+ SrsAppCasterFlv(SrsConfDirective* c);
+ virtual ~SrsAppCasterFlv();
+public:
+ virtual int initialize();
+// ISrsTcpHandler
+public:
+ virtual int on_tcp_client(st_netfd_t stfd);
+// IConnectionManager
+public:
+ virtual void remove(SrsConnection* c);
+// ISrsHttpHandler
+public:
+ virtual int serve_http(ISrsHttpResponseWriter* w, SrsHttpMessage* r);
+};
+
+#endif
+
+#endif
diff --git a/trunk/src/app/srs_app_config.hpp b/trunk/src/app/srs_app_config.hpp
index c32262cb2..6e2a1b353 100644
--- a/trunk/src/app/srs_app_config.hpp
+++ b/trunk/src/app/srs_app_config.hpp
@@ -100,6 +100,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#define SRS_CONF_DEFAULT_STREAM_CASTER_ENABLED false
#define SRS_CONF_DEFAULT_STREAM_CASTER_MPEGTS_OVER_UDP "mpegts_over_udp"
#define SRS_CONF_DEFAULT_STREAM_CASTER_RTSP "rtsp"
+#define SRS_CONF_DEFAULT_STREAM_CASTER_FLV "flv"
#define SRS_CONF_DEFAULT_STATS_NETWORK_DEVICE_INDEX 0
diff --git a/trunk/src/app/srs_app_conn.cpp b/trunk/src/app/srs_app_conn.cpp
index 656cbe031..4c483ba1c 100644
--- a/trunk/src/app/srs_app_conn.cpp
+++ b/trunk/src/app/srs_app_conn.cpp
@@ -25,14 +25,21 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include
#include
-#include
#include
-SrsConnection::SrsConnection(SrsServer* srs_server, st_netfd_t client_stfd)
+IConnectionManager::IConnectionManager()
+{
+}
+
+IConnectionManager::~IConnectionManager()
+{
+}
+
+SrsConnection::SrsConnection(IConnectionManager* cm, st_netfd_t c)
{
id = 0;
- server = srs_server;
- stfd = client_stfd;
+ manager = cm;
+ stfd = c;
// the client thread should reap itself,
// so we never use joinable.
@@ -86,7 +93,7 @@ int SrsConnection::cycle()
void SrsConnection::on_thread_stop()
{
// TODO: FIXME: never remove itself, use isolate thread to do cleanup.
- server->remove(this);
+ manager->remove(this);
}
int SrsConnection::srs_id()
diff --git a/trunk/src/app/srs_app_conn.hpp b/trunk/src/app/srs_app_conn.hpp
index 8cff99a18..29a6eace7 100644
--- a/trunk/src/app/srs_app_conn.hpp
+++ b/trunk/src/app/srs_app_conn.hpp
@@ -36,7 +36,22 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include
#include
-class SrsServer;
+class SrsConnection;
+
+/**
+ * the manager for connection.
+ */
+class IConnectionManager
+{
+public:
+ IConnectionManager();
+ virtual ~IConnectionManager();
+public:
+ /**
+ * remove the specified connection.
+ */
+ virtual void remove(SrsConnection* c) = 0;
+};
/**
* the basic connection of SRS,
@@ -57,9 +72,9 @@ private:
int id;
protected:
/**
- * the server object to manage the connection.
+ * the manager object to manage the connection.
*/
- SrsServer* server;
+ IConnectionManager* manager;
/**
* the underlayer st fd handler.
*/
@@ -69,7 +84,7 @@ protected:
*/
std::string ip;
public:
- SrsConnection(SrsServer* srs_server, st_netfd_t client_stfd);
+ SrsConnection(IConnectionManager* cm, st_netfd_t c);
virtual ~SrsConnection();
public:
/**
diff --git a/trunk/src/app/srs_app_http_api.cpp b/trunk/src/app/srs_app_http_api.cpp
index 5c95af7b0..0f3aac193 100644
--- a/trunk/src/app/srs_app_http_api.cpp
+++ b/trunk/src/app/srs_app_http_api.cpp
@@ -473,8 +473,8 @@ int SrsGoApiStreams::serve_http(ISrsHttpResponseWriter* w, SrsHttpMessage* r)
return srs_go_http_response_json(w, ss.str());
}
-SrsHttpApi::SrsHttpApi(SrsServer* svr, st_netfd_t fd, SrsHttpServeMux* m)
- : SrsConnection(svr, fd)
+SrsHttpApi::SrsHttpApi(IConnectionManager* cm, st_netfd_t fd, SrsHttpServeMux* m)
+ : SrsConnection(cm, fd)
{
mux = m;
parser = new SrsHttpParser();
diff --git a/trunk/src/app/srs_app_http_api.hpp b/trunk/src/app/srs_app_http_api.hpp
index 6251fa30c..66e971088 100644
--- a/trunk/src/app/srs_app_http_api.hpp
+++ b/trunk/src/app/srs_app_http_api.hpp
@@ -166,7 +166,7 @@ private:
SrsHttpServeMux* mux;
bool crossdomain_required;
public:
- SrsHttpApi(SrsServer* svr, st_netfd_t fd, SrsHttpServeMux* m);
+ SrsHttpApi(IConnectionManager* cm, st_netfd_t fd, SrsHttpServeMux* m);
virtual ~SrsHttpApi();
// interface IKbpsDelta
public:
diff --git a/trunk/src/app/srs_app_http_conn.cpp b/trunk/src/app/srs_app_http_conn.cpp
index 43fa69e0b..c6f4b94b5 100644
--- a/trunk/src/app/srs_app_http_conn.cpp
+++ b/trunk/src/app/srs_app_http_conn.cpp
@@ -1334,11 +1334,11 @@ int SrsHttpServer::initialize_hls_streaming()
return ret;
}
-SrsHttpConn::SrsHttpConn(SrsServer* svr, st_netfd_t fd, SrsHttpServer* m)
- : SrsConnection(svr, fd)
+SrsHttpConn::SrsHttpConn(IConnectionManager* cm, st_netfd_t fd, SrsHttpServeMux* m)
+ : SrsConnection(cm, fd)
{
parser = new SrsHttpParser();
- http_server = m;
+ http_mux = m;
}
SrsHttpConn::~SrsHttpConn()
@@ -1424,7 +1424,7 @@ int SrsHttpConn::process_request(ISrsHttpResponseWriter* w, SrsHttpMessage* r)
r->method_str().c_str(), r->url().c_str(), r->content_length());
// use default server mux to serve http request.
- if ((ret = http_server->mux.serve_http(w, r)) != ERROR_SUCCESS) {
+ if ((ret = http_mux->serve_http(w, r)) != ERROR_SUCCESS) {
if (!srs_is_client_gracefully_close(ret)) {
srs_error("serve http msg failed. ret=%d", ret);
}
diff --git a/trunk/src/app/srs_app_http_conn.hpp b/trunk/src/app/srs_app_http_conn.hpp
index 418364294..63f87a5ff 100644
--- a/trunk/src/app/srs_app_http_conn.hpp
+++ b/trunk/src/app/srs_app_http_conn.hpp
@@ -39,6 +39,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include
#include
+class SrsServer;
class SrsSource;
class SrsRequest;
class SrsConsumer;
@@ -375,9 +376,9 @@ class SrsHttpConn : public SrsConnection
{
private:
SrsHttpParser* parser;
- SrsHttpServer* http_server;
+ SrsHttpServeMux* http_mux;
public:
- SrsHttpConn(SrsServer* svr, st_netfd_t fd, SrsHttpServer* m);
+ SrsHttpConn(IConnectionManager* cm, st_netfd_t fd, SrsHttpServeMux* m);
virtual ~SrsHttpConn();
// interface IKbpsDelta
public:
diff --git a/trunk/src/app/srs_app_rtmp_conn.cpp b/trunk/src/app/srs_app_rtmp_conn.cpp
index 588a6cdf4..6b0583f49 100644
--- a/trunk/src/app/srs_app_rtmp_conn.cpp
+++ b/trunk/src/app/srs_app_rtmp_conn.cpp
@@ -75,12 +75,13 @@ using namespace std;
// when edge timeout, retry next.
#define SRS_EDGE_TOKEN_TRAVERSE_TIMEOUT_US (int64_t)(3*1000*1000LL)
-SrsRtmpConn::SrsRtmpConn(SrsServer* srs_server, st_netfd_t client_stfd)
- : SrsConnection(srs_server, client_stfd)
+SrsRtmpConn::SrsRtmpConn(SrsServer* svr, st_netfd_t c)
+ : SrsConnection(svr, c)
{
+ server = svr;
req = new SrsRequest();
res = new SrsResponse();
- skt = new SrsStSocket(client_stfd);
+ skt = new SrsStSocket(c);
rtmp = new SrsRtmpServer(skt);
refer = new SrsRefer();
bandwidth = new SrsBandwidth();
diff --git a/trunk/src/app/srs_app_rtmp_conn.hpp b/trunk/src/app/srs_app_rtmp_conn.hpp
index 7c1a2205a..39aad6e0e 100644
--- a/trunk/src/app/srs_app_rtmp_conn.hpp
+++ b/trunk/src/app/srs_app_rtmp_conn.hpp
@@ -34,6 +34,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include
#include
+class SrsServer;
class SrsRtmpServer;
class SrsRequest;
class SrsResponse;
@@ -61,6 +62,7 @@ class SrsRtmpConn : public virtual SrsConnection, public virtual ISrsReloadHandl
// for the thread to directly access any field of connection.
friend class SrsPublishRecvThread;
private:
+ SrsServer* server;
SrsRequest* req;
SrsResponse* res;
SrsStSocket* skt;
@@ -81,7 +83,7 @@ private:
// @see https://github.com/simple-rtmp-server/srs/issues/257
bool realtime;
public:
- SrsRtmpConn(SrsServer* srs_server, st_netfd_t client_stfd);
+ SrsRtmpConn(SrsServer* svr, st_netfd_t c);
virtual ~SrsRtmpConn();
protected:
virtual int do_cycle();
diff --git a/trunk/src/app/srs_app_server.cpp b/trunk/src/app/srs_app_server.cpp
index 3c21a542b..851c8023c 100644
--- a/trunk/src/app/srs_app_server.cpp
+++ b/trunk/src/app/srs_app_server.cpp
@@ -46,6 +46,7 @@ using namespace std;
#include
#include
#include
+#include
// signal defines.
#define SIGNAL_RELOAD SIGHUP
@@ -105,6 +106,8 @@ std::string srs_listener_type2string(SrsListenerType type)
return "MPEG-TS over UDP";
case SrsListenerRtsp:
return "RTSP";
+ case SrsListenerFlv:
+ return "HTTP-FLV";
default:
return "UNKONWN";
}
@@ -206,7 +209,7 @@ int SrsRtspListener::listen(string ip, int port)
listener = new SrsTcpListener(this, ip, port);
if ((ret = listener->listen()) != ERROR_SUCCESS) {
- srs_error("udp caster listen failed. ret=%d", ret);
+ srs_error("rtsp caster listen failed. ret=%d", ret);
return ret;
}
@@ -231,6 +234,68 @@ int SrsRtspListener::on_tcp_client(st_netfd_t stfd)
return ret;
}
+SrsHttpFlvListener::SrsHttpFlvListener(SrsServer* server, SrsListenerType type, SrsConfDirective* c) : SrsListener(server, type)
+{
+ listener = NULL;
+
+ // the caller already ensure the type is ok,
+ // we just assert here for unknown stream caster.
+ srs_assert(_type == SrsListenerFlv);
+ if (_type == SrsListenerFlv) {
+ caster = new SrsAppCasterFlv(c);
+ }
+}
+
+SrsHttpFlvListener::~SrsHttpFlvListener()
+{
+ srs_freep(caster);
+ srs_freep(listener);
+}
+
+int SrsHttpFlvListener::listen(string ip, int port)
+{
+ int ret = ERROR_SUCCESS;
+
+ // the caller already ensure the type is ok,
+ // we just assert here for unknown stream caster.
+ srs_assert(_type == SrsListenerFlv);
+
+ _ip = ip;
+ _port = port;
+
+ if ((ret = caster->initialize()) != ERROR_SUCCESS) {
+ return ret;
+ }
+
+ srs_freep(listener);
+ listener = new SrsTcpListener(this, ip, port);
+
+ if ((ret = listener->listen()) != ERROR_SUCCESS) {
+ srs_error("flv caster listen failed. ret=%d", ret);
+ return ret;
+ }
+
+ srs_info("listen thread cid=%d, current_cid=%d, "
+ "listen at port=%d, type=%d, fd=%d started success, ep=%s:%d",
+ pthread->cid(), _srs_context->get_id(), _port, _type, fd, ip.c_str(), port);
+
+ srs_trace("%s listen at tcp://%s:%d, fd=%d", srs_listener_type2string(_type).c_str(), ip.c_str(), _port, listener->fd());
+
+ return ret;
+}
+
+int SrsHttpFlvListener::on_tcp_client(st_netfd_t stfd)
+{
+ int ret = ERROR_SUCCESS;
+
+ if ((ret = caster->on_tcp_client(stfd)) != ERROR_SUCCESS) {
+ srs_warn("accept client error. ret=%d", ret);
+ return ret;
+ }
+
+ return ret;
+}
+
SrsUdpCasterListener::SrsUdpCasterListener(SrsServer* server, SrsListenerType type, SrsConfDirective* c) : SrsListener(server, type)
{
_type = type;
@@ -1003,6 +1068,8 @@ int SrsServer::listen_stream_caster()
listener = new SrsUdpCasterListener(this, SrsListenerMpegTsOverUdp, stream_caster);
} else if (caster == SRS_CONF_DEFAULT_STREAM_CASTER_RTSP) {
listener = new SrsRtspListener(this, SrsListenerRtsp, stream_caster);
+ } else if (caster == SRS_CONF_DEFAULT_STREAM_CASTER_FLV) {
+ listener = new SrsHttpFlvListener(this, SrsListenerFlv, stream_caster);
} else {
ret = ERROR_STREAM_CASTER_ENGINE;
srs_error("unsupported stream caster %s. ret=%d", caster.c_str(), ret);
@@ -1096,7 +1163,7 @@ int SrsServer::accept_client(SrsListenerType type, st_netfd_t client_stfd)
#endif
} else if (type == SrsListenerHttpStream) {
#ifdef SRS_AUTO_HTTP_SERVER
- conn = new SrsHttpConn(this, client_stfd, http_stream_mux);
+ conn = new SrsHttpConn(this, client_stfd, &http_stream_mux->mux);
#else
srs_warn("close http client for server not support http-server");
srs_close_stfd(client_stfd);
diff --git a/trunk/src/app/srs_app_server.hpp b/trunk/src/app/srs_app_server.hpp
index 1bad2d8b1..1ff7cee90 100644
--- a/trunk/src/app/srs_app_server.hpp
+++ b/trunk/src/app/srs_app_server.hpp
@@ -38,6 +38,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include
#include
#include
+#include
class SrsServer;
class SrsConnection;
@@ -51,6 +52,9 @@ class ISrsTcpHandler;
class ISrsUdpHandler;
class SrsUdpListener;
class SrsTcpListener;
+#ifdef SRS_AUTO_STREAM_CASTER
+class SrsAppCasterFlv;
+#endif
// listener type for server to identify the connection,
// that is, use different type to process the connection.
@@ -66,6 +70,8 @@ enum SrsListenerType
SrsListenerMpegTsOverUdp = 3,
// TCP stream, RTSP stream.
SrsListenerRtsp = 4,
+ // TCP stream, FLV stream over HTTP.
+ SrsListenerFlv = 5,
};
/**
@@ -123,6 +129,24 @@ public:
virtual int on_tcp_client(st_netfd_t stfd);
};
+/**
+ * the tcp listener, for flv stream server.
+ */
+class SrsHttpFlvListener : virtual public SrsListener, virtual public ISrsTcpHandler
+{
+private:
+ SrsTcpListener* listener;
+ SrsAppCasterFlv* caster;
+public:
+ SrsHttpFlvListener(SrsServer* server, SrsListenerType type, SrsConfDirective* c);
+ virtual ~SrsHttpFlvListener();
+public:
+ virtual int listen(std::string ip, int port);
+// ISrsTcpHandler
+public:
+ virtual int on_tcp_client(st_netfd_t stfd);
+};
+
/**
* the udp listener, for udp server.
*/
@@ -195,6 +219,7 @@ public:
*/
class SrsServer : virtual public ISrsReloadHandler
, virtual public ISrsSourceHandler, virtual public ISrsHlsHandler
+ , virtual public IConnectionManager
{
private:
#ifdef SRS_AUTO_HTTP_API
@@ -259,7 +284,7 @@ public:
virtual int http_handle();
virtual int ingest();
virtual int cycle();
-// server utility
+// IConnectionManager
public:
/**
* callback for connection to remove itself.
@@ -267,6 +292,8 @@ public:
* @see SrsConnection.on_thread_stop().
*/
virtual void remove(SrsConnection* conn);
+// server utilities.
+public:
/**
* callback for signal manager got a signal.
* the signal manager convert signal to io message,