winlin

merge from 2.0.152

@@ -566,6 +566,7 @@ Supported operating systems and hardware: @@ -566,6 +566,7 @@ Supported operating systems and hardware:
566 566
567 ### SRS 2.0 history 567 ### SRS 2.0 history
568 568
  569 +* v2.0, 2015-03-31, support on_hls for http hooks. 2.0.152.
569 * v2.0, 2015-03-31, enhanced hls, support deviation for duration. 2.0.151. 570 * v2.0, 2015-03-31, enhanced hls, support deviation for duration. 2.0.151.
570 * v2.0, 2015-03-30, for [#351](https://github.com/winlinvip/simple-rtmp-server/issues/351), support config the m3u8/ts path for hls. 2.0.149. 571 * v2.0, 2015-03-30, for [#351](https://github.com/winlinvip/simple-rtmp-server/issues/351), support config the m3u8/ts path for hls. 2.0.149.
571 * v2.0, 2015-03-17, for [#155](https://github.com/winlinvip/simple-rtmp-server/issues/155), osx(darwin) support demo with nginx and ffmpeg. 2.0.143. 572 * v2.0, 2015-03-17, for [#155](https://github.com/winlinvip/simple-rtmp-server/issues/155), osx(darwin) support demo with nginx and ffmpeg. 2.0.143.
@@ -563,6 +563,7 @@ vhost with-hls.srs.com { @@ -563,6 +563,7 @@ vhost with-hls.srs.com {
563 # whether use floor for the hls_ts_file path generation. 563 # whether use floor for the hls_ts_file path generation.
564 # if on, use floor(timestamp/hls_fragment) as the variable [timestamp], 564 # if on, use floor(timestamp/hls_fragment) as the variable [timestamp],
565 # and use enahanced algorithm to calc deviation for segment. 565 # and use enahanced algorithm to calc deviation for segment.
  566 + # @remark when floor on, recommend the hls_segment>=2*gop.
566 # default: off 567 # default: off
567 hls_ts_floor off; 568 hls_ts_floor off;
568 # the hls entry prefix, which is base url of ts url. 569 # the hls entry prefix, which is base url of ts url.
@@ -740,7 +741,8 @@ vhost hooks.callback.srs.com { @@ -740,7 +741,8 @@ vhost hooks.callback.srs.com {
740 # "ip": "192.168.1.10", "vhost": "video.test.com", "app": "live", 741 # "ip": "192.168.1.10", "vhost": "video.test.com", "app": "live",
741 # "stream": "livestream", 742 # "stream": "livestream",
742 # "cwd": "/usr/local/srs", 743 # "cwd": "/usr/local/srs",
743 - # "file": "./objs/nginx/html/live/livestream.1420254068776-100.ts" 744 + # "file": "./objs/nginx/html/live/livestream.1420254068776-100.ts",
  745 + # "seq_no": 100
744 # } 746 # }
745 # if valid, the hook must return HTTP code 200(Stauts OK) and response 747 # if valid, the hook must return HTTP code 200(Stauts OK) and response
746 # an int value specifies the error code(0 corresponding to success): 748 # an int value specifies the error code(0 corresponding to success):
@@ -174,7 +174,7 @@ if [ $SRS_EXPORT_LIBRTMP_PROJECT = NO ]; then @@ -174,7 +174,7 @@ if [ $SRS_EXPORT_LIBRTMP_PROJECT = NO ]; then
174 "srs_app_json" "srs_app_ingest" "srs_app_ffmpeg" "srs_app_utility" "srs_app_dvr" "srs_app_edge" 174 "srs_app_json" "srs_app_ingest" "srs_app_ffmpeg" "srs_app_utility" "srs_app_dvr" "srs_app_edge"
175 "srs_app_kbps" "srs_app_heartbeat" "srs_app_empty" "srs_app_http_client" 175 "srs_app_kbps" "srs_app_heartbeat" "srs_app_empty" "srs_app_http_client"
176 "srs_app_recv_thread" "srs_app_security" "srs_app_statistic" "srs_app_hds" 176 "srs_app_recv_thread" "srs_app_security" "srs_app_statistic" "srs_app_hds"
177 - "srs_app_mpegts_udp" "srs_app_rtsp" "srs_app_listener") 177 + "srs_app_mpegts_udp" "srs_app_rtsp" "srs_app_listener" "srs_app_async_call")
178 DEFINES="" 178 DEFINES=""
179 # add each modules for app 179 # add each modules for app
180 for SRS_MODULE in $SRS_MODULES; do 180 for SRS_MODULE in $SRS_MODULES; do
@@ -64,6 +64,8 @@ file @@ -64,6 +64,8 @@ file
64 ../../src/protocol/srs_rtmp_utility.hpp, 64 ../../src/protocol/srs_rtmp_utility.hpp,
65 ../../src/protocol/srs_rtmp_utility.cpp, 65 ../../src/protocol/srs_rtmp_utility.cpp,
66 app readonly separator, 66 app readonly separator,
  67 + ../../src/app/srs_app_async_call.hpp,
  68 + ../../src/app/srs_app_async_call.cpp,
67 ../../src/app/srs_app_bandwidth.hpp, 69 ../../src/app/srs_app_bandwidth.hpp,
68 ../../src/app/srs_app_bandwidth.cpp, 70 ../../src/app/srs_app_bandwidth.cpp,
69 ../../src/app/srs_app_conn.hpp, 71 ../../src/app/srs_app_conn.hpp,
@@ -97,6 +97,7 @@ @@ -97,6 +97,7 @@
97 3C689F9F1AB6AAC800C9CEEE /* sched.c in Sources */ = {isa = PBXBuildFile; fileRef = 3C689F9B1AB6AAC800C9CEEE /* sched.c */; }; 97 3C689F9F1AB6AAC800C9CEEE /* sched.c in Sources */ = {isa = PBXBuildFile; fileRef = 3C689F9B1AB6AAC800C9CEEE /* sched.c */; };
98 3C689FA01AB6AAC800C9CEEE /* stk.c in Sources */ = {isa = PBXBuildFile; fileRef = 3C689F9C1AB6AAC800C9CEEE /* stk.c */; }; 98 3C689FA01AB6AAC800C9CEEE /* stk.c in Sources */ = {isa = PBXBuildFile; fileRef = 3C689F9C1AB6AAC800C9CEEE /* stk.c */; };
99 3C689FA11AB6AAC800C9CEEE /* sync.c in Sources */ = {isa = PBXBuildFile; fileRef = 3C689F9D1AB6AAC800C9CEEE /* sync.c */; }; 99 3C689FA11AB6AAC800C9CEEE /* sync.c in Sources */ = {isa = PBXBuildFile; fileRef = 3C689F9D1AB6AAC800C9CEEE /* sync.c */; };
  100 + 3CD88B3F1ACA9C58000359E0 /* srs_app_async_call.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3CD88B3D1ACA9C58000359E0 /* srs_app_async_call.cpp */; };
100 /* End PBXBuildFile section */ 101 /* End PBXBuildFile section */
101 102
102 /* Begin PBXCopyFilesBuildPhase section */ 103 /* Begin PBXCopyFilesBuildPhase section */
@@ -337,6 +338,8 @@ @@ -337,6 +338,8 @@
337 3C689F9B1AB6AAC800C9CEEE /* sched.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = sched.c; path = "../../objs/st-1.9/sched.c"; sourceTree = "<group>"; }; 338 3C689F9B1AB6AAC800C9CEEE /* sched.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = sched.c; path = "../../objs/st-1.9/sched.c"; sourceTree = "<group>"; };
338 3C689F9C1AB6AAC800C9CEEE /* stk.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = stk.c; path = "../../objs/st-1.9/stk.c"; sourceTree = "<group>"; }; 339 3C689F9C1AB6AAC800C9CEEE /* stk.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = stk.c; path = "../../objs/st-1.9/stk.c"; sourceTree = "<group>"; };
339 3C689F9D1AB6AAC800C9CEEE /* sync.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = sync.c; path = "../../objs/st-1.9/sync.c"; sourceTree = "<group>"; }; 340 3C689F9D1AB6AAC800C9CEEE /* sync.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = sync.c; path = "../../objs/st-1.9/sync.c"; sourceTree = "<group>"; };
  341 + 3CD88B3D1ACA9C58000359E0 /* srs_app_async_call.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = srs_app_async_call.cpp; path = ../../../src/app/srs_app_async_call.cpp; sourceTree = "<group>"; };
  342 + 3CD88B3E1ACA9C58000359E0 /* srs_app_async_call.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = srs_app_async_call.hpp; path = ../../../src/app/srs_app_async_call.hpp; sourceTree = "<group>"; };
340 /* End PBXFileReference section */ 343 /* End PBXFileReference section */
341 344
342 /* Begin PBXFrameworksBuildPhase section */ 345 /* Begin PBXFrameworksBuildPhase section */
@@ -483,6 +486,8 @@ @@ -483,6 +486,8 @@
483 3C12324B1AAE81CE00CE8F6C /* app */ = { 486 3C12324B1AAE81CE00CE8F6C /* app */ = {
484 isa = PBXGroup; 487 isa = PBXGroup;
485 children = ( 488 children = (
  489 + 3CD88B3D1ACA9C58000359E0 /* srs_app_async_call.cpp */,
  490 + 3CD88B3E1ACA9C58000359E0 /* srs_app_async_call.hpp */,
486 3C12324C1AAE81D900CE8F6C /* srs_app_bandwidth.cpp */, 491 3C12324C1AAE81D900CE8F6C /* srs_app_bandwidth.cpp */,
487 3C12324D1AAE81D900CE8F6C /* srs_app_bandwidth.hpp */, 492 3C12324D1AAE81D900CE8F6C /* srs_app_bandwidth.hpp */,
488 3C12324E1AAE81D900CE8F6C /* srs_app_config.cpp */, 493 3C12324E1AAE81D900CE8F6C /* srs_app_config.cpp */,
@@ -789,6 +794,7 @@ @@ -789,6 +794,7 @@
789 3C1232951AAE81D900CE8F6C /* srs_app_config.cpp in Sources */, 794 3C1232951AAE81D900CE8F6C /* srs_app_config.cpp in Sources */,
790 3C663F0F1AB0155100286D8B /* srs_aac_raw_publish.c in Sources */, 795 3C663F0F1AB0155100286D8B /* srs_aac_raw_publish.c in Sources */,
791 3C689FA01AB6AAC800C9CEEE /* stk.c in Sources */, 796 3C689FA01AB6AAC800C9CEEE /* stk.c in Sources */,
  797 + 3CD88B3F1ACA9C58000359E0 /* srs_app_async_call.cpp in Sources */,
792 3C1232961AAE81D900CE8F6C /* srs_app_conn.cpp in Sources */, 798 3C1232961AAE81D900CE8F6C /* srs_app_conn.cpp in Sources */,
793 3C12322A1AAE814D00CE8F6C /* srs_kernel_ts.cpp in Sources */, 799 3C12322A1AAE814D00CE8F6C /* srs_kernel_ts.cpp in Sources */,
794 3C12329E1AAE81D900CE8F6C /* srs_app_hls.cpp in Sources */, 800 3C12329E1AAE81D900CE8F6C /* srs_app_hls.cpp in Sources */,
@@ -253,7 +253,7 @@ class RESTDvrs(object): @@ -253,7 +253,7 @@ class RESTDvrs(object):
253 return json.dumps(dvrs) 253 return json.dumps(dvrs)
254 254
255 ''' 255 '''
256 - for SRS hook: on_dvr, on_dvr_reap_segment 256 + for SRS hook: on_dvr
257 on_dvr: 257 on_dvr:
258 when srs reap a dvr file, call the hook, 258 when srs reap a dvr file, call the hook,
259 the request in the POST data string is a object encode by json: 259 the request in the POST data string is a object encode by json:
@@ -265,17 +265,6 @@ class RESTDvrs(object): @@ -265,17 +265,6 @@ class RESTDvrs(object):
265 "cwd": "/usr/local/srs", 265 "cwd": "/usr/local/srs",
266 "file": "./objs/nginx/html/live/livestream.1420254068776.flv" 266 "file": "./objs/nginx/html/live/livestream.1420254068776.flv"
267 } 267 }
268 - on_dvr_reap_segment:  
269 - when api dvr specifes the callback when reap flv segment, call the hook,  
270 - the request in the POST data string is a object encode by json:  
271 - {  
272 - "action": "on_dvr_reap_segment",  
273 - "client_id": 1985,  
274 - "vhost": "video.test.com", "app": "live",  
275 - "stream": "livestream",  
276 - "cwd": "/usr/local/srs",  
277 - "file": "./objs/nginx/html/live/livestream.1420254068776.flv"  
278 - }  
279 if valid, the hook must return HTTP code 200(Stauts OK) and response 268 if valid, the hook must return HTTP code 200(Stauts OK) and response
280 an int value specifies the error code(0 corresponding to success): 269 an int value specifies the error code(0 corresponding to success):
281 0 270 0
@@ -298,8 +287,6 @@ class RESTDvrs(object): @@ -298,8 +287,6 @@ class RESTDvrs(object):
298 action = json_req["action"] 287 action = json_req["action"]
299 if action == "on_dvr": 288 if action == "on_dvr":
300 code = self.__on_dvr(json_req) 289 code = self.__on_dvr(json_req)
301 - if action == "on_dvr_reap_segment":  
302 - code = self.__on_dvr_reap_segment(json_req)  
303 else: 290 else:
304 trace("invalid request action: %s"%(json_req["action"])) 291 trace("invalid request action: %s"%(json_req["action"]))
305 code = Error.request_invalid_action 292 code = Error.request_invalid_action
@@ -321,15 +308,72 @@ class RESTDvrs(object): @@ -321,15 +308,72 @@ class RESTDvrs(object):
321 308
322 return code 309 return code
323 310
324 - def __on_dvr_reap_segment(self, req): 311 +'''
  312 +handle the hls requests: hls stream.
  313 +'''
  314 +class RESTHls(object):
  315 + exposed = True
  316 +
  317 + def GET(self):
  318 + enable_crossdomain()
  319 +
  320 + hls = {}
  321 + return json.dumps(hls)
  322 +
  323 + '''
  324 + for SRS hook: on_hls
  325 + on_hls:
  326 + when srs reap a dvr file, call the hook,
  327 + the request in the POST data string is a object encode by json:
  328 + {
  329 + "action": "on_dvr",
  330 + "client_id": 1985,
  331 + "ip": "192.168.1.10", "vhost": "video.test.com", "app": "live",
  332 + "stream": "livestream",
  333 + "cwd": "/usr/local/srs",
  334 + "file": "./objs/nginx/html/live/livestream.1420254068776-100.ts",
  335 + "seq_no": 100
  336 + }
  337 + if valid, the hook must return HTTP code 200(Stauts OK) and response
  338 + an int value specifies the error code(0 corresponding to success):
  339 + 0
  340 + '''
  341 + def POST(self):
  342 + enable_crossdomain()
  343 +
  344 + # return the error code in str
325 code = Error.success 345 code = Error.success
326 346
327 - trace("srs %s: client id=%s, vhost=%s, app=%s, stream=%s, cwd=%s, file=%s"%(  
328 - req["action"], req["client_id"], req["vhost"], req["app"], req["stream"],  
329 - req["cwd"], req["file"] 347 + req = cherrypy.request.body.read()
  348 + trace("post to hls, req=%s"%(req))
  349 + try:
  350 + json_req = json.loads(req)
  351 + except Exception, ex:
  352 + code = Error.system_parse_json
  353 + trace("parse the request to json failed, req=%s, ex=%s, code=%s"%(req, ex, code))
  354 + return str(code)
  355 +
  356 + action = json_req["action"]
  357 + if action == "on_hls":
  358 + code = self.__on_hls(json_req)
  359 + else:
  360 + trace("invalid request action: %s"%(json_req["action"]))
  361 + code = Error.request_invalid_action
  362 +
  363 + return str(code)
  364 +
  365 + def OPTIONS(self, *args, **kwargs):
  366 + enable_crossdomain()
  367 +
  368 + def __on_hls(self, req):
  369 + code = Error.success
  370 +
  371 + trace("srs %s: client id=%s, ip=%s, vhost=%s, app=%s, stream=%s, cwd=%s, file=%s, seq_no=%s"%(
  372 + req["action"], req["client_id"], req["ip"], req["vhost"], req["app"], req["stream"],
  373 + req["cwd"], req["file"], req["seq_no"]
330 )) 374 ))
331 375
332 - # TODO: process the on_dvr event 376 + # TODO: process the on_hls event
333 377
334 return code 378 return code
335 379
@@ -1133,6 +1177,7 @@ class V1(object): @@ -1133,6 +1177,7 @@ class V1(object):
1133 self.streams = RESTStreams() 1177 self.streams = RESTStreams()
1134 self.sessions = RESTSessions() 1178 self.sessions = RESTSessions()
1135 self.dvrs = RESTDvrs() 1179 self.dvrs = RESTDvrs()
  1180 + self.hls = RESTHls()
1136 self.chats = RESTChats() 1181 self.chats = RESTChats()
1137 self.servers = RESTServers() 1182 self.servers = RESTServers()
1138 self.nodes = RESTNodes() 1183 self.nodes = RESTNodes()
  1 +/*
  2 +The MIT License (MIT)
  3 +
  4 +Copyright (c) 2013-2015 winlin
  5 +
  6 +Permission is hereby granted, free of charge, to any person obtaining a copy of
  7 +this software and associated documentation files (the "Software"), to deal in
  8 +the Software without restriction, including without limitation the rights to
  9 +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
  10 +the Software, and to permit persons to whom the Software is furnished to do so,
  11 +subject to the following conditions:
  12 +
  13 +The above copyright notice and this permission notice shall be included in all
  14 +copies or substantial portions of the Software.
  15 +
  16 +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  17 +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
  18 +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
  19 +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
  20 +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  21 +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  22 +*/
  23 +
  24 +#include <srs_app_async_call.hpp>
  25 +
  26 +using namespace std;
  27 +
  28 +#include <srs_kernel_error.hpp>
  29 +#include <srs_kernel_log.hpp>
  30 +
  31 +// the sleep interval for http async callback.
  32 +#define SRS_AUTO_ASYNC_CALLBACL_SLEEP_US 300000
  33 +
  34 +ISrsDvrAsyncCall::ISrsDvrAsyncCall()
  35 +{
  36 +}
  37 +
  38 +ISrsDvrAsyncCall::~ISrsDvrAsyncCall()
  39 +{
  40 +}
  41 +
  42 +SrsDvrAsyncCallThread::SrsDvrAsyncCallThread()
  43 +{
  44 + pthread = new SrsThread("async", this, SRS_AUTO_ASYNC_CALLBACL_SLEEP_US, true);
  45 +}
  46 +
  47 +SrsDvrAsyncCallThread::~SrsDvrAsyncCallThread()
  48 +{
  49 + stop();
  50 + srs_freep(pthread);
  51 +
  52 + std::vector<ISrsDvrAsyncCall*>::iterator it;
  53 + for (it = callbacks.begin(); it != callbacks.end(); ++it) {
  54 + ISrsDvrAsyncCall* call = *it;
  55 + srs_freep(call);
  56 + }
  57 + callbacks.clear();
  58 +}
  59 +
  60 +int SrsDvrAsyncCallThread::call(ISrsDvrAsyncCall* c)
  61 +{
  62 + int ret = ERROR_SUCCESS;
  63 +
  64 + callbacks.push_back(c);
  65 +
  66 + return ret;
  67 +}
  68 +
  69 +int SrsDvrAsyncCallThread::start()
  70 +{
  71 + return pthread->start();
  72 +}
  73 +
  74 +void SrsDvrAsyncCallThread::stop()
  75 +{
  76 + pthread->stop();
  77 +}
  78 +
  79 +int SrsDvrAsyncCallThread::cycle()
  80 +{
  81 + int ret = ERROR_SUCCESS;
  82 +
  83 + std::vector<ISrsDvrAsyncCall*> copies = callbacks;
  84 + callbacks.clear();
  85 +
  86 + std::vector<ISrsDvrAsyncCall*>::iterator it;
  87 + for (it = copies.begin(); it != copies.end(); ++it) {
  88 + ISrsDvrAsyncCall* call = *it;
  89 + if ((ret = call->call()) != ERROR_SUCCESS) {
  90 + srs_warn("dvr: ignore callback %s, ret=%d", call->to_string().c_str(), ret);
  91 + }
  92 + srs_freep(call);
  93 + }
  94 +
  95 + return ret;
  96 +}
  97 +
  98 +
  1 +/*
  2 +The MIT License (MIT)
  3 +
  4 +Copyright (c) 2013-2015 winlin
  5 +
  6 +Permission is hereby granted, free of charge, to any person obtaining a copy of
  7 +this software and associated documentation files (the "Software"), to deal in
  8 +the Software without restriction, including without limitation the rights to
  9 +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
  10 +the Software, and to permit persons to whom the Software is furnished to do so,
  11 +subject to the following conditions:
  12 +
  13 +The above copyright notice and this permission notice shall be included in all
  14 +copies or substantial portions of the Software.
  15 +
  16 +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  17 +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
  18 +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
  19 +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
  20 +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  21 +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  22 +*/
  23 +
  24 +#ifndef SRS_APP_ASYNC_CALL_HPP
  25 +#define SRS_APP_ASYNC_CALL_HPP
  26 +
  27 +/*
  28 +#include <srs_app_async_call.hpp>
  29 +*/
  30 +#include <srs_core.hpp>
  31 +
  32 +#include <string>
  33 +#include <vector>
  34 +
  35 +#include <srs_app_thread.hpp>
  36 +
  37 +/**
  38 + * the async call for http hooks,
  39 + * for the http hooks will switch st-thread,
  40 + * so we must use isolate thread to avoid the thread corrupt,
  41 + * for example, when dvr call http hooks, the video receive thread got
  42 + * a video and pass it to the dvr again.
  43 + * futhurmore, the aync call never block the main worker thread.
  44 + */
  45 +class ISrsDvrAsyncCall
  46 +{
  47 +public:
  48 + ISrsDvrAsyncCall();
  49 + virtual ~ISrsDvrAsyncCall();
  50 +public:
  51 + virtual int call() = 0;
  52 + virtual std::string to_string() = 0;
  53 +};
  54 +
  55 +/**
  56 +* the async callback for dvr.
  57 +*/
  58 +class SrsDvrAsyncCallThread : public ISrsThreadHandler
  59 +{
  60 +private:
  61 + SrsThread* pthread;
  62 + std::vector<ISrsDvrAsyncCall*> callbacks;
  63 +public:
  64 + SrsDvrAsyncCallThread();
  65 + virtual ~SrsDvrAsyncCallThread();
  66 +public:
  67 + virtual int call(ISrsDvrAsyncCall* c);
  68 +public:
  69 + virtual int start();
  70 + virtual void stop();
  71 + virtual int cycle();
  72 +};
  73 +
  74 +#endif
  75 +
@@ -1494,7 +1494,7 @@ int SrsConfig::check_config() @@ -1494,7 +1494,7 @@ int SrsConfig::check_config()
1494 string m = conf->at(j)->name.c_str(); 1494 string m = conf->at(j)->name.c_str();
1495 if (m != "enabled" && m != "on_connect" && m != "on_close" && m != "on_publish" 1495 if (m != "enabled" && m != "on_connect" && m != "on_close" && m != "on_publish"
1496 && m != "on_unpublish" && m != "on_play" && m != "on_stop" 1496 && m != "on_unpublish" && m != "on_play" && m != "on_stop"
1497 - && m != "on_dvr" 1497 + && m != "on_dvr" && m != "on_hls"
1498 ) { 1498 ) {
1499 ret = ERROR_SYSTEM_CONFIG_INVALID; 1499 ret = ERROR_SYSTEM_CONFIG_INVALID;
1500 srs_error("unsupported vhost http_hooks directive %s, ret=%d", m.c_str(), ret); 1500 srs_error("unsupported vhost http_hooks directive %s, ret=%d", m.c_str(), ret);
@@ -2411,6 +2411,17 @@ SrsConfDirective* SrsConfig::get_vhost_on_dvr(string vhost) @@ -2411,6 +2411,17 @@ SrsConfDirective* SrsConfig::get_vhost_on_dvr(string vhost)
2411 return conf->get("on_dvr"); 2411 return conf->get("on_dvr");
2412 } 2412 }
2413 2413
  2414 +SrsConfDirective* SrsConfig::get_vhost_on_hls(string vhost)
  2415 +{
  2416 + SrsConfDirective* conf = get_vhost_http_hooks(vhost);
  2417 +
  2418 + if (!conf) {
  2419 + return NULL;
  2420 + }
  2421 +
  2422 + return conf->get("on_hls");
  2423 +}
  2424 +
2414 bool SrsConfig::get_bw_check_enabled(string vhost) 2425 bool SrsConfig::get_bw_check_enabled(string vhost)
2415 { 2426 {
2416 SrsConfDirective* conf = get_vhost(vhost); 2427 SrsConfDirective* conf = get_vhost(vhost);
@@ -631,6 +631,11 @@ public: @@ -631,6 +631,11 @@ public:
631 * @return the on_dvr callback directive, the args is the url to callback. 631 * @return the on_dvr callback directive, the args is the url to callback.
632 */ 632 */
633 virtual SrsConfDirective* get_vhost_on_dvr(std::string vhost); 633 virtual SrsConfDirective* get_vhost_on_dvr(std::string vhost);
  634 + /**
  635 + * get the on_hls callbacks of vhost.
  636 + * @return the on_hls callback directive, the args is the url to callback.
  637 + */
  638 + virtual SrsConfDirective* get_vhost_on_hls(std::string vhost);
634 // bwct(bandwidth check tool) section 639 // bwct(bandwidth check tool) section
635 public: 640 public:
636 /** 641 /**
@@ -46,12 +46,6 @@ using namespace std; @@ -46,12 +46,6 @@ using namespace std;
46 // update the flv duration and filesize every this interval in ms. 46 // update the flv duration and filesize every this interval in ms.
47 #define SRS_DVR_UPDATE_DURATION_INTERVAL 60000 47 #define SRS_DVR_UPDATE_DURATION_INTERVAL 60000
48 48
49 -// the sleep interval for http async callback.  
50 -#define SRS_AUTO_ASYNC_CALLBACL_SLEEP_US 300000  
51 -  
52 -// the use raction for dvr rpc.  
53 -#define SRS_DVR_USER_ACTION_REAP_SEGMENT "reap_segment"  
54 -  
55 SrsFlvSegment::SrsFlvSegment(SrsDvrPlan* p) 49 SrsFlvSegment::SrsFlvSegment(SrsDvrPlan* p)
56 { 50 {
57 req = NULL; 51 req = NULL;
@@ -502,14 +496,6 @@ int SrsFlvSegment::on_reload_vhost_dvr(std::string /*vhost*/) @@ -502,14 +496,6 @@ int SrsFlvSegment::on_reload_vhost_dvr(std::string /*vhost*/)
502 return ret; 496 return ret;
503 } 497 }
504 498
505 -ISrsDvrAsyncCall::ISrsDvrAsyncCall()  
506 -{  
507 -}  
508 -  
509 -ISrsDvrAsyncCall::~ISrsDvrAsyncCall()  
510 -{  
511 -}  
512 -  
513 SrsDvrAsyncCallOnDvr::SrsDvrAsyncCallOnDvr(SrsRequest* r, string p) 499 SrsDvrAsyncCallOnDvr::SrsDvrAsyncCallOnDvr(SrsRequest* r, string p)
514 { 500 {
515 req = r; 501 req = r;
@@ -534,13 +520,10 @@ int SrsDvrAsyncCallOnDvr::call() @@ -534,13 +520,10 @@ int SrsDvrAsyncCallOnDvr::call()
534 return ret; 520 return ret;
535 } 521 }
536 522
537 - int connection_id = _srs_context->get_id();  
538 - std::string ip = req->ip;  
539 - std::string cwd = _srs_config->cwd();  
540 std::string file = path; 523 std::string file = path;
541 for (int i = 0; i < (int)on_dvr->args.size(); i++) { 524 for (int i = 0; i < (int)on_dvr->args.size(); i++) {
542 std::string url = on_dvr->args.at(i); 525 std::string url = on_dvr->args.at(i);
543 - if ((ret = SrsHttpHooks::on_dvr(url, connection_id, ip, req, cwd, file)) != ERROR_SUCCESS) { 526 + if ((ret = SrsHttpHooks::on_dvr(url, req, file)) != ERROR_SUCCESS) {
544 srs_error("hook client on_dvr failed. url=%s, ret=%d", url.c_str(), ret); 527 srs_error("hook client on_dvr failed. url=%s, ret=%d", url.c_str(), ret);
545 return ret; 528 return ret;
546 } 529 }
@@ -558,62 +541,6 @@ string SrsDvrAsyncCallOnDvr::to_string() @@ -558,62 +541,6 @@ string SrsDvrAsyncCallOnDvr::to_string()
558 return ss.str(); 541 return ss.str();
559 } 542 }
560 543
561 -SrsDvrAsyncCallThread::SrsDvrAsyncCallThread()  
562 -{  
563 - pthread = new SrsThread("async", this, SRS_AUTO_ASYNC_CALLBACL_SLEEP_US, true);  
564 -}  
565 -  
566 -SrsDvrAsyncCallThread::~SrsDvrAsyncCallThread()  
567 -{  
568 - stop();  
569 - srs_freep(pthread);  
570 -  
571 - std::vector<ISrsDvrAsyncCall*>::iterator it;  
572 - for (it = callbacks.begin(); it != callbacks.end(); ++it) {  
573 - ISrsDvrAsyncCall* call = *it;  
574 - srs_freep(call);  
575 - }  
576 - callbacks.clear();  
577 -}  
578 -  
579 -int SrsDvrAsyncCallThread::call(ISrsDvrAsyncCall* c)  
580 -{  
581 - int ret = ERROR_SUCCESS;  
582 -  
583 - callbacks.push_back(c);  
584 -  
585 - return ret;  
586 -}  
587 -  
588 -int SrsDvrAsyncCallThread::start()  
589 -{  
590 - return pthread->start();  
591 -}  
592 -  
593 -void SrsDvrAsyncCallThread::stop()  
594 -{  
595 - pthread->stop();  
596 -}  
597 -  
598 -int SrsDvrAsyncCallThread::cycle()  
599 -{  
600 - int ret = ERROR_SUCCESS;  
601 -  
602 - std::vector<ISrsDvrAsyncCall*> copies = callbacks;  
603 - callbacks.clear();  
604 -  
605 - std::vector<ISrsDvrAsyncCall*>::iterator it;  
606 - for (it = copies.begin(); it != copies.end(); ++it) {  
607 - ISrsDvrAsyncCall* call = *it;  
608 - if ((ret = call->call()) != ERROR_SUCCESS) {  
609 - srs_warn("dvr: ignore callback %s, ret=%d", call->to_string().c_str(), ret);  
610 - }  
611 - srs_freep(call);  
612 - }  
613 -  
614 - return ret;  
615 -}  
616 -  
617 SrsDvrPlan::SrsDvrPlan() 544 SrsDvrPlan::SrsDvrPlan()
618 { 545 {
619 req = NULL; 546 req = NULL;
@@ -49,7 +49,7 @@ class SrsThread; @@ -49,7 +49,7 @@ class SrsThread;
49 49
50 #include <srs_app_source.hpp> 50 #include <srs_app_source.hpp>
51 #include <srs_app_reload.hpp> 51 #include <srs_app_reload.hpp>
52 -#include <srs_app_thread.hpp> 52 +#include <srs_app_async_call.hpp>
53 53
54 /** 54 /**
55 * a piece of flv segment. 55 * a piece of flv segment.
@@ -178,15 +178,6 @@ public: @@ -178,15 +178,6 @@ public:
178 /** 178 /**
179 * the dvr async call. 179 * the dvr async call.
180 */ 180 */
181 -class ISrsDvrAsyncCall  
182 -{  
183 -public:  
184 - ISrsDvrAsyncCall();  
185 - virtual ~ISrsDvrAsyncCall();  
186 -public:  
187 - virtual int call() = 0;  
188 - virtual std::string to_string() = 0;  
189 -};  
190 class SrsDvrAsyncCallOnDvr : public ISrsDvrAsyncCall 181 class SrsDvrAsyncCallOnDvr : public ISrsDvrAsyncCall
191 { 182 {
192 private: 183 private:
@@ -201,25 +192,6 @@ public: @@ -201,25 +192,6 @@ public:
201 }; 192 };
202 193
203 /** 194 /**
204 -* the async callback for dvr.  
205 -*/  
206 -class SrsDvrAsyncCallThread : public ISrsThreadHandler  
207 -{  
208 -private:  
209 - SrsThread* pthread;  
210 - std::vector<ISrsDvrAsyncCall*> callbacks;  
211 -public:  
212 - SrsDvrAsyncCallThread();  
213 - virtual ~SrsDvrAsyncCallThread();  
214 -public:  
215 - virtual int call(ISrsDvrAsyncCall* c);  
216 -public:  
217 - virtual int start();  
218 - virtual void stop();  
219 - virtual int cycle();  
220 -};  
221 -  
222 -/**  
223 * the plan for dvr. 195 * the plan for dvr.
224 * use to control the following dvr params: 196 * use to control the following dvr params:
225 * 1. filename: the filename for record file. 197 * 1. filename: the filename for record file.
@@ -54,6 +54,7 @@ using namespace std; @@ -54,6 +54,7 @@ using namespace std;
54 #include <srs_rtmp_buffer.hpp> 54 #include <srs_rtmp_buffer.hpp>
55 #include <srs_kernel_ts.hpp> 55 #include <srs_kernel_ts.hpp>
56 #include <srs_app_utility.hpp> 56 #include <srs_app_utility.hpp>
  57 +#include <srs_app_http_hooks.hpp>
57 58
58 // drop the segment when duration of ts too small. 59 // drop the segment when duration of ts too small.
59 #define SRS_AUTO_HLS_SEGMENT_MIN_DURATION_MS 100 60 #define SRS_AUTO_HLS_SEGMENT_MIN_DURATION_MS 100
@@ -169,6 +170,53 @@ void SrsHlsSegment::update_duration(int64_t current_frame_dts) @@ -169,6 +170,53 @@ void SrsHlsSegment::update_duration(int64_t current_frame_dts)
169 return; 170 return;
170 } 171 }
171 172
  173 +SrsDvrAsyncCallOnHls::SrsDvrAsyncCallOnHls(SrsRequest* r, string p, int s)
  174 +{
  175 + req = r;
  176 + path = p;
  177 + seq_no = s;
  178 +}
  179 +
  180 +SrsDvrAsyncCallOnHls::~SrsDvrAsyncCallOnHls()
  181 +{
  182 +}
  183 +
  184 +int SrsDvrAsyncCallOnHls::call()
  185 +{
  186 + int ret = ERROR_SUCCESS;
  187 +
  188 +#ifdef SRS_AUTO_HTTP_CALLBACK
  189 + // http callback for on_hls in config.
  190 + if (_srs_config->get_vhost_http_hooks_enabled(req->vhost)) {
  191 + // HTTP: on_hls
  192 + SrsConfDirective* on_hls = _srs_config->get_vhost_on_hls(req->vhost);
  193 + if (!on_hls) {
  194 + srs_info("ignore the empty http callback: on_hls");
  195 + return ret;
  196 + }
  197 +
  198 + std::string file = path;
  199 + int sn = seq_no;
  200 + for (int i = 0; i < (int)on_hls->args.size(); i++) {
  201 + std::string url = on_hls->args.at(i);
  202 + if ((ret = SrsHttpHooks::on_hls(url, req, file, sn)) != ERROR_SUCCESS) {
  203 + srs_error("hook client on_hls failed. url=%s, ret=%d", url.c_str(), ret);
  204 + return ret;
  205 + }
  206 + }
  207 + }
  208 +#endif
  209 +
  210 + return ret;
  211 +}
  212 +
  213 +string SrsDvrAsyncCallOnHls::to_string()
  214 +{
  215 + std::stringstream ss;
  216 + ss << "vhost=" << req->vhost << ", file=" << path;
  217 + return ss.str();
  218 +}
  219 +
172 SrsHlsMuxer::SrsHlsMuxer() 220 SrsHlsMuxer::SrsHlsMuxer()
173 { 221 {
174 req = NULL; 222 req = NULL;
@@ -177,6 +225,7 @@ SrsHlsMuxer::SrsHlsMuxer() @@ -177,6 +225,7 @@ SrsHlsMuxer::SrsHlsMuxer()
177 hls_aof_ratio = 1.0; 225 hls_aof_ratio = 1.0;
178 hls_fragment_deviation = 0; 226 hls_fragment_deviation = 0;
179 previous_floor_ts = 0; 227 previous_floor_ts = 0;
  228 + accept_floor_ts = 0;
180 hls_ts_floor = false; 229 hls_ts_floor = false;
181 target_duration = 0; 230 target_duration = 0;
182 _sequence_no = 0; 231 _sequence_no = 0;
@@ -184,6 +233,7 @@ SrsHlsMuxer::SrsHlsMuxer() @@ -184,6 +233,7 @@ SrsHlsMuxer::SrsHlsMuxer()
184 acodec = SrsCodecAudioReserved1; 233 acodec = SrsCodecAudioReserved1;
185 should_write_cache = false; 234 should_write_cache = false;
186 should_write_file = true; 235 should_write_file = true;
  236 + async = new SrsDvrAsyncCallThread();
187 } 237 }
188 238
189 SrsHlsMuxer::~SrsHlsMuxer() 239 SrsHlsMuxer::~SrsHlsMuxer()
@@ -197,6 +247,7 @@ SrsHlsMuxer::~SrsHlsMuxer() @@ -197,6 +247,7 @@ SrsHlsMuxer::~SrsHlsMuxer()
197 247
198 srs_freep(current); 248 srs_freep(current);
199 srs_freep(req); 249 srs_freep(req);
  250 + srs_freep(async);
200 } 251 }
201 252
202 int SrsHlsMuxer::initialize(ISrsHlsHandler* h) 253 int SrsHlsMuxer::initialize(ISrsHlsHandler* h)
@@ -205,6 +256,10 @@ int SrsHlsMuxer::initialize(ISrsHlsHandler* h) @@ -205,6 +256,10 @@ int SrsHlsMuxer::initialize(ISrsHlsHandler* h)
205 256
206 handler = h; 257 handler = h;
207 258
  259 + if ((ret = async->start()) != ERROR_SUCCESS) {
  260 + return ret;
  261 + }
  262 +
208 return ret; 263 return ret;
209 } 264 }
210 265
@@ -244,6 +299,7 @@ int SrsHlsMuxer::update_config(SrsRequest* r, string entry_prefix, @@ -244,6 +299,7 @@ int SrsHlsMuxer::update_config(SrsRequest* r, string entry_prefix,
244 hls_aof_ratio = aof_ratio; 299 hls_aof_ratio = aof_ratio;
245 hls_ts_floor = ts_floor; 300 hls_ts_floor = ts_floor;
246 previous_floor_ts = 0; 301 previous_floor_ts = 0;
  302 + accept_floor_ts = 0;
247 hls_window = window; 303 hls_window = window;
248 // for the first time, we set to -N% of fragment, 304 // for the first time, we set to -N% of fragment,
249 // that is, the first piece always smaller. 305 // that is, the first piece always smaller.
@@ -331,9 +387,17 @@ int SrsHlsMuxer::segment_open(int64_t segment_start_dts) @@ -331,9 +387,17 @@ int SrsHlsMuxer::segment_open(int64_t segment_start_dts)
331 std::string ts_file = hls_ts_file; 387 std::string ts_file = hls_ts_file;
332 ts_file = srs_path_build_stream(ts_file, req->vhost, req->app, req->stream); 388 ts_file = srs_path_build_stream(ts_file, req->vhost, req->app, req->stream);
333 if (hls_ts_floor) { 389 if (hls_ts_floor) {
  390 + // accept the floor ts for the first piece.
334 int64_t floor_ts = (int64_t)(srs_get_system_time_ms() / (1000 * hls_fragment)); 391 int64_t floor_ts = (int64_t)(srs_get_system_time_ms() / (1000 * hls_fragment));
  392 + if (!accept_floor_ts) {
  393 + accept_floor_ts = floor_ts - 1;
  394 + } else {
  395 + accept_floor_ts++;
  396 + }
  397 +
  398 + // we always ensure the piece is increase one by one.
335 std::stringstream ts_floor; 399 std::stringstream ts_floor;
336 - ts_floor << floor_ts; 400 + ts_floor << accept_floor_ts;
337 ts_file = srs_string_replace(ts_file, "[timestamp]", ts_floor.str()); 401 ts_file = srs_string_replace(ts_file, "[timestamp]", ts_floor.str());
338 402
339 // dup/jmp detect for ts in floor mode. 403 // dup/jmp detect for ts in floor mode.
@@ -514,6 +578,11 @@ int SrsHlsMuxer::segment_close(string log_desc) @@ -514,6 +578,11 @@ int SrsHlsMuxer::segment_close(string log_desc)
514 hls_fragment_deviation += (double)(hls_fragment - current->duration); 578 hls_fragment_deviation += (double)(hls_fragment - current->duration);
515 } 579 }
516 580
  581 + // use async to call the http hooks, for it will cause thread switch.
  582 + if ((ret = async->call(new SrsDvrAsyncCallOnHls(req, current->full_path, current->sequence_no))) != ERROR_SUCCESS) {
  583 + return ret;
  584 + }
  585 +
517 srs_info("%s reap ts segment, sequence_no=%d, uri=%s, duration=%.2f, start=%"PRId64", deviation=%.2f", 586 srs_info("%s reap ts segment, sequence_no=%d, uri=%s, duration=%.2f, start=%"PRId64", deviation=%.2f",
518 log_desc.c_str(), current->sequence_no, current->uri.c_str(), current->duration, 587 log_desc.c_str(), current->sequence_no, current->uri.c_str(), current->duration,
519 current->segment_start_dts, hls_fragment_deviation); 588 current->segment_start_dts, hls_fragment_deviation);
@@ -39,6 +39,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. @@ -39,6 +39,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
39 39
40 #include <srs_kernel_codec.hpp> 40 #include <srs_kernel_codec.hpp>
41 #include <srs_kernel_file.hpp> 41 #include <srs_kernel_file.hpp>
  42 +#include <srs_app_async_call.hpp>
42 43
43 class SrsSharedPtrMessage; 44 class SrsSharedPtrMessage;
44 class SrsCodecSample; 45 class SrsCodecSample;
@@ -155,6 +156,23 @@ public: @@ -155,6 +156,23 @@ public:
155 }; 156 };
156 157
157 /** 158 /**
  159 + * the dvr async call.
  160 + */
  161 +class SrsDvrAsyncCallOnHls : public ISrsDvrAsyncCall
  162 +{
  163 +private:
  164 + std::string path;
  165 + int seq_no;
  166 + SrsRequest* req;
  167 +public:
  168 + SrsDvrAsyncCallOnHls(SrsRequest* r, std::string p, int s);
  169 + virtual ~SrsDvrAsyncCallOnHls();
  170 +public:
  171 + virtual int call();
  172 + virtual std::string to_string();
  173 +};
  174 +
  175 +/**
158 * muxer the HLS stream(m3u8 and ts files). 176 * muxer the HLS stream(m3u8 and ts files).
159 * generally, the m3u8 muxer only provides methods to open/close segments, 177 * generally, the m3u8 muxer only provides methods to open/close segments,
160 * to flush video/audio, without any mechenisms. 178 * to flush video/audio, without any mechenisms.
@@ -174,6 +192,7 @@ private: @@ -174,6 +192,7 @@ private:
174 double hls_aof_ratio; 192 double hls_aof_ratio;
175 double hls_fragment; 193 double hls_fragment;
176 double hls_window; 194 double hls_window;
  195 + SrsDvrAsyncCallThread* async;
177 private: 196 private:
178 // whether use floor algorithm for timestamp. 197 // whether use floor algorithm for timestamp.
179 bool hls_ts_floor; 198 bool hls_ts_floor;
@@ -182,6 +201,7 @@ private: @@ -182,6 +201,7 @@ private:
182 double hls_fragment_deviation; 201 double hls_fragment_deviation;
183 // the previous reap floor timestamp, 202 // the previous reap floor timestamp,
184 // used to detect the dup or jmp or ts. 203 // used to detect the dup or jmp or ts.
  204 + int64_t accept_floor_ts;
185 int64_t previous_floor_ts; 205 int64_t previous_floor_ts;
186 private: 206 private:
187 int _sequence_no; 207 int _sequence_no;
@@ -36,6 +36,7 @@ using namespace std; @@ -36,6 +36,7 @@ using namespace std;
36 #include <srs_app_dvr.hpp> 36 #include <srs_app_dvr.hpp>
37 #include <srs_app_http_client.hpp> 37 #include <srs_app_http_client.hpp>
38 #include <srs_core_autofree.hpp> 38 #include <srs_core_autofree.hpp>
  39 +#include <srs_app_config.hpp>
39 40
40 #define SRS_HTTP_RESPONSE_OK SRS_XSTR(ERROR_SUCCESS) 41 #define SRS_HTTP_RESPONSE_OK SRS_XSTR(ERROR_SUCCESS)
41 42
@@ -50,15 +51,17 @@ SrsHttpHooks::~SrsHttpHooks() @@ -50,15 +51,17 @@ SrsHttpHooks::~SrsHttpHooks()
50 { 51 {
51 } 52 }
52 53
53 -int SrsHttpHooks::on_connect(string url, int client_id, string ip, SrsRequest* req) 54 +int SrsHttpHooks::on_connect(string url, SrsRequest* req)
54 { 55 {
55 int ret = ERROR_SUCCESS; 56 int ret = ERROR_SUCCESS;
56 57
  58 + int client_id = _srs_context->get_id();
  59 +
57 std::stringstream ss; 60 std::stringstream ss;
58 ss << SRS_JOBJECT_START 61 ss << SRS_JOBJECT_START
59 << SRS_JFIELD_STR("action", "on_connect") << SRS_JFIELD_CONT 62 << SRS_JFIELD_STR("action", "on_connect") << SRS_JFIELD_CONT
60 << SRS_JFIELD_ORG("client_id", client_id) << SRS_JFIELD_CONT 63 << SRS_JFIELD_ORG("client_id", client_id) << SRS_JFIELD_CONT
61 - << SRS_JFIELD_STR("ip", ip) << SRS_JFIELD_CONT 64 + << SRS_JFIELD_STR("ip", req->ip) << SRS_JFIELD_CONT
62 << SRS_JFIELD_STR("vhost", req->vhost) << SRS_JFIELD_CONT 65 << SRS_JFIELD_STR("vhost", req->vhost) << SRS_JFIELD_CONT
63 << SRS_JFIELD_STR("app", req->app) << SRS_JFIELD_CONT 66 << SRS_JFIELD_STR("app", req->app) << SRS_JFIELD_CONT
64 << SRS_JFIELD_STR("tcUrl", req->tcUrl) << SRS_JFIELD_CONT 67 << SRS_JFIELD_STR("tcUrl", req->tcUrl) << SRS_JFIELD_CONT
@@ -82,15 +85,17 @@ int SrsHttpHooks::on_connect(string url, int client_id, string ip, SrsRequest* r @@ -82,15 +85,17 @@ int SrsHttpHooks::on_connect(string url, int client_id, string ip, SrsRequest* r
82 return ret; 85 return ret;
83 } 86 }
84 87
85 -void SrsHttpHooks::on_close(string url, int client_id, string ip, SrsRequest* req, int64_t send_bytes, int64_t recv_bytes) 88 +void SrsHttpHooks::on_close(string url, SrsRequest* req, int64_t send_bytes, int64_t recv_bytes)
86 { 89 {
87 int ret = ERROR_SUCCESS; 90 int ret = ERROR_SUCCESS;
88 91
  92 + int client_id = _srs_context->get_id();
  93 +
89 std::stringstream ss; 94 std::stringstream ss;
90 ss << SRS_JOBJECT_START 95 ss << SRS_JOBJECT_START
91 << SRS_JFIELD_STR("action", "on_close") << SRS_JFIELD_CONT 96 << SRS_JFIELD_STR("action", "on_close") << SRS_JFIELD_CONT
92 << SRS_JFIELD_ORG("client_id", client_id) << SRS_JFIELD_CONT 97 << SRS_JFIELD_ORG("client_id", client_id) << SRS_JFIELD_CONT
93 - << SRS_JFIELD_STR("ip", ip) << SRS_JFIELD_CONT 98 + << SRS_JFIELD_STR("ip", req->ip) << SRS_JFIELD_CONT
94 << SRS_JFIELD_STR("vhost", req->vhost) << SRS_JFIELD_CONT 99 << SRS_JFIELD_STR("vhost", req->vhost) << SRS_JFIELD_CONT
95 << SRS_JFIELD_ORG("send_bytes", send_bytes) << SRS_JFIELD_CONT 100 << SRS_JFIELD_ORG("send_bytes", send_bytes) << SRS_JFIELD_CONT
96 << SRS_JFIELD_ORG("recv_bytes", recv_bytes) << SRS_JFIELD_CONT 101 << SRS_JFIELD_ORG("recv_bytes", recv_bytes) << SRS_JFIELD_CONT
@@ -114,15 +119,17 @@ void SrsHttpHooks::on_close(string url, int client_id, string ip, SrsRequest* re @@ -114,15 +119,17 @@ void SrsHttpHooks::on_close(string url, int client_id, string ip, SrsRequest* re
114 return; 119 return;
115 } 120 }
116 121
117 -int SrsHttpHooks::on_publish(string url, int client_id, string ip, SrsRequest* req) 122 +int SrsHttpHooks::on_publish(string url, SrsRequest* req)
118 { 123 {
119 int ret = ERROR_SUCCESS; 124 int ret = ERROR_SUCCESS;
120 125
  126 + int client_id = _srs_context->get_id();
  127 +
121 std::stringstream ss; 128 std::stringstream ss;
122 ss << SRS_JOBJECT_START 129 ss << SRS_JOBJECT_START
123 << SRS_JFIELD_STR("action", "on_publish") << SRS_JFIELD_CONT 130 << SRS_JFIELD_STR("action", "on_publish") << SRS_JFIELD_CONT
124 << SRS_JFIELD_ORG("client_id", client_id) << SRS_JFIELD_CONT 131 << SRS_JFIELD_ORG("client_id", client_id) << SRS_JFIELD_CONT
125 - << SRS_JFIELD_STR("ip", ip) << SRS_JFIELD_CONT 132 + << SRS_JFIELD_STR("ip", req->ip) << SRS_JFIELD_CONT
126 << SRS_JFIELD_STR("vhost", req->vhost) << SRS_JFIELD_CONT 133 << SRS_JFIELD_STR("vhost", req->vhost) << SRS_JFIELD_CONT
127 << SRS_JFIELD_STR("app", req->app) << SRS_JFIELD_CONT 134 << SRS_JFIELD_STR("app", req->app) << SRS_JFIELD_CONT
128 << SRS_JFIELD_STR("stream", req->stream) 135 << SRS_JFIELD_STR("stream", req->stream)
@@ -145,15 +152,17 @@ int SrsHttpHooks::on_publish(string url, int client_id, string ip, SrsRequest* r @@ -145,15 +152,17 @@ int SrsHttpHooks::on_publish(string url, int client_id, string ip, SrsRequest* r
145 return ret; 152 return ret;
146 } 153 }
147 154
148 -void SrsHttpHooks::on_unpublish(string url, int client_id, string ip, SrsRequest* req) 155 +void SrsHttpHooks::on_unpublish(string url, SrsRequest* req)
149 { 156 {
150 int ret = ERROR_SUCCESS; 157 int ret = ERROR_SUCCESS;
151 158
  159 + int client_id = _srs_context->get_id();
  160 +
152 std::stringstream ss; 161 std::stringstream ss;
153 ss << SRS_JOBJECT_START 162 ss << SRS_JOBJECT_START
154 << SRS_JFIELD_STR("action", "on_unpublish") << SRS_JFIELD_CONT 163 << SRS_JFIELD_STR("action", "on_unpublish") << SRS_JFIELD_CONT
155 << SRS_JFIELD_ORG("client_id", client_id) << SRS_JFIELD_CONT 164 << SRS_JFIELD_ORG("client_id", client_id) << SRS_JFIELD_CONT
156 - << SRS_JFIELD_STR("ip", ip) << SRS_JFIELD_CONT 165 + << SRS_JFIELD_STR("ip", req->ip) << SRS_JFIELD_CONT
157 << SRS_JFIELD_STR("vhost", req->vhost) << SRS_JFIELD_CONT 166 << SRS_JFIELD_STR("vhost", req->vhost) << SRS_JFIELD_CONT
158 << SRS_JFIELD_STR("app", req->app) << SRS_JFIELD_CONT 167 << SRS_JFIELD_STR("app", req->app) << SRS_JFIELD_CONT
159 << SRS_JFIELD_STR("stream", req->stream) 168 << SRS_JFIELD_STR("stream", req->stream)
@@ -176,15 +185,17 @@ void SrsHttpHooks::on_unpublish(string url, int client_id, string ip, SrsRequest @@ -176,15 +185,17 @@ void SrsHttpHooks::on_unpublish(string url, int client_id, string ip, SrsRequest
176 return; 185 return;
177 } 186 }
178 187
179 -int SrsHttpHooks::on_play(string url, int client_id, string ip, SrsRequest* req) 188 +int SrsHttpHooks::on_play(string url, SrsRequest* req)
180 { 189 {
181 int ret = ERROR_SUCCESS; 190 int ret = ERROR_SUCCESS;
182 191
  192 + int client_id = _srs_context->get_id();
  193 +
183 std::stringstream ss; 194 std::stringstream ss;
184 ss << SRS_JOBJECT_START 195 ss << SRS_JOBJECT_START
185 << SRS_JFIELD_STR("action", "on_play") << SRS_JFIELD_CONT 196 << SRS_JFIELD_STR("action", "on_play") << SRS_JFIELD_CONT
186 << SRS_JFIELD_ORG("client_id", client_id) << SRS_JFIELD_CONT 197 << SRS_JFIELD_ORG("client_id", client_id) << SRS_JFIELD_CONT
187 - << SRS_JFIELD_STR("ip", ip) << SRS_JFIELD_CONT 198 + << SRS_JFIELD_STR("ip", req->ip) << SRS_JFIELD_CONT
188 << SRS_JFIELD_STR("vhost", req->vhost) << SRS_JFIELD_CONT 199 << SRS_JFIELD_STR("vhost", req->vhost) << SRS_JFIELD_CONT
189 << SRS_JFIELD_STR("app", req->app) << SRS_JFIELD_CONT 200 << SRS_JFIELD_STR("app", req->app) << SRS_JFIELD_CONT
190 << SRS_JFIELD_STR("stream", req->stream) 201 << SRS_JFIELD_STR("stream", req->stream)
@@ -207,15 +218,17 @@ int SrsHttpHooks::on_play(string url, int client_id, string ip, SrsRequest* req) @@ -207,15 +218,17 @@ int SrsHttpHooks::on_play(string url, int client_id, string ip, SrsRequest* req)
207 return ret; 218 return ret;
208 } 219 }
209 220
210 -void SrsHttpHooks::on_stop(string url, int client_id, string ip, SrsRequest* req) 221 +void SrsHttpHooks::on_stop(string url, SrsRequest* req)
211 { 222 {
212 int ret = ERROR_SUCCESS; 223 int ret = ERROR_SUCCESS;
213 224
  225 + int client_id = _srs_context->get_id();
  226 +
214 std::stringstream ss; 227 std::stringstream ss;
215 ss << SRS_JOBJECT_START 228 ss << SRS_JOBJECT_START
216 << SRS_JFIELD_STR("action", "on_stop") << SRS_JFIELD_CONT 229 << SRS_JFIELD_STR("action", "on_stop") << SRS_JFIELD_CONT
217 << SRS_JFIELD_ORG("client_id", client_id) << SRS_JFIELD_CONT 230 << SRS_JFIELD_ORG("client_id", client_id) << SRS_JFIELD_CONT
218 - << SRS_JFIELD_STR("ip", ip) << SRS_JFIELD_CONT 231 + << SRS_JFIELD_STR("ip", req->ip) << SRS_JFIELD_CONT
219 << SRS_JFIELD_STR("vhost", req->vhost) << SRS_JFIELD_CONT 232 << SRS_JFIELD_STR("vhost", req->vhost) << SRS_JFIELD_CONT
220 << SRS_JFIELD_STR("app", req->app) << SRS_JFIELD_CONT 233 << SRS_JFIELD_STR("app", req->app) << SRS_JFIELD_CONT
221 << SRS_JFIELD_STR("stream", req->stream) 234 << SRS_JFIELD_STR("stream", req->stream)
@@ -238,15 +251,18 @@ void SrsHttpHooks::on_stop(string url, int client_id, string ip, SrsRequest* req @@ -238,15 +251,18 @@ void SrsHttpHooks::on_stop(string url, int client_id, string ip, SrsRequest* req
238 return; 251 return;
239 } 252 }
240 253
241 -int SrsHttpHooks::on_dvr(string url, int client_id, string ip, SrsRequest* req, string cwd, string file) 254 +int SrsHttpHooks::on_dvr(string url, SrsRequest* req, string file)
242 { 255 {
243 int ret = ERROR_SUCCESS; 256 int ret = ERROR_SUCCESS;
244 257
  258 + int client_id = _srs_context->get_id();
  259 + std::string cwd = _srs_config->cwd();
  260 +
245 std::stringstream ss; 261 std::stringstream ss;
246 ss << SRS_JOBJECT_START 262 ss << SRS_JOBJECT_START
247 << SRS_JFIELD_STR("action", "on_dvr") << SRS_JFIELD_CONT 263 << SRS_JFIELD_STR("action", "on_dvr") << SRS_JFIELD_CONT
248 << SRS_JFIELD_ORG("client_id", client_id) << SRS_JFIELD_CONT 264 << SRS_JFIELD_ORG("client_id", client_id) << SRS_JFIELD_CONT
249 - << SRS_JFIELD_STR("ip", ip) << SRS_JFIELD_CONT 265 + << SRS_JFIELD_STR("ip", req->ip) << SRS_JFIELD_CONT
250 << SRS_JFIELD_STR("vhost", req->vhost) << SRS_JFIELD_CONT 266 << SRS_JFIELD_STR("vhost", req->vhost) << SRS_JFIELD_CONT
251 << SRS_JFIELD_STR("app", req->app) << SRS_JFIELD_CONT 267 << SRS_JFIELD_STR("app", req->app) << SRS_JFIELD_CONT
252 << SRS_JFIELD_STR("stream", req->stream) << SRS_JFIELD_CONT 268 << SRS_JFIELD_STR("stream", req->stream) << SRS_JFIELD_CONT
@@ -271,32 +287,37 @@ int SrsHttpHooks::on_dvr(string url, int client_id, string ip, SrsRequest* req, @@ -271,32 +287,37 @@ int SrsHttpHooks::on_dvr(string url, int client_id, string ip, SrsRequest* req,
271 return ret; 287 return ret;
272 } 288 }
273 289
274 -int SrsHttpHooks::on_dvr_reap_segment(string url, int client_id, SrsRequest* req, string cwd, string file) 290 +int SrsHttpHooks::on_hls(string url, SrsRequest* req, string file, int sn)
275 { 291 {
276 int ret = ERROR_SUCCESS; 292 int ret = ERROR_SUCCESS;
277 293
  294 + int client_id = _srs_context->get_id();
  295 + std::string cwd = _srs_config->cwd();
  296 +
278 std::stringstream ss; 297 std::stringstream ss;
279 ss << SRS_JOBJECT_START 298 ss << SRS_JOBJECT_START
280 - << SRS_JFIELD_STR("action", "on_dvr_reap_segment") << SRS_JFIELD_CONT 299 + << SRS_JFIELD_STR("action", "on_hls") << SRS_JFIELD_CONT
281 << SRS_JFIELD_ORG("client_id", client_id) << SRS_JFIELD_CONT 300 << SRS_JFIELD_ORG("client_id", client_id) << SRS_JFIELD_CONT
  301 + << SRS_JFIELD_STR("ip", req->ip) << SRS_JFIELD_CONT
282 << SRS_JFIELD_STR("vhost", req->vhost) << SRS_JFIELD_CONT 302 << SRS_JFIELD_STR("vhost", req->vhost) << SRS_JFIELD_CONT
283 << SRS_JFIELD_STR("app", req->app) << SRS_JFIELD_CONT 303 << SRS_JFIELD_STR("app", req->app) << SRS_JFIELD_CONT
284 << SRS_JFIELD_STR("stream", req->stream) << SRS_JFIELD_CONT 304 << SRS_JFIELD_STR("stream", req->stream) << SRS_JFIELD_CONT
285 << SRS_JFIELD_STR("cwd", cwd) << SRS_JFIELD_CONT 305 << SRS_JFIELD_STR("cwd", cwd) << SRS_JFIELD_CONT
286 - << SRS_JFIELD_STR("file", file) 306 + << SRS_JFIELD_STR("file", file) << SRS_JFIELD_CONT
  307 + << SRS_JFIELD_ORG("seq_no", sn)
287 << SRS_JOBJECT_END; 308 << SRS_JOBJECT_END;
288 309
289 std::string data = ss.str(); 310 std::string data = ss.str();
290 std::string res; 311 std::string res;
291 int status_code; 312 int status_code;
292 if ((ret = do_post(url, data, status_code, res)) != ERROR_SUCCESS) { 313 if ((ret = do_post(url, data, status_code, res)) != ERROR_SUCCESS) {
293 - srs_error("http post on_dvr_reap_segment uri failed, ignored. " 314 + srs_error("http post on_hls uri failed, ignored. "
294 "client_id=%d, url=%s, request=%s, response=%s, code=%d, ret=%d", 315 "client_id=%d, url=%s, request=%s, response=%s, code=%d, ret=%d",
295 client_id, url.c_str(), data.c_str(), res.c_str(), status_code, ret); 316 client_id, url.c_str(), data.c_str(), res.c_str(), status_code, ret);
296 return ret; 317 return ret;
297 } 318 }
298 319
299 - srs_trace("http hook on_dvr_reap_segment success. " 320 + srs_trace("http hook on_hls success. "
300 "client_id=%d, url=%s, request=%s, response=%s, ret=%d", 321 "client_id=%d, url=%s, request=%s, response=%s, ret=%d",
301 client_id, url.c_str(), data.c_str(), res.c_str(), ret); 322 client_id, url.c_str(), data.c_str(), res.c_str(), ret);
302 323
@@ -55,64 +55,55 @@ public: @@ -55,64 +55,55 @@ public:
55 public: 55 public:
56 /** 56 /**
57 * on_connect hook, when client connect to srs. 57 * on_connect hook, when client connect to srs.
58 - * @param client_id the id of client on server.  
59 * @param url the api server url, to valid the client. 58 * @param url the api server url, to valid the client.
60 * ignore if empty. 59 * ignore if empty.
61 */ 60 */
62 - static int on_connect(std::string url, int client_id, std::string ip, SrsRequest* req); 61 + static int on_connect(std::string url, SrsRequest* req);
63 /** 62 /**
64 * on_close hook, when client disconnect to srs, where client is valid by on_connect. 63 * on_close hook, when client disconnect to srs, where client is valid by on_connect.
65 - * @param client_id the id of client on server.  
66 * @param url the api server url, to process the event. 64 * @param url the api server url, to process the event.
67 * ignore if empty. 65 * ignore if empty.
68 */ 66 */
69 - static void on_close(std::string url, int client_id, std::string ip, SrsRequest* req, int64_t send_bytes, int64_t recv_bytes); 67 + static void on_close(std::string url, SrsRequest* req, int64_t send_bytes, int64_t recv_bytes);
70 /** 68 /**
71 * on_publish hook, when client(encoder) start to publish stream 69 * on_publish hook, when client(encoder) start to publish stream
72 - * @param client_id the id of client on server.  
73 * @param url the api server url, to valid the client. 70 * @param url the api server url, to valid the client.
74 * ignore if empty. 71 * ignore if empty.
75 */ 72 */
76 - static int on_publish(std::string url, int client_id, std::string ip, SrsRequest* req); 73 + static int on_publish(std::string url, SrsRequest* req);
77 /** 74 /**
78 * on_unpublish hook, when client(encoder) stop publish stream. 75 * on_unpublish hook, when client(encoder) stop publish stream.
79 - * @param client_id the id of client on server.  
80 * @param url the api server url, to process the event. 76 * @param url the api server url, to process the event.
81 * ignore if empty. 77 * ignore if empty.
82 */ 78 */
83 - static void on_unpublish(std::string url, int client_id, std::string ip, SrsRequest* req); 79 + static void on_unpublish(std::string url, SrsRequest* req);
84 /** 80 /**
85 * on_play hook, when client start to play stream. 81 * on_play hook, when client start to play stream.
86 - * @param client_id the id of client on server.  
87 * @param url the api server url, to valid the client. 82 * @param url the api server url, to valid the client.
88 * ignore if empty. 83 * ignore if empty.
89 */ 84 */
90 - static int on_play(std::string url, int client_id, std::string ip, SrsRequest* req); 85 + static int on_play(std::string url, SrsRequest* req);
91 /** 86 /**
92 * on_stop hook, when client stop to play the stream. 87 * on_stop hook, when client stop to play the stream.
93 - * @param client_id the id of client on server.  
94 * @param url the api server url, to process the event. 88 * @param url the api server url, to process the event.
95 * ignore if empty. 89 * ignore if empty.
96 */ 90 */
97 - static void on_stop(std::string url, int client_id, std::string ip, SrsRequest* req); 91 + static void on_stop(std::string url, SrsRequest* req);
98 /** 92 /**
99 * on_dvr hook, when reap a dvr file. 93 * 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. 94 * @param url the api server url, to process the event.
102 * ignore if empty. 95 * 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. 96 * @param file the file path, can be relative or absolute path.
105 */ 97 */
106 - static int on_dvr(std::string url, int client_id, std::string ip, SrsRequest* req, std::string cwd, std::string file); 98 + static int on_dvr(std::string url, SrsRequest* req, std::string file);
107 /** 99 /**
108 - * when dvr reap segment, callback.  
109 - * @param client_id the id of client on server. 100 + * when hls reap segment, callback.
110 * @param url the api server url, to process the event. 101 * @param url the api server url, to process the event.
111 * ignore if empty. 102 * ignore if empty.
112 - * @param cwd the current work directory, used to resolve the reltive file path.  
113 - * @param file the file path, can be relative or absolute path. 103 + * @param file the ts file path, can be relative or absolute path.
  104 + * @param sn the seq_no, the sequence number of ts in hls/m3u8.
114 */ 105 */
115 - static int on_dvr_reap_segment(std::string url, int client_id, SrsRequest* req, std::string cwd, std::string file); 106 + static int on_hls(std::string url, SrsRequest* req, std::string file, int sn);
116 private: 107 private:
117 static int do_post(std::string url, std::string req, int& code, std::string& res); 108 static int do_post(std::string url, std::string req, int& code, std::string& res);
118 }; 109 };
@@ -1265,10 +1265,9 @@ int SrsRtmpConn::http_hooks_on_connect() @@ -1265,10 +1265,9 @@ int SrsRtmpConn::http_hooks_on_connect()
1265 return ret; 1265 return ret;
1266 } 1266 }
1267 1267
1268 - int connection_id = _srs_context->get_id();  
1269 for (int i = 0; i < (int)on_connect->args.size(); i++) { 1268 for (int i = 0; i < (int)on_connect->args.size(); i++) {
1270 std::string url = on_connect->args.at(i); 1269 std::string url = on_connect->args.at(i);
1271 - if ((ret = SrsHttpHooks::on_connect(url, connection_id, ip, req)) != ERROR_SUCCESS) { 1270 + if ((ret = SrsHttpHooks::on_connect(url, req)) != ERROR_SUCCESS) {
1272 srs_error("hook client on_connect failed. url=%s, ret=%d", url.c_str(), ret); 1271 srs_error("hook client on_connect failed. url=%s, ret=%d", url.c_str(), ret);
1273 return ret; 1272 return ret;
1274 } 1273 }
@@ -1291,10 +1290,9 @@ void SrsRtmpConn::http_hooks_on_close() @@ -1291,10 +1290,9 @@ void SrsRtmpConn::http_hooks_on_close()
1291 return; 1290 return;
1292 } 1291 }
1293 1292
1294 - int connection_id = _srs_context->get_id();  
1295 for (int i = 0; i < (int)on_close->args.size(); i++) { 1293 for (int i = 0; i < (int)on_close->args.size(); i++) {
1296 std::string url = on_close->args.at(i); 1294 std::string url = on_close->args.at(i);
1297 - SrsHttpHooks::on_close(url, connection_id, ip, req, kbps->get_send_bytes(), kbps->get_recv_bytes()); 1295 + SrsHttpHooks::on_close(url, req, kbps->get_send_bytes(), kbps->get_recv_bytes());
1298 } 1296 }
1299 } 1297 }
1300 #endif 1298 #endif
@@ -1313,10 +1311,9 @@ int SrsRtmpConn::http_hooks_on_publish() @@ -1313,10 +1311,9 @@ int SrsRtmpConn::http_hooks_on_publish()
1313 return ret; 1311 return ret;
1314 } 1312 }
1315 1313
1316 - int connection_id = _srs_context->get_id();  
1317 for (int i = 0; i < (int)on_publish->args.size(); i++) { 1314 for (int i = 0; i < (int)on_publish->args.size(); i++) {
1318 std::string url = on_publish->args.at(i); 1315 std::string url = on_publish->args.at(i);
1319 - if ((ret = SrsHttpHooks::on_publish(url, connection_id, ip, req)) != ERROR_SUCCESS) { 1316 + if ((ret = SrsHttpHooks::on_publish(url, req)) != ERROR_SUCCESS) {
1320 srs_error("hook client on_publish failed. url=%s, ret=%d", url.c_str(), ret); 1317 srs_error("hook client on_publish failed. url=%s, ret=%d", url.c_str(), ret);
1321 return ret; 1318 return ret;
1322 } 1319 }
@@ -1339,10 +1336,9 @@ void SrsRtmpConn::http_hooks_on_unpublish() @@ -1339,10 +1336,9 @@ void SrsRtmpConn::http_hooks_on_unpublish()
1339 return; 1336 return;
1340 } 1337 }
1341 1338
1342 - int connection_id = _srs_context->get_id();  
1343 for (int i = 0; i < (int)on_unpublish->args.size(); i++) { 1339 for (int i = 0; i < (int)on_unpublish->args.size(); i++) {
1344 std::string url = on_unpublish->args.at(i); 1340 std::string url = on_unpublish->args.at(i);
1345 - SrsHttpHooks::on_unpublish(url, connection_id, ip, req); 1341 + SrsHttpHooks::on_unpublish(url, req);
1346 } 1342 }
1347 } 1343 }
1348 #endif 1344 #endif
@@ -1361,10 +1357,9 @@ int SrsRtmpConn::http_hooks_on_play() @@ -1361,10 +1357,9 @@ int SrsRtmpConn::http_hooks_on_play()
1361 return ret; 1357 return ret;
1362 } 1358 }
1363 1359
1364 - int connection_id = _srs_context->get_id();  
1365 for (int i = 0; i < (int)on_play->args.size(); i++) { 1360 for (int i = 0; i < (int)on_play->args.size(); i++) {
1366 std::string url = on_play->args.at(i); 1361 std::string url = on_play->args.at(i);
1367 - if ((ret = SrsHttpHooks::on_play(url, connection_id, ip, req)) != ERROR_SUCCESS) { 1362 + if ((ret = SrsHttpHooks::on_play(url, req)) != ERROR_SUCCESS) {
1368 srs_error("hook client on_play failed. url=%s, ret=%d", url.c_str(), ret); 1363 srs_error("hook client on_play failed. url=%s, ret=%d", url.c_str(), ret);
1369 return ret; 1364 return ret;
1370 } 1365 }
@@ -1387,10 +1382,9 @@ void SrsRtmpConn::http_hooks_on_stop() @@ -1387,10 +1382,9 @@ void SrsRtmpConn::http_hooks_on_stop()
1387 return; 1382 return;
1388 } 1383 }
1389 1384
1390 - int connection_id = _srs_context->get_id();  
1391 for (int i = 0; i < (int)on_stop->args.size(); i++) { 1385 for (int i = 0; i < (int)on_stop->args.size(); i++) {
1392 std::string url = on_stop->args.at(i); 1386 std::string url = on_stop->args.at(i);
1393 - SrsHttpHooks::on_stop(url, connection_id, ip, req); 1387 + SrsHttpHooks::on_stop(url, req);
1394 } 1388 }
1395 } 1389 }
1396 #endif 1390 #endif