From f0c24eeacc5a0a351bd2a660d887ba6729231bca Mon Sep 17 00:00:00 2001 From: winlin Date: Sun, 3 May 2015 10:56:20 +0800 Subject: [PATCH] add stream caster for post flv over http. --- trunk/conf/full.conf | 7 +++ trunk/configure | 3 +- trunk/ide/srs_upp/srs_upp.upp | 2 + trunk/ide/srs_vs2010/srs.vcxproj | 4 +- .../srs_xcode.xcodeproj/project.pbxproj | 6 ++ trunk/src/app/srs_app_caster_flv.cpp | 48 ++++++++++++++ trunk/src/app/srs_app_caster_flv.hpp | 52 +++++++++++++++ trunk/src/app/srs_app_config.hpp | 1 + trunk/src/app/srs_app_server.cpp | 63 ++++++++++++++++++- trunk/src/app/srs_app_server.hpp | 20 ++++++ 10 files changed, 203 insertions(+), 3 deletions(-) create mode 100644 trunk/src/app/srs_app_caster_flv.cpp create mode 100644 trunk/src/app/srs_app_caster_flv.hpp 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. */