正在显示
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. |
-
请 注册 或 登录 后发表评论