diff --git a/README.md b/README.md index 5ab538f06a..3f2c35ca32 100755 --- a/README.md +++ b/README.md @@ -344,6 +344,7 @@ Remark: ## History +* v3.0, 2015-09-14, fix [#459][bug #459], support dvr raw api. 3.0.4 * v3.0, 2015-09-14, fix [#459][bug #459], dvr support apply filter for ng-control dvr module. * v3.0, 2015-09-14, fix [#319][bug #319], http raw api support update global and vhost. 3.0.3 * v3.0, 2015-08-31, fix [#319][bug #319], http raw api support query global and vhost. diff --git a/trunk/src/app/srs_app_config.cpp b/trunk/src/app/srs_app_config.cpp index 7ac8063d18..bb22f699ed 100644 --- a/trunk/src/app/srs_app_config.cpp +++ b/trunk/src/app/srs_app_config.cpp @@ -850,15 +850,8 @@ int SrsConfig::reload_vhost(SrsConfDirective* old_root) // @see https://github.com/simple-rtmp-server/srs/issues/459#issuecomment-140296597 SrsConfDirective* nda = new_vhost->get("dvr")? new_vhost->get("dvr")->get("dvr_apply") : NULL; SrsConfDirective* oda = old_vhost->get("dvr")? old_vhost->get("dvr")->get("dvr_apply") : NULL; - if (!srs_directive_equals(nda, oda)) { - for (it = subscribes.begin(); it != subscribes.end(); ++it) { - ISrsReloadHandler* subscribe = *it; - if ((ret = subscribe->on_reload_vhost_dvr_apply(vhost)) != ERROR_SUCCESS) { - srs_error("vhost %s notify subscribes dvr_apply failed. ret=%d", vhost.c_str(), ret); - return ret; - } - } - srs_trace("vhost %s reload dvr_apply success.", vhost.c_str()); + if (!srs_directive_equals(nda, oda) && (ret = do_reload_vhost_dvr_apply(vhost)) != ERROR_SUCCESS) { + return ret; } } @@ -2563,6 +2556,60 @@ int SrsConfig::raw_enable_vhost(string vhost, bool& applied) return ret; } +int SrsConfig::raw_enable_dvr(string vhost, string stream, bool& applied) +{ + int ret = ERROR_SUCCESS; + + applied = false; + + SrsConfDirective* conf = root->get("vhost", vhost); + conf = conf->get_or_create("dvr")->get_or_create("dvr_apply"); + + if (conf->args.size() == 1 && (conf->arg0() == "all" || conf->arg0() == "none")) { + conf->args.clear(); + } + + if (::find(conf->args.begin(), conf->args.end(), stream) == conf->args.end()) { + conf->args.push_back(stream); + } + + if ((ret = do_reload_vhost_dvr_apply(vhost)) != ERROR_SUCCESS) { + return ret; + } + + applied = true; + + return ret; +} + +int SrsConfig::raw_disable_dvr(string vhost, string stream, bool& applied) +{ + int ret = ERROR_SUCCESS; + + applied = false; + + SrsConfDirective* conf = root->get("vhost", vhost); + conf = conf->get_or_create("dvr")->get_or_create("dvr_apply"); + + std::vector::iterator it; + + if ((it = ::find(conf->args.begin(), conf->args.end(), stream)) != conf->args.end()) { + conf->args.erase(it); + } + + if (conf->args.empty()) { + conf->args.push_back("none"); + } + + if ((ret = do_reload_vhost_dvr_apply(vhost)) != ERROR_SUCCESS) { + return ret; + } + + applied = true; + + return ret; +} + int SrsConfig::do_reload_listen() { int ret = ERROR_SUCCESS; @@ -2739,6 +2786,23 @@ int SrsConfig::do_reload_vhost_removed(string vhost) return ret; } +int SrsConfig::do_reload_vhost_dvr_apply(string vhost) +{ + int ret = ERROR_SUCCESS; + + vector::iterator it; + for (it = subscribes.begin(); it != subscribes.end(); ++it) { + ISrsReloadHandler* subscribe = *it; + if ((ret = subscribe->on_reload_vhost_dvr_apply(vhost)) != ERROR_SUCCESS) { + srs_error("vhost %s notify subscribes dvr_apply failed. ret=%d", vhost.c_str(), ret); + return ret; + } + } + srs_trace("vhost %s reload dvr_apply success.", vhost.c_str()); + + return ret; +} + string SrsConfig::config() { return config_file; diff --git a/trunk/src/app/srs_app_config.hpp b/trunk/src/app/srs_app_config.hpp index d52d797c29..e05c770fa1 100644 --- a/trunk/src/app/srs_app_config.hpp +++ b/trunk/src/app/srs_app_config.hpp @@ -399,6 +399,14 @@ class SrsConfig * raw enable the disabled vhost. */ virtual int raw_enable_vhost(std::string vhost, bool& applied); + /** + * raw enable the dvr of stream of vhost. + */ + virtual int raw_enable_dvr(std::string vhost, std::string stream, bool& applied); + /** + * raw disable the dvr of stream of vhost. + */ + virtual int raw_disable_dvr(std::string vhost, std::string stream, bool& applied); private: virtual int do_reload_listen(); virtual int do_reload_pid(); @@ -410,6 +418,7 @@ class SrsConfig virtual int do_reload_pithy_print_ms(); virtual int do_reload_vhost_added(std::string vhost); virtual int do_reload_vhost_removed(std::string vhost); + virtual int do_reload_vhost_dvr_apply(std::string vhost); public: /** * get the config file path. diff --git a/trunk/src/app/srs_app_http_api.cpp b/trunk/src/app/srs_app_http_api.cpp index 74bc77840d..1330091352 100755 --- a/trunk/src/app/srs_app_http_api.cpp +++ b/trunk/src/app/srs_app_http_api.cpp @@ -1002,6 +1002,10 @@ int SrsGoApiRaw::serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r) // @scope @value @param @data description // vhost ossrs.net create - create vhost ossrs.net // vhost ossrs.net update new.ossrs.net the new name to update vhost + // dvr specified updates: + // @scope @value @param @data description + // dvr ossrs.net enable live/livestream enable the dvr of stream + // dvr ossrs.net disable live/livestream disable the dvr of stream if (rpc == "update") { if (!allow_update) { ret = ERROR_SYSTEM_CONFIG_RAW_DISABLED; @@ -1019,7 +1023,7 @@ int SrsGoApiRaw::serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r) if (scope != "listen" && scope != "pid" && scope != "chunk_size" && scope != "ff_log_dir" && scope != "srs_log_tank" && scope != "srs_log_level" && scope != "srs_log_file" && scope != "max_connections" && scope != "utc_time" - && scope != "pithy_print_ms" && scope != "vhost" + && scope != "pithy_print_ms" && scope != "vhost" && scope != "dvr" ) { ret = ERROR_SYSTEM_CONFIG_RAW_NOT_ALLOWED; srs_error("raw api query invalid scope=%s. ret=%d", scope.c_str(), ret); @@ -1231,6 +1235,34 @@ int SrsGoApiRaw::serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r) } else { // TODO: support other param. } + } else if (scope == "dvr") { + std::string action = r->query_get("param"); + std::string stream = r->query_get("data"); + extra += "/" + stream + " to " + action; + + if (action != "enable" && action != "disable") { + ret = ERROR_SYSTEM_CONFIG_RAW_NOT_ALLOWED; + srs_error("raw api query invalid scope=%s, param=%s. ret=%d", scope.c_str(), action.c_str(), ret); + return srs_api_response_code(w, r, ret); + } + + if (!_srs_config->get_dvr_enabled(value)) { + ret = ERROR_SYSTEM_CONFIG_RAW_NOT_ALLOWED; + srs_error("raw api query invalid scope=%s, value=%s, param=%s. ret=%d", scope.c_str(), value.c_str(), action.c_str(), ret); + return srs_api_response_code(w, r, ret); + } + + if (action == "enable") { + if ((ret = _srs_config->raw_enable_dvr(value, stream, applied)) != ERROR_SUCCESS) { + srs_error("raw api update dvr=%s/%s, param=%s failed. ret=%d", value.c_str(), stream.c_str(), action.c_str(), ret); + return srs_api_response_code(w, r, ret); + } + } else { + if ((ret = _srs_config->raw_disable_dvr(value, stream, applied)) != ERROR_SUCCESS) { + srs_error("raw api update dvr=%s/%s, param=%s failed. ret=%d", value.c_str(), stream.c_str(), action.c_str(), ret); + return srs_api_response_code(w, r, ret); + } + } } else { // TODO: support other scope. } diff --git a/trunk/src/core/srs_core.hpp b/trunk/src/core/srs_core.hpp index 5efc3f734a..4cb9bf54d6 100644 --- a/trunk/src/core/srs_core.hpp +++ b/trunk/src/core/srs_core.hpp @@ -31,7 +31,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // current release version #define VERSION_MAJOR 3 #define VERSION_MINOR 0 -#define VERSION_REVISION 3 +#define VERSION_REVISION 4 // server info. #define RTMP_SIG_SRS_KEY "SRS"