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..11a4f1a03
--- /dev/null
+++ b/trunk/src/app/srs_app_caster_flv.cpp
@@ -0,0 +1,48 @@
+/*
+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
+#include
+#include
+#include
+#include
+
+SrsAppCasterFlv::SrsAppCasterFlv(SrsConfDirective* c)
+{
+}
+
+SrsAppCasterFlv::~SrsAppCasterFlv()
+{
+}
+
+int SrsAppCasterFlv::on_tcp_client(st_netfd_t stfd)
+{
+ int ret = ERROR_SUCCESS;
+ 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..6d0015e8c
--- /dev/null
+++ b/trunk/src/app/srs_app_caster_flv.hpp
@@ -0,0 +1,52 @@
+/*
+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
+
+#ifdef SRS_AUTO_STREAM_CASTER
+
+class SrsConfDirective;
+
+#include
+#include
+
+class SrsAppCasterFlv : public ISrsTcpHandler
+{
+public:
+ SrsAppCasterFlv(SrsConfDirective* c);
+ virtual ~SrsAppCasterFlv();
+// ISrsTcpHandler
+public:
+ virtual int on_tcp_client(st_netfd_t stfd);
+};
+
+#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_server.cpp b/trunk/src/app/srs_app_server.cpp
index 3c21a542b..b522c2545 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
@@ -206,7 +207,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 +232,64 @@ 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 == SrsListenerRtsp);
+ if (_type == SrsListenerRtsp) {
+ 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 == SrsListenerRtsp);
+
+ _ip = ip;
+ _port = port;
+
+ 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 +1062,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);
diff --git a/trunk/src/app/srs_app_server.hpp b/trunk/src/app/srs_app_server.hpp
index 1bad2d8b1..b2ecafbb1 100644
--- a/trunk/src/app/srs_app_server.hpp
+++ b/trunk/src/app/srs_app_server.hpp
@@ -66,6 +66,8 @@ enum SrsListenerType
SrsListenerMpegTsOverUdp = 3,
// TCP stream, RTSP stream.
SrsListenerRtsp = 4,
+ // HTTP stream, FLV over HTTP POST.
+ SrsListenerFlv = 5,
};
/**
@@ -123,6 +125,24 @@ public:
virtual int on_tcp_client(st_netfd_t stfd);
};
+/**
+ * the tcp listener, for http flv server.
+ */
+class SrsHttpFlvListener : virtual public SrsListener, virtual public ISrsTcpHandler
+{
+private:
+ SrsTcpListener* listener;
+ ISrsTcpHandler* 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.
*/