for #324, support hstrs(http stream trigger rtmp source) origin mode. 2.0.139.
正在显示
8 个修改的文件
包含
117 行增加
和
7 行删除
| @@ -21,7 +21,9 @@ Download from ossrs.net: | @@ -21,7 +21,9 @@ Download from ossrs.net: | ||
| 21 | RTSP/MPEGTS-over-UDP. | 21 | RTSP/MPEGTS-over-UDP. |
| 22 | 1. Popular internet delivery: RTMP/HDS for flash, HLS for mobile(IOS/IPad/MAC/Android), HTTP | 22 | 1. Popular internet delivery: RTMP/HDS for flash, HLS for mobile(IOS/IPad/MAC/Android), HTTP |
| 23 | flv/ts/mp3/aac streaming for user prefered. | 23 | flv/ts/mp3/aac streaming for user prefered. |
| 24 | -1. Enhanced DVR: segment/session/append plan, customer path and HTTP callback. | 24 | +1. Enhanced DVR and hstrs: segment/session/append plan, customer path and HTTP callback. |
| 25 | +the hstrs(http stream trigger rtmp source) enable the http-flv stream standby util encoder | ||
| 26 | +start publish, similar to rtmp, which will trigger edge to fetch from origin. | ||
| 25 | 1. Multiple feature: transcode, forward, ingest, http hooks, dvr, hls, rtsp, http streaming, | 27 | 1. Multiple feature: transcode, forward, ingest, http hooks, dvr, hls, rtsp, http streaming, |
| 26 | http api, refer, log, bandwith test and srs-librtmp. | 28 | http api, refer, log, bandwith test and srs-librtmp. |
| 27 | 1. Best maintainess: simple arch over state-threads(coroutine), single thread, single process | 29 | 1. Best maintainess: simple arch over state-threads(coroutine), single thread, single process |
| @@ -558,6 +560,7 @@ Supported operating systems and hardware: | @@ -558,6 +560,7 @@ Supported operating systems and hardware: | ||
| 558 | 560 | ||
| 559 | ### SRS 2.0 history | 561 | ### SRS 2.0 history |
| 560 | 562 | ||
| 563 | +* v2.0, 2015-03-14, for [#324](https://github.com/winlinvip/simple-rtmp-server/issues/324), support hstrs(http stream trigger rtmp source) origin mode. 2.0.139. | ||
| 561 | * v2.0, 2015-03-12, fix [#328](https://github.com/winlinvip/simple-rtmp-server/issues/328), support adobe hds. 2.0.138. | 564 | * v2.0, 2015-03-12, fix [#328](https://github.com/winlinvip/simple-rtmp-server/issues/328), support adobe hds. 2.0.138. |
| 562 | * v2.0, 2015-03-10, fix [#155](https://github.com/winlinvip/simple-rtmp-server/issues/155), support osx(darwin) for mac pro. 2.0.137. | 565 | * v2.0, 2015-03-10, fix [#155](https://github.com/winlinvip/simple-rtmp-server/issues/155), support osx(darwin) for mac pro. 2.0.137. |
| 563 | * v2.0, 2015-03-08, fix [#316](https://github.com/winlinvip/simple-rtmp-server/issues/316), http api provides stream/vhost/srs/server bytes, codec and count. 2.0.136. | 566 | * v2.0, 2015-03-08, fix [#316](https://github.com/winlinvip/simple-rtmp-server/issues/316), http api provides stream/vhost/srs/server bytes, codec and count. 2.0.136. |
| @@ -40,6 +40,8 @@ using namespace std; | @@ -40,6 +40,8 @@ using namespace std; | ||
| 40 | #include <srs_kernel_file.hpp> | 40 | #include <srs_kernel_file.hpp> |
| 41 | #include <srs_core_autofree.hpp> | 41 | #include <srs_core_autofree.hpp> |
| 42 | #include <srs_rtmp_buffer.hpp> | 42 | #include <srs_rtmp_buffer.hpp> |
| 43 | +#include <srs_rtmp_sdk.hpp> | ||
| 44 | +#include <srs_rtmp_utility.hpp> | ||
| 43 | 45 | ||
| 44 | #define SRS_DEFAULT_HTTP_PORT 80 | 46 | #define SRS_DEFAULT_HTTP_PORT 80 |
| 45 | 47 | ||
| @@ -1286,6 +1288,32 @@ string SrsHttpMessage::get_request_header(string name) | @@ -1286,6 +1288,32 @@ string SrsHttpMessage::get_request_header(string name) | ||
| 1286 | return ""; | 1288 | return ""; |
| 1287 | } | 1289 | } |
| 1288 | 1290 | ||
| 1291 | +SrsRequest* SrsHttpMessage::to_request(string vhost) | ||
| 1292 | +{ | ||
| 1293 | + SrsRequest* req = new SrsRequest(); | ||
| 1294 | + | ||
| 1295 | + req->app = _uri->get_path(); | ||
| 1296 | + ssize_t pos = string::npos; | ||
| 1297 | + if ((pos = req->app.rfind("/")) != string::npos) { | ||
| 1298 | + req->stream = req->app.substr(pos + 1); | ||
| 1299 | + req->app = req->app.substr(0, pos); | ||
| 1300 | + } | ||
| 1301 | + if ((pos = req->stream.rfind(".")) != string::npos) { | ||
| 1302 | + req->stream = req->stream.substr(0, pos); | ||
| 1303 | + } | ||
| 1304 | + | ||
| 1305 | + req->tcUrl = "rtmp://" + vhost + req->app; | ||
| 1306 | + req->pageUrl = get_request_header("Referer"); | ||
| 1307 | + req->objectEncoding = 0; | ||
| 1308 | + | ||
| 1309 | + srs_discovery_tc_url(req->tcUrl, | ||
| 1310 | + req->schema, req->host, req->vhost, req->app, req->port, | ||
| 1311 | + req->param); | ||
| 1312 | + req->strip(); | ||
| 1313 | + | ||
| 1314 | + return req; | ||
| 1315 | +} | ||
| 1316 | + | ||
| 1289 | SrsHttpParser::SrsHttpParser() | 1317 | SrsHttpParser::SrsHttpParser() |
| 1290 | { | 1318 | { |
| 1291 | buffer = new SrsFastBuffer(); | 1319 | buffer = new SrsFastBuffer(); |
| @@ -565,6 +565,12 @@ public: | @@ -565,6 +565,12 @@ public: | ||
| 565 | virtual std::string request_header_key_at(int index); | 565 | virtual std::string request_header_key_at(int index); |
| 566 | virtual std::string request_header_value_at(int index); | 566 | virtual std::string request_header_value_at(int index); |
| 567 | virtual std::string get_request_header(std::string name); | 567 | virtual std::string get_request_header(std::string name); |
| 568 | +public: | ||
| 569 | + /** | ||
| 570 | + * convert the http message to a request. | ||
| 571 | + * @remark user must free the return request. | ||
| 572 | + */ | ||
| 573 | + virtual SrsRequest* to_request(std::string vhost); | ||
| 568 | }; | 574 | }; |
| 569 | 575 | ||
| 570 | /** | 576 | /** |
| @@ -48,6 +48,8 @@ using namespace std; | @@ -48,6 +48,8 @@ using namespace std; | ||
| 48 | #include <srs_kernel_mp3.hpp> | 48 | #include <srs_kernel_mp3.hpp> |
| 49 | #include <srs_kernel_ts.hpp> | 49 | #include <srs_kernel_ts.hpp> |
| 50 | #include <srs_app_pithy_print.hpp> | 50 | #include <srs_app_pithy_print.hpp> |
| 51 | +#include <srs_app_source.hpp> | ||
| 52 | +#include <srs_app_server.hpp> | ||
| 51 | 53 | ||
| 52 | SrsVodStream::SrsVodStream(string root_dir) | 54 | SrsVodStream::SrsVodStream(string root_dir) |
| 53 | : SrsHttpFileServer(root_dir) | 55 | : SrsHttpFileServer(root_dir) |
| @@ -796,8 +798,10 @@ SrsHlsEntry::SrsHlsEntry() | @@ -796,8 +798,10 @@ SrsHlsEntry::SrsHlsEntry() | ||
| 796 | { | 798 | { |
| 797 | } | 799 | } |
| 798 | 800 | ||
| 799 | -SrsHttpServer::SrsHttpServer() | 801 | +SrsHttpServer::SrsHttpServer(SrsServer* svr) |
| 800 | { | 802 | { |
| 803 | + server = svr; | ||
| 804 | + | ||
| 801 | mux.hijack(this); | 805 | mux.hijack(this); |
| 802 | } | 806 | } |
| 803 | 807 | ||
| @@ -1110,11 +1114,76 @@ int SrsHttpServer::hijack(SrsHttpMessage* request, ISrsHttpHandler** ph) | @@ -1110,11 +1114,76 @@ int SrsHttpServer::hijack(SrsHttpMessage* request, ISrsHttpHandler** ph) | ||
| 1110 | if (ext.empty()) { | 1114 | if (ext.empty()) { |
| 1111 | return ret; | 1115 | return ret; |
| 1112 | } | 1116 | } |
| 1113 | - if (ext != ".flv" && ext != ".ts" && ext != ".mp3" && ext != ".aac") { | 1117 | + |
| 1118 | + // find the actually request vhost. | ||
| 1119 | + SrsConfDirective* vhost = _srs_config->get_vhost(request->host()); | ||
| 1120 | + if (!vhost || !_srs_config->get_vhost_enabled(vhost)) { | ||
| 1114 | return ret; | 1121 | return ret; |
| 1115 | } | 1122 | } |
| 1116 | 1123 | ||
| 1117 | - // TODO: FIXME: implements it. | 1124 | + // find the entry template for the stream. |
| 1125 | + SrsLiveEntry* entry = NULL; | ||
| 1126 | + if (true) { | ||
| 1127 | + // no http streaming on vhost, ignore. | ||
| 1128 | + std::map<std::string, SrsLiveEntry*>::iterator it = tflvs.find(vhost->arg0()); | ||
| 1129 | + if (it == tflvs.end()) { | ||
| 1130 | + return ret; | ||
| 1131 | + } | ||
| 1132 | + | ||
| 1133 | + // hstrs not enabled, ignore. | ||
| 1134 | + entry = it->second; | ||
| 1135 | + if (!entry->hstrs) { | ||
| 1136 | + return ret; | ||
| 1137 | + } | ||
| 1138 | + | ||
| 1139 | + // check entry and request extension. | ||
| 1140 | + if (entry->is_flv()) { | ||
| 1141 | + if (ext != ".flv") { | ||
| 1142 | + return ret; | ||
| 1143 | + } | ||
| 1144 | + } else if (entry->is_ts()) { | ||
| 1145 | + if (ext != ".ts") { | ||
| 1146 | + return ret; | ||
| 1147 | + } | ||
| 1148 | + } else if (entry->is_mp3()) { | ||
| 1149 | + if (ext != ".mp3") { | ||
| 1150 | + return ret; | ||
| 1151 | + } | ||
| 1152 | + } else if (entry->is_aac()) { | ||
| 1153 | + if (ext != ".aac") { | ||
| 1154 | + return ret; | ||
| 1155 | + } | ||
| 1156 | + } else { | ||
| 1157 | + return ret; | ||
| 1158 | + } | ||
| 1159 | + } | ||
| 1160 | + | ||
| 1161 | + // hijack for entry. | ||
| 1162 | + SrsRequest* r = request->to_request(vhost->arg0()); | ||
| 1163 | + SrsAutoFree(SrsRequest, r); | ||
| 1164 | + SrsSource* s = SrsSource::fetch(r); | ||
| 1165 | + if (!s) { | ||
| 1166 | + if ((ret = SrsSource::create(r, server, server, &s)) != ERROR_SUCCESS) { | ||
| 1167 | + return ret; | ||
| 1168 | + } | ||
| 1169 | + } | ||
| 1170 | + srs_assert(s != NULL); | ||
| 1171 | + | ||
| 1172 | + // create http streaming handler. | ||
| 1173 | + if ((ret = http_mount(s, r)) != ERROR_SUCCESS) { | ||
| 1174 | + return ret; | ||
| 1175 | + } | ||
| 1176 | + | ||
| 1177 | + // use the handler if exists. | ||
| 1178 | + if (ph) { | ||
| 1179 | + std::string sid = r->get_stream_url(); | ||
| 1180 | + if (sflvs.find(sid) != sflvs.end()) { | ||
| 1181 | + entry = sflvs[sid]; | ||
| 1182 | + *ph = entry->stream; | ||
| 1183 | + srs_trace("hstrs sid=%s", sid.c_str()); | ||
| 1184 | + } | ||
| 1185 | + } | ||
| 1186 | + | ||
| 1118 | return ret; | 1187 | return ret; |
| 1119 | } | 1188 | } |
| 1120 | 1189 |
| @@ -330,6 +330,8 @@ struct SrsHlsEntry | @@ -330,6 +330,8 @@ struct SrsHlsEntry | ||
| 330 | class SrsHttpServer : virtual public ISrsReloadHandler | 330 | class SrsHttpServer : virtual public ISrsReloadHandler |
| 331 | , virtual public ISrsHttpMatchHijacker | 331 | , virtual public ISrsHttpMatchHijacker |
| 332 | { | 332 | { |
| 333 | +private: | ||
| 334 | + SrsServer* server; | ||
| 333 | public: | 335 | public: |
| 334 | SrsHttpServeMux mux; | 336 | SrsHttpServeMux mux; |
| 335 | // the http live streaming template, to create streams. | 337 | // the http live streaming template, to create streams. |
| @@ -341,7 +343,7 @@ public: | @@ -341,7 +343,7 @@ public: | ||
| 341 | // the hls live streaming streams, crote by template. | 343 | // the hls live streaming streams, crote by template. |
| 342 | std::map<std::string, SrsHlsEntry*> shls; | 344 | std::map<std::string, SrsHlsEntry*> shls; |
| 343 | public: | 345 | public: |
| 344 | - SrsHttpServer(); | 346 | + SrsHttpServer(SrsServer* svr); |
| 345 | virtual ~SrsHttpServer(); | 347 | virtual ~SrsHttpServer(); |
| 346 | public: | 348 | public: |
| 347 | virtual int initialize(); | 349 | virtual int initialize(); |
| @@ -296,6 +296,7 @@ int SrsRtmpConn::service_cycle() | @@ -296,6 +296,7 @@ int SrsRtmpConn::service_cycle() | ||
| 296 | 296 | ||
| 297 | // do token traverse before serve it. | 297 | // do token traverse before serve it. |
| 298 | // @see https://github.com/winlinvip/simple-rtmp-server/pull/239 | 298 | // @see https://github.com/winlinvip/simple-rtmp-server/pull/239 |
| 299 | + if (true) { | ||
| 299 | bool vhost_is_edge = _srs_config->get_vhost_is_edge(req->vhost); | 300 | bool vhost_is_edge = _srs_config->get_vhost_is_edge(req->vhost); |
| 300 | bool edge_traverse = _srs_config->get_vhost_edge_token_traverse(req->vhost); | 301 | bool edge_traverse = _srs_config->get_vhost_edge_token_traverse(req->vhost); |
| 301 | if (vhost_is_edge && edge_traverse) { | 302 | if (vhost_is_edge && edge_traverse) { |
| @@ -304,6 +305,7 @@ int SrsRtmpConn::service_cycle() | @@ -304,6 +305,7 @@ int SrsRtmpConn::service_cycle() | ||
| 304 | return ret; | 305 | return ret; |
| 305 | } | 306 | } |
| 306 | } | 307 | } |
| 308 | + } | ||
| 307 | 309 | ||
| 308 | // response the client connect ok. | 310 | // response the client connect ok. |
| 309 | if ((ret = rtmp->response_connect_app(req, local_ip.c_str())) != ERROR_SUCCESS) { | 311 | if ((ret = rtmp->response_connect_app(req, local_ip.c_str())) != ERROR_SUCCESS) { |
| @@ -401,7 +401,7 @@ SrsServer::SrsServer() | @@ -401,7 +401,7 @@ SrsServer::SrsServer() | ||
| 401 | http_api_mux = new SrsHttpServeMux(); | 401 | http_api_mux = new SrsHttpServeMux(); |
| 402 | #endif | 402 | #endif |
| 403 | #ifdef SRS_AUTO_HTTP_SERVER | 403 | #ifdef SRS_AUTO_HTTP_SERVER |
| 404 | - http_stream_mux = new SrsHttpServer(); | 404 | + http_stream_mux = new SrsHttpServer(this); |
| 405 | #endif | 405 | #endif |
| 406 | #ifdef SRS_AUTO_HTTP_PARSER | 406 | #ifdef SRS_AUTO_HTTP_PARSER |
| 407 | http_heartbeat = NULL; | 407 | http_heartbeat = NULL; |
| @@ -31,7 +31,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | @@ -31,7 +31,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
| 31 | // current release version | 31 | // current release version |
| 32 | #define VERSION_MAJOR 2 | 32 | #define VERSION_MAJOR 2 |
| 33 | #define VERSION_MINOR 0 | 33 | #define VERSION_MINOR 0 |
| 34 | -#define VERSION_REVISION 138 | 34 | +#define VERSION_REVISION 139 |
| 35 | 35 | ||
| 36 | // server info. | 36 | // server info. |
| 37 | #define RTMP_SIG_SRS_KEY "SRS" | 37 | #define RTMP_SIG_SRS_KEY "SRS" |
-
请 注册 或 登录 后发表评论