正在显示
5 个修改的文件
包含
133 行增加
和
2 行删除
@@ -322,7 +322,20 @@ vhost hooks.callback.srs.com { | @@ -322,7 +322,20 @@ vhost hooks.callback.srs.com { | ||
322 | # support multiple api hooks, format: | 322 | # support multiple api hooks, format: |
323 | # on_stop http://xxx/api0 http://xxx/api1 http://xxx/apiN | 323 | # on_stop http://xxx/api0 http://xxx/api1 http://xxx/apiN |
324 | on_stop http://127.0.0.1:8085/api/v1/sessions http://localhost:8085/api/v1/sessions; | 324 | on_stop http://127.0.0.1:8085/api/v1/sessions http://localhost:8085/api/v1/sessions; |
325 | - # when dvr got an keyframe, call the hook, | 325 | + # when dvr got flv header, call the hook, |
326 | + # the request in the POST data string is a object encode by json: | ||
327 | + # { | ||
328 | + # "action": "on_dvr_reap_flv", | ||
329 | + # "vhost": "video.test.com", "app": "live", | ||
330 | + # "stream": "livestream", | ||
331 | + # "segment": { | ||
332 | + # "cwd": "/usr/local/srs", | ||
333 | + # "path": "./objs/nginx/html/live/livestream.1398315892865.flv", | ||
334 | + # "duration": 1001, "offset":0, | ||
335 | + # "has_keyframe": true, "pts":1398315895958 | ||
336 | + # } | ||
337 | + # } | ||
338 | + # when dvr reap flv file, call the hook, | ||
326 | # the request in the POST data string is a object encode by json: | 339 | # the request in the POST data string is a object encode by json: |
327 | # { | 340 | # { |
328 | # "action": "on_dvr_reap_flv", | 341 | # "action": "on_dvr_reap_flv", |
@@ -804,9 +804,49 @@ void SrsDvrHssPlan::on_unpublish() | @@ -804,9 +804,49 @@ void SrsDvrHssPlan::on_unpublish() | ||
804 | dvr_enabled = false; | 804 | dvr_enabled = false; |
805 | } | 805 | } |
806 | 806 | ||
807 | -int SrsDvrHssPlan::on_meta_data(SrsOnMetaDataPacket* /*metadata*/) | 807 | +int SrsDvrHssPlan::on_meta_data(SrsOnMetaDataPacket* metadata) |
808 | { | 808 | { |
809 | int ret = ERROR_SUCCESS; | 809 | int ret = ERROR_SUCCESS; |
810 | + | ||
811 | + SrsRequest* req = _req; | ||
812 | + | ||
813 | + // new flv file | ||
814 | + std::stringstream path; | ||
815 | + path << _srs_config->get_dvr_path(req->vhost) | ||
816 | + << "/" << req->app << "/" | ||
817 | + << req->stream << ".header.flv"; | ||
818 | + | ||
819 | + SrsFileStream fs; | ||
820 | + if ((ret = fs.open(path.str().c_str())) != ERROR_SUCCESS) { | ||
821 | + return ret; | ||
822 | + } | ||
823 | + | ||
824 | + SrsFlvEncoder enc; | ||
825 | + if ((ret = enc.initialize(&fs)) != ERROR_SUCCESS) { | ||
826 | + return ret; | ||
827 | + } | ||
828 | + | ||
829 | + if ((ret = enc.write_header()) != ERROR_SUCCESS) { | ||
830 | + return ret; | ||
831 | + } | ||
832 | + | ||
833 | + int size = 0; | ||
834 | + char* payload = NULL; | ||
835 | + if ((ret = metadata->encode(size, payload)) != ERROR_SUCCESS) { | ||
836 | + return ret; | ||
837 | + } | ||
838 | + SrsAutoFree(char, payload, true); | ||
839 | + | ||
840 | + if ((ret = enc.write_metadata(payload, size)) != ERROR_SUCCESS) { | ||
841 | + return ret; | ||
842 | + } | ||
843 | + | ||
844 | +#ifdef SRS_AUTO_HTTP_CALLBACK | ||
845 | + if ((ret = on_dvr_reap_flv_header(path.str())) != ERROR_SUCCESS) { | ||
846 | + return ret; | ||
847 | + } | ||
848 | +#endif | ||
849 | + | ||
810 | return ret; | 850 | return ret; |
811 | } | 851 | } |
812 | 852 | ||
@@ -842,6 +882,27 @@ int64_t SrsDvrHssPlan::filter_timestamp(int64_t timestamp) | @@ -842,6 +882,27 @@ int64_t SrsDvrHssPlan::filter_timestamp(int64_t timestamp) | ||
842 | return segment->stream_starttime + timestamp; | 882 | return segment->stream_starttime + timestamp; |
843 | } | 883 | } |
844 | 884 | ||
885 | +int SrsDvrHssPlan::on_dvr_reap_flv_header(string path) | ||
886 | +{ | ||
887 | + int ret = ERROR_SUCCESS; | ||
888 | + | ||
889 | +#ifdef SRS_AUTO_HTTP_CALLBACK | ||
890 | + // HTTP: on_dvr_reap_flv_header | ||
891 | + SrsConfDirective* on_dvr_reap_flv = _srs_config->get_vhost_on_dvr_reap_flv(_req->vhost); | ||
892 | + if (!on_dvr_reap_flv) { | ||
893 | + srs_info("ignore the empty http callback: on_dvr_reap_flv"); | ||
894 | + return ret; | ||
895 | + } | ||
896 | + | ||
897 | + for (int i = 0; i < (int)on_dvr_reap_flv->args.size(); i++) { | ||
898 | + std::string url = on_dvr_reap_flv->args.at(i); | ||
899 | + SrsHttpHooks::on_dvr_reap_flv_header(url, _req, path); | ||
900 | + } | ||
901 | +#endif | ||
902 | + | ||
903 | + return ret; | ||
904 | +} | ||
905 | + | ||
845 | int SrsDvrHssPlan::update_duration(SrsSharedPtrMessage* msg) | 906 | int SrsDvrHssPlan::update_duration(SrsSharedPtrMessage* msg) |
846 | { | 907 | { |
847 | int ret = ERROR_SUCCESS; | 908 | int ret = ERROR_SUCCESS; |
@@ -259,6 +259,7 @@ protected: | @@ -259,6 +259,7 @@ protected: | ||
259 | virtual int on_video_keyframe(); | 259 | virtual int on_video_keyframe(); |
260 | virtual int64_t filter_timestamp(int64_t timestamp); | 260 | virtual int64_t filter_timestamp(int64_t timestamp); |
261 | private: | 261 | private: |
262 | + virtual int on_dvr_reap_flv_header(std::string path); | ||
262 | virtual int update_duration(SrsSharedPtrMessage* msg); | 263 | virtual int update_duration(SrsSharedPtrMessage* msg); |
263 | }; | 264 | }; |
264 | 265 |
@@ -459,6 +459,55 @@ void SrsHttpHooks::on_stop(string url, int client_id, string ip, SrsRequest* req | @@ -459,6 +459,55 @@ void SrsHttpHooks::on_stop(string url, int client_id, string ip, SrsRequest* req | ||
459 | return; | 459 | return; |
460 | } | 460 | } |
461 | 461 | ||
462 | +void SrsHttpHooks::on_dvr_reap_flv_header(std::string url, SrsRequest* req, std::string header_file) | ||
463 | +{ | ||
464 | + int ret = ERROR_SUCCESS; | ||
465 | + | ||
466 | + srs_verbose("flv header reap, file=%s", header_file.c_str()); | ||
467 | + | ||
468 | + SrsHttpUri uri; | ||
469 | + if ((ret = uri.initialize(url)) != ERROR_SUCCESS) { | ||
470 | + srs_warn("http uri parse on_dvr_reap_flv_header url failed, ignored. " | ||
471 | + "url=%s, ret=%d", url.c_str(), ret); | ||
472 | + return; | ||
473 | + } | ||
474 | + | ||
475 | + std::stringstream ss; | ||
476 | + ss << JOBJECT_START | ||
477 | + << JFIELD_STR("action", "on_dvr_reap_flv_header") << JFIELD_CONT | ||
478 | + << JFIELD_STR("vhost", req->vhost) << JFIELD_CONT | ||
479 | + << JFIELD_STR("app", req->app) << JFIELD_CONT | ||
480 | + << JFIELD_STR("stream", req->stream) << JFIELD_CONT | ||
481 | + << JFIELD_NAME("segment") << JOBJECT_START | ||
482 | + << JFIELD_STR("cwd", _srs_config->get_cwd()) << JFIELD_CONT | ||
483 | + << JFIELD_STR("path", header_file) | ||
484 | + << JOBJECT_END | ||
485 | + << JOBJECT_END; | ||
486 | + std::string data = ss.str(); | ||
487 | + std::string res; | ||
488 | + | ||
489 | + SrsHttpClient http; | ||
490 | + if ((ret = http.post(&uri, data, res)) != ERROR_SUCCESS) { | ||
491 | + srs_warn("http post on_dvr_reap_flv_header uri failed, ignored. " | ||
492 | + "url=%s, request=%s, response=%s, ret=%d", | ||
493 | + url.c_str(), data.c_str(), res.c_str(), ret); | ||
494 | + return; | ||
495 | + } | ||
496 | + | ||
497 | + if (res.empty() || res != SRS_HTTP_RESPONSE_OK) { | ||
498 | + ret = ERROR_HTTP_DATA_INVLIAD; | ||
499 | + srs_warn("http hook on_dvr_reap_flv_header validate failed, ignored. " | ||
500 | + "res=%s, ret=%d", res.c_str(), ret); | ||
501 | + return; | ||
502 | + } | ||
503 | + | ||
504 | + srs_info("http hook on_dvr_reap_flv_header success. " | ||
505 | + "url=%s, request=%s, response=%s, ret=%d", | ||
506 | + url.c_str(), data.c_str(), res.c_str(), ret); | ||
507 | + | ||
508 | + return; | ||
509 | +} | ||
510 | + | ||
462 | void SrsHttpHooks::on_dvr_reap_flv(string url, SrsRequest* req, SrsFlvSegment* segment) | 511 | void SrsHttpHooks::on_dvr_reap_flv(string url, SrsRequest* req, SrsFlvSegment* segment) |
463 | { | 512 | { |
464 | int ret = ERROR_SUCCESS; | 513 | int ret = ERROR_SUCCESS; |
@@ -124,6 +124,13 @@ public: | @@ -124,6 +124,13 @@ public: | ||
124 | static void on_stop(std::string url, int client_id, std::string ip, SrsRequest* req); | 124 | static void on_stop(std::string url, int client_id, std::string ip, SrsRequest* req); |
125 | public: | 125 | public: |
126 | /** | 126 | /** |
127 | + * on_dvr_reap_flv_header hook, when dvr write flv file header. | ||
128 | + * @param url the api server url, to process the event. | ||
129 | + * ignore if empty. | ||
130 | + * @param header_file the flv header file. | ||
131 | + */ | ||
132 | + static void on_dvr_reap_flv_header(std::string url, SrsRequest* req, std::string header_file); | ||
133 | + /** | ||
127 | * on_dvr_reap_flv hook, when dvr close flv file. | 134 | * on_dvr_reap_flv hook, when dvr close flv file. |
128 | * @param url the api server url, to process the event. | 135 | * @param url the api server url, to process the event. |
129 | * ignore if empty. | 136 | * ignore if empty. |
-
请 注册 或 登录 后发表评论