fix #274: http-callback support on_dvr when reap a dvr file. 2.0.89
正在显示
12 个修改的文件
包含
207 行增加
和
7 行删除
| @@ -501,6 +501,7 @@ Supported operating systems and hardware: | @@ -501,6 +501,7 @@ Supported operating systems and hardware: | ||
| 501 | * 2013-10-17, Created.<br/> | 501 | * 2013-10-17, Created.<br/> |
| 502 | 502 | ||
| 503 | ## History | 503 | ## History |
| 504 | +* v2.0, 2015-01-03, fix [#274](https://github.com/winlinvip/simple-rtmp-server/issues/274), http-callback support on_dvr when reap a dvr file. 2.0.89 | ||
| 504 | * v2.0, 2015-01-03, hotfix to remove the pageUrl for http callback. 2.0.88 | 505 | * v2.0, 2015-01-03, hotfix to remove the pageUrl for http callback. 2.0.88 |
| 505 | * v2.0, 2015-01-03, fix [#179](https://github.com/winlinvip/simple-rtmp-server/issues/179), dvr support custom filepath by variables. 2.0.87 | 506 | * v2.0, 2015-01-03, fix [#179](https://github.com/winlinvip/simple-rtmp-server/issues/179), dvr support custom filepath by variables. 2.0.87 |
| 506 | * v2.0, 2015-01-02, fix [#211](https://github.com/winlinvip/simple-rtmp-server/issues/211), support security allow/deny publish/play all/ip. 2.0.86 | 507 | * v2.0, 2015-01-02, fix [#211](https://github.com/winlinvip/simple-rtmp-server/issues/211), support security allow/deny publish/play all/ip. 2.0.86 |
| @@ -296,6 +296,11 @@ vhost dvr.srs.com { | @@ -296,6 +296,11 @@ vhost dvr.srs.com { | ||
| 296 | # 3. off, disable the time jitter algorithm, like atc. | 296 | # 3. off, disable the time jitter algorithm, like atc. |
| 297 | # default: full | 297 | # default: full |
| 298 | time_jitter full; | 298 | time_jitter full; |
| 299 | + | ||
| 300 | + # on_dvr | ||
| 301 | + # for the dvr http callback, @see http_hooks.on_dvr of vhost hooks.callback.srs.com | ||
| 302 | + # @read https://github.com/winlinvip/simple-rtmp-server/wiki/v2_CN_DVR#http-callback | ||
| 303 | + # @read https://github.com/winlinvip/simple-rtmp-server/wiki/v2_EN_DVR#http-callback | ||
| 299 | } | 304 | } |
| 300 | } | 305 | } |
| 301 | 306 | ||
| @@ -338,7 +343,7 @@ vhost ingest.srs.com { | @@ -338,7 +343,7 @@ vhost ingest.srs.com { | ||
| 338 | } | 343 | } |
| 339 | } | 344 | } |
| 340 | 345 | ||
| 341 | -# vhost for http | 346 | +# vhost for http server config in each vhost. |
| 342 | vhost http.srs.com { | 347 | vhost http.srs.com { |
| 343 | # http vhost specified config | 348 | # http vhost specified config |
| 344 | http { | 349 | http { |
| @@ -490,6 +495,20 @@ vhost hooks.callback.srs.com { | @@ -490,6 +495,20 @@ vhost hooks.callback.srs.com { | ||
| 490 | # support multiple api hooks, format: | 495 | # support multiple api hooks, format: |
| 491 | # on_stop http://xxx/api0 http://xxx/api1 http://xxx/apiN | 496 | # on_stop http://xxx/api0 http://xxx/api1 http://xxx/apiN |
| 492 | on_stop http://127.0.0.1:8085/api/v1/sessions http://localhost:8085/api/v1/sessions; | 497 | on_stop http://127.0.0.1:8085/api/v1/sessions http://localhost:8085/api/v1/sessions; |
| 498 | + # when srs reap a dvr file, call the hook, | ||
| 499 | + # the request in the POST data string is a object encode by json: | ||
| 500 | + # { | ||
| 501 | + # "action": "on_dvr", | ||
| 502 | + # "client_id": 1985, | ||
| 503 | + # "ip": "192.168.1.10", "vhost": "video.test.com", "app": "live", | ||
| 504 | + # "stream": "livestream", | ||
| 505 | + # "cwd": "/usr/local/srs", | ||
| 506 | + # "file": "./objs/nginx/html/live/livestream.1420254068776.flv" | ||
| 507 | + # } | ||
| 508 | + # if valid, the hook must return HTTP code 200(Stauts OK) and response | ||
| 509 | + # an int value specifies the error code(0 corresponding to success): | ||
| 510 | + # 0 | ||
| 511 | + on_dvr http://127.0.0.1:8085/api/v1/dvrs http://localhost:8085/api/v1/dvrs; | ||
| 493 | } | 512 | } |
| 494 | } | 513 | } |
| 495 | 514 |
| @@ -154,7 +154,7 @@ class RESTClients(object): | @@ -154,7 +154,7 @@ class RESTClients(object): | ||
| 154 | return code | 154 | return code |
| 155 | 155 | ||
| 156 | ''' | 156 | ''' |
| 157 | -handle the streams requests: publish/unpublish/dvr stream. | 157 | +handle the streams requests: publish/unpublish stream. |
| 158 | ''' | 158 | ''' |
| 159 | class RESTStreams(object): | 159 | class RESTStreams(object): |
| 160 | exposed = True | 160 | exposed = True |
| @@ -241,6 +241,74 @@ class RESTStreams(object): | @@ -241,6 +241,74 @@ class RESTStreams(object): | ||
| 241 | return code | 241 | return code |
| 242 | 242 | ||
| 243 | ''' | 243 | ''' |
| 244 | +handle the dvrs requests: dvr stream. | ||
| 245 | +''' | ||
| 246 | +class RESTDvrs(object): | ||
| 247 | + exposed = True | ||
| 248 | + | ||
| 249 | + def GET(self): | ||
| 250 | + enable_crossdomain() | ||
| 251 | + | ||
| 252 | + dvrs = {} | ||
| 253 | + return json.dumps(dvrs) | ||
| 254 | + | ||
| 255 | + ''' | ||
| 256 | + for SRS hook: on_dvr | ||
| 257 | + on_dvr: | ||
| 258 | + when srs reap a dvr file, call the hook, | ||
| 259 | + the request in the POST data string is a object encode by json: | ||
| 260 | + { | ||
| 261 | + "action": "on_dvr", | ||
| 262 | + "client_id": 1985, | ||
| 263 | + "ip": "192.168.1.10", "vhost": "video.test.com", "app": "live", | ||
| 264 | + "stream": "livestream", | ||
| 265 | + "cwd": "/usr/local/srs", | ||
| 266 | + "file": "./objs/nginx/html/live/livestream.1420254068776.flv" | ||
| 267 | + } | ||
| 268 | + if valid, the hook must return HTTP code 200(Stauts OK) and response | ||
| 269 | + an int value specifies the error code(0 corresponding to success): | ||
| 270 | + 0 | ||
| 271 | + ''' | ||
| 272 | + def POST(self): | ||
| 273 | + enable_crossdomain() | ||
| 274 | + | ||
| 275 | + # return the error code in str | ||
| 276 | + code = Error.success | ||
| 277 | + | ||
| 278 | + req = cherrypy.request.body.read() | ||
| 279 | + trace("post to dvrs, req=%s"%(req)) | ||
| 280 | + try: | ||
| 281 | + json_req = json.loads(req) | ||
| 282 | + except Exception, ex: | ||
| 283 | + code = Error.system_parse_json | ||
| 284 | + trace("parse the request to json failed, req=%s, ex=%s, code=%s"%(req, ex, code)) | ||
| 285 | + return str(code) | ||
| 286 | + | ||
| 287 | + action = json_req["action"] | ||
| 288 | + if action == "on_dvr": | ||
| 289 | + code = self.__on_dvr(json_req) | ||
| 290 | + else: | ||
| 291 | + trace("invalid request action: %s"%(json_req["action"])) | ||
| 292 | + code = Error.request_invalid_action | ||
| 293 | + | ||
| 294 | + return str(code) | ||
| 295 | + | ||
| 296 | + def OPTIONS(self, *args, **kwargs): | ||
| 297 | + enable_crossdomain() | ||
| 298 | + | ||
| 299 | + def __on_dvr(self, req): | ||
| 300 | + code = Error.success | ||
| 301 | + | ||
| 302 | + trace("srs %s: client id=%s, ip=%s, vhost=%s, app=%s, stream=%s, cwd=%s, file=%s"%( | ||
| 303 | + req["action"], req["client_id"], req["ip"], req["vhost"], req["app"], req["stream"], | ||
| 304 | + req["cwd"], req["file"] | ||
| 305 | + )) | ||
| 306 | + | ||
| 307 | + # TODO: process the on_dvr event | ||
| 308 | + | ||
| 309 | + return code | ||
| 310 | + | ||
| 311 | +''' | ||
| 244 | handle the sessions requests: client play/stop stream | 312 | handle the sessions requests: client play/stop stream |
| 245 | ''' | 313 | ''' |
| 246 | class RESTSessions(object): | 314 | class RESTSessions(object): |
| @@ -1039,6 +1107,7 @@ class V1(object): | @@ -1039,6 +1107,7 @@ class V1(object): | ||
| 1039 | self.clients = RESTClients() | 1107 | self.clients = RESTClients() |
| 1040 | self.streams = RESTStreams() | 1108 | self.streams = RESTStreams() |
| 1041 | self.sessions = RESTSessions() | 1109 | self.sessions = RESTSessions() |
| 1110 | + self.dvrs = RESTDvrs() | ||
| 1042 | self.chats = RESTChats() | 1111 | self.chats = RESTChats() |
| 1043 | self.servers = RESTServers() | 1112 | self.servers = RESTServers() |
| 1044 | self.nodes = RESTNodes() | 1113 | self.nodes = RESTNodes() |
| @@ -1048,6 +1117,7 @@ class V1(object): | @@ -1048,6 +1117,7 @@ class V1(object): | ||
| 1048 | "clients": "for srs http callback, to handle the clients requests: connect/disconnect vhost/app.", | 1117 | "clients": "for srs http callback, to handle the clients requests: connect/disconnect vhost/app.", |
| 1049 | "streams": "for srs http callback, to handle the streams requests: publish/unpublish stream.", | 1118 | "streams": "for srs http callback, to handle the streams requests: publish/unpublish stream.", |
| 1050 | "sessions": "for srs http callback, to handle the sessions requests: client play/stop stream", | 1119 | "sessions": "for srs http callback, to handle the sessions requests: client play/stop stream", |
| 1120 | + "dvrs": "for srs http callback, to handle the dvr requests: dvr stream.", | ||
| 1051 | "chats": "for srs demo meeting, the chat streams, public chat room.", | 1121 | "chats": "for srs demo meeting, the chat streams, public chat room.", |
| 1052 | "nodes": { | 1122 | "nodes": { |
| 1053 | "summary": "for srs cdn node", | 1123 | "summary": "for srs cdn node", |
| @@ -1426,6 +1426,7 @@ int SrsConfig::check_config() | @@ -1426,6 +1426,7 @@ int SrsConfig::check_config() | ||
| 1426 | string m = conf->at(j)->name.c_str(); | 1426 | string m = conf->at(j)->name.c_str(); |
| 1427 | if (m != "enabled" && m != "on_connect" && m != "on_close" && m != "on_publish" | 1427 | if (m != "enabled" && m != "on_connect" && m != "on_close" && m != "on_publish" |
| 1428 | && m != "on_unpublish" && m != "on_play" && m != "on_stop" | 1428 | && m != "on_unpublish" && m != "on_play" && m != "on_stop" |
| 1429 | + && m != "on_dvr" | ||
| 1429 | ) { | 1430 | ) { |
| 1430 | ret = ERROR_SYSTEM_CONFIG_INVALID; | 1431 | ret = ERROR_SYSTEM_CONFIG_INVALID; |
| 1431 | srs_error("unsupported vhost http_hooks directive %s, ret=%d", m.c_str(), ret); | 1432 | srs_error("unsupported vhost http_hooks directive %s, ret=%d", m.c_str(), ret); |
| @@ -2335,6 +2336,17 @@ SrsConfDirective* SrsConfig::get_vhost_on_stop(string vhost) | @@ -2335,6 +2336,17 @@ SrsConfDirective* SrsConfig::get_vhost_on_stop(string vhost) | ||
| 2335 | return conf->get("on_stop"); | 2336 | return conf->get("on_stop"); |
| 2336 | } | 2337 | } |
| 2337 | 2338 | ||
| 2339 | +SrsConfDirective* SrsConfig::get_vhost_on_dvr(string vhost) | ||
| 2340 | +{ | ||
| 2341 | + SrsConfDirective* conf = get_vhost_http_hooks(vhost); | ||
| 2342 | + | ||
| 2343 | + if (!conf) { | ||
| 2344 | + return NULL; | ||
| 2345 | + } | ||
| 2346 | + | ||
| 2347 | + return conf->get("on_dvr"); | ||
| 2348 | +} | ||
| 2349 | + | ||
| 2338 | bool SrsConfig::get_bw_check_enabled(string vhost) | 2350 | bool SrsConfig::get_bw_check_enabled(string vhost) |
| 2339 | { | 2351 | { |
| 2340 | SrsConfDirective* conf = get_vhost(vhost); | 2352 | SrsConfDirective* conf = get_vhost(vhost); |
| @@ -610,6 +610,11 @@ public: | @@ -610,6 +610,11 @@ public: | ||
| 610 | * @return the on_stop callback directive, the args is the url to callback. | 610 | * @return the on_stop callback directive, the args is the url to callback. |
| 611 | */ | 611 | */ |
| 612 | virtual SrsConfDirective* get_vhost_on_stop(std::string vhost); | 612 | virtual SrsConfDirective* get_vhost_on_stop(std::string vhost); |
| 613 | + /** | ||
| 614 | + * get the on_dvr callbacks of vhost. | ||
| 615 | + * @return the on_dvr callback directive, the args is the url to callback. | ||
| 616 | + */ | ||
| 617 | + virtual SrsConfDirective* get_vhost_on_dvr(std::string vhost); | ||
| 613 | // bwct(bandwidth check tool) section | 618 | // bwct(bandwidth check tool) section |
| 614 | public: | 619 | public: |
| 615 | /** | 620 | /** |
| @@ -404,6 +404,30 @@ int SrsDvrPlan::flv_close() | @@ -404,6 +404,30 @@ int SrsDvrPlan::flv_close() | ||
| 404 | return ret; | 404 | return ret; |
| 405 | } | 405 | } |
| 406 | 406 | ||
| 407 | +#ifdef SRS_AUTO_HTTP_CALLBACK | ||
| 408 | + SrsRequest* req = _req; | ||
| 409 | + if (_srs_config->get_vhost_http_hooks_enabled(req->vhost)) { | ||
| 410 | + // HTTP: on_dvr | ||
| 411 | + SrsConfDirective* on_dvr = _srs_config->get_vhost_on_dvr(req->vhost); | ||
| 412 | + if (!on_dvr) { | ||
| 413 | + srs_info("ignore the empty http callback: on_dvr"); | ||
| 414 | + return ret; | ||
| 415 | + } | ||
| 416 | + | ||
| 417 | + int connection_id = _srs_context->get_id(); | ||
| 418 | + std::string ip = req->ip; | ||
| 419 | + std::string cwd = _srs_config->cwd(); | ||
| 420 | + std::string file = segment->path; | ||
| 421 | + for (int i = 0; i < (int)on_dvr->args.size(); i++) { | ||
| 422 | + std::string url = on_dvr->args.at(i); | ||
| 423 | + if ((ret = SrsHttpHooks::on_dvr(url, connection_id, ip, req, cwd, file)) != ERROR_SUCCESS) { | ||
| 424 | + srs_error("hook client on_dvr failed. url=%s, ret=%d", url.c_str(), ret); | ||
| 425 | + return ret; | ||
| 426 | + } | ||
| 427 | + } | ||
| 428 | + } | ||
| 429 | +#endif | ||
| 430 | + | ||
| 407 | return ret; | 431 | return ret; |
| 408 | } | 432 | } |
| 409 | 433 |
| @@ -379,5 +379,61 @@ void SrsHttpHooks::on_stop(string url, int client_id, string ip, SrsRequest* req | @@ -379,5 +379,61 @@ void SrsHttpHooks::on_stop(string url, int client_id, string ip, SrsRequest* req | ||
| 379 | return; | 379 | return; |
| 380 | } | 380 | } |
| 381 | 381 | ||
| 382 | -#endif | 382 | +int SrsHttpHooks::on_dvr(string url, int client_id, string ip, SrsRequest* req, string cwd, string file) |
| 383 | +{ | ||
| 384 | + int ret = ERROR_SUCCESS; | ||
| 385 | + | ||
| 386 | + SrsHttpUri uri; | ||
| 387 | + if ((ret = uri.initialize(url)) != ERROR_SUCCESS) { | ||
| 388 | + srs_error("http uri parse on_dvr url failed, ignored. " | ||
| 389 | + "client_id=%d, url=%s, ret=%d", client_id, url.c_str(), ret); | ||
| 390 | + return ret; | ||
| 391 | + } | ||
| 392 | + | ||
| 393 | + std::stringstream ss; | ||
| 394 | + ss << __SRS_JOBJECT_START | ||
| 395 | + << __SRS_JFIELD_STR("action", "on_dvr") << __SRS_JFIELD_CONT | ||
| 396 | + << __SRS_JFIELD_ORG("client_id", client_id) << __SRS_JFIELD_CONT | ||
| 397 | + << __SRS_JFIELD_STR("ip", ip) << __SRS_JFIELD_CONT | ||
| 398 | + << __SRS_JFIELD_STR("vhost", req->vhost) << __SRS_JFIELD_CONT | ||
| 399 | + << __SRS_JFIELD_STR("app", req->app) << __SRS_JFIELD_CONT | ||
| 400 | + << __SRS_JFIELD_STR("stream", req->stream) << __SRS_JFIELD_CONT | ||
| 401 | + << __SRS_JFIELD_STR("cwd", cwd) << __SRS_JFIELD_CONT | ||
| 402 | + << __SRS_JFIELD_STR("file", file) | ||
| 403 | + << __SRS_JOBJECT_END; | ||
| 404 | + std::string data = ss.str(); | ||
| 405 | + std::string res; | ||
| 406 | + int status_code; | ||
| 407 | + | ||
| 408 | + SrsHttpClient http; | ||
| 409 | + if ((ret = http.post(&uri, data, status_code, res)) != ERROR_SUCCESS) { | ||
| 410 | + srs_error("http post on_dvr uri failed, ignored. " | ||
| 411 | + "client_id=%d, url=%s, request=%s, response=%s, ret=%d", | ||
| 412 | + client_id, url.c_str(), data.c_str(), res.c_str(), ret); | ||
| 413 | + return ret; | ||
| 414 | + } | ||
| 415 | + | ||
| 416 | + // ensure the http status is ok. | ||
| 417 | + // https://github.com/winlinvip/simple-rtmp-server/issues/158 | ||
| 418 | + if (status_code != SRS_CONSTS_HTTP_OK) { | ||
| 419 | + ret = ERROR_HTTP_STATUS_INVLIAD; | ||
| 420 | + srs_error("http hook on_dvr status failed. " | ||
| 421 | + "client_id=%d, code=%d, ret=%d", client_id, status_code, ret); | ||
| 422 | + return ret; | ||
| 423 | + } | ||
| 424 | + | ||
| 425 | + if (res.empty() || res != SRS_HTTP_RESPONSE_OK) { | ||
| 426 | + ret = ERROR_HTTP_DATA_INVLIAD; | ||
| 427 | + srs_warn("http hook on_dvr validate failed, ignored. " | ||
| 428 | + "client_id=%d, res=%s, ret=%d", client_id, res.c_str(), ret); | ||
| 429 | + return ret; | ||
| 430 | + } | ||
| 431 | + | ||
| 432 | + srs_trace("http hook on_dvr success. " | ||
| 433 | + "client_id=%d, url=%s, request=%s, response=%s, ret=%d", | ||
| 434 | + client_id, url.c_str(), data.c_str(), res.c_str(), ret); | ||
| 435 | + | ||
| 436 | + return ret; | ||
| 437 | +} | ||
| 383 | 438 | ||
| 439 | +#endif |
| @@ -58,7 +58,6 @@ public: | @@ -58,7 +58,6 @@ public: | ||
| 58 | * @param client_id the id of client on server. | 58 | * @param client_id the id of client on server. |
| 59 | * @param url the api server url, to valid the client. | 59 | * @param url the api server url, to valid the client. |
| 60 | * ignore if empty. | 60 | * ignore if empty. |
| 61 | - * @return valid failed or connect to the url failed. | ||
| 62 | */ | 61 | */ |
| 63 | static int on_connect(std::string url, int client_id, std::string ip, SrsRequest* req); | 62 | static int on_connect(std::string url, int client_id, std::string ip, SrsRequest* req); |
| 64 | /** | 63 | /** |
| @@ -73,7 +72,6 @@ public: | @@ -73,7 +72,6 @@ public: | ||
| 73 | * @param client_id the id of client on server. | 72 | * @param client_id the id of client on server. |
| 74 | * @param url the api server url, to valid the client. | 73 | * @param url the api server url, to valid the client. |
| 75 | * ignore if empty. | 74 | * ignore if empty. |
| 76 | - * @return valid failed or connect to the url failed. | ||
| 77 | */ | 75 | */ |
| 78 | static int on_publish(std::string url, int client_id, std::string ip, SrsRequest* req); | 76 | static int on_publish(std::string url, int client_id, std::string ip, SrsRequest* req); |
| 79 | /** | 77 | /** |
| @@ -88,7 +86,6 @@ public: | @@ -88,7 +86,6 @@ public: | ||
| 88 | * @param client_id the id of client on server. | 86 | * @param client_id the id of client on server. |
| 89 | * @param url the api server url, to valid the client. | 87 | * @param url the api server url, to valid the client. |
| 90 | * ignore if empty. | 88 | * ignore if empty. |
| 91 | - * @return valid failed or connect to the url failed. | ||
| 92 | */ | 89 | */ |
| 93 | static int on_play(std::string url, int client_id, std::string ip, SrsRequest* req); | 90 | static int on_play(std::string url, int client_id, std::string ip, SrsRequest* req); |
| 94 | /** | 91 | /** |
| @@ -98,6 +95,15 @@ public: | @@ -98,6 +95,15 @@ public: | ||
| 98 | * ignore if empty. | 95 | * ignore if empty. |
| 99 | */ | 96 | */ |
| 100 | static void on_stop(std::string url, int client_id, std::string ip, SrsRequest* req); | 97 | static void on_stop(std::string url, int client_id, std::string ip, SrsRequest* req); |
| 98 | + /** | ||
| 99 | + * on_dvr hook, when reap a dvr file. | ||
| 100 | + * @param client_id the id of client on server. | ||
| 101 | + * @param url the api server url, to process the event. | ||
| 102 | + * ignore if empty. | ||
| 103 | + * @param cwd the current work directory, used to resolve the reltive file path. | ||
| 104 | + * @param file the file path, can be relative or absolute path. | ||
| 105 | + */ | ||
| 106 | + static int on_dvr(std::string url, int client_id, std::string ip, SrsRequest* req, std::string cwd, std::string file); | ||
| 101 | }; | 107 | }; |
| 102 | 108 | ||
| 103 | #endif | 109 | #endif |
| @@ -135,6 +135,9 @@ int SrsRtmpConn::do_cycle() | @@ -135,6 +135,9 @@ int SrsRtmpConn::do_cycle() | ||
| 135 | } | 135 | } |
| 136 | srs_verbose("rtmp connect app success"); | 136 | srs_verbose("rtmp connect app success"); |
| 137 | 137 | ||
| 138 | + // set client ip to request. | ||
| 139 | + req->ip = ip; | ||
| 140 | + | ||
| 138 | // discovery vhost, resolve the vhost from config | 141 | // discovery vhost, resolve the vhost from config |
| 139 | SrsConfDirective* parsed_vhost = _srs_config->get_vhost(req->vhost); | 142 | SrsConfDirective* parsed_vhost = _srs_config->get_vhost(req->vhost); |
| 140 | if (parsed_vhost) { | 143 | if (parsed_vhost) { |
| @@ -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 88 | 34 | +#define VERSION_REVISION 89 |
| 35 | // server info. | 35 | // server info. |
| 36 | #define RTMP_SIG_SRS_KEY "SRS" | 36 | #define RTMP_SIG_SRS_KEY "SRS" |
| 37 | #define RTMP_SIG_SRS_ROLE "origin/edge server" | 37 | #define RTMP_SIG_SRS_ROLE "origin/edge server" |
| @@ -91,6 +91,7 @@ SrsRequest* SrsRequest::copy() | @@ -91,6 +91,7 @@ SrsRequest* SrsRequest::copy() | ||
| 91 | { | 91 | { |
| 92 | SrsRequest* cp = new SrsRequest(); | 92 | SrsRequest* cp = new SrsRequest(); |
| 93 | 93 | ||
| 94 | + cp->ip = ip; | ||
| 94 | cp->app = app; | 95 | cp->app = app; |
| 95 | cp->objectEncoding = objectEncoding; | 96 | cp->objectEncoding = objectEncoding; |
| 96 | cp->pageUrl = pageUrl; | 97 | cp->pageUrl = pageUrl; |
| @@ -54,6 +54,9 @@ class IMergeReadHandler; | @@ -54,6 +54,9 @@ class IMergeReadHandler; | ||
| 54 | class SrsRequest | 54 | class SrsRequest |
| 55 | { | 55 | { |
| 56 | public: | 56 | public: |
| 57 | + // client ip. | ||
| 58 | + std::string ip; | ||
| 59 | +public: | ||
| 57 | /** | 60 | /** |
| 58 | * tcUrl: rtmp://request_vhost:port/app/stream | 61 | * tcUrl: rtmp://request_vhost:port/app/stream |
| 59 | * support pass vhost in query string, such as: | 62 | * support pass vhost in query string, such as: |
-
请 注册 或 登录 后发表评论