Skip to content

Commit

Permalink
for ossrs#179, dvr suport vhost/app/stream level control. 2.0.125.
Browse files Browse the repository at this point in the history
  • Loading branch information
winlinvip committed Feb 25, 2015
1 parent 1cb8e44 commit b903a7b
Show file tree
Hide file tree
Showing 7 changed files with 72 additions and 15 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -532,6 +532,7 @@ Supported operating systems and hardware:

### SRS 2.0 history

* v2.0, 2015-02-24, for [#179](https://github.com/winlinvip/simple-rtmp-server/issues/179), dvr suport vhost/app/stream level control. 2.0.125.
* v2.0, 2015-02-24, for [#304](https://github.com/winlinvip/simple-rtmp-server/issues/304), fix hls bug, write pts/dts error. 2.0.124.
* v2.0, 2015-02-24, fix [#179](https://github.com/winlinvip/simple-rtmp-server/issues/179), support dvr http api. 2.0.123.
* v2.0, 2015-02-19, refine dvr, append file when dvr file exists. 2.0.122.
Expand Down
18 changes: 13 additions & 5 deletions trunk/conf/full.conf
Original file line number Diff line number Diff line change
Expand Up @@ -293,19 +293,24 @@ vhost dvr.srs.com {
# http url to control dvr, for example, http://dev:1985/api/v1/dvrs
# method=GET
# to query dvrs of server.
# request params, for example ?vhost=__defaultVhost__, where:
# vhost, query all dvr of this vhost.
# request params, for example ?vhost=__defaultVhost__&&app=live&&stream=livestream, where:
# vhost, <required>, query all dvr of this vhost.
# app, [optinal], query all dvr of this app. query all app if not specified.
# stream, [optional], query specified dvr stream. query all stream if not specified.
# response in json, where:
# {code:0, dvrs: [{path_tmpl:"./[15].[04].[05].[999].flv", path_dvr:"./22.7.43.312.flv",
# wait_keyframe:true, vhost:"__defaultVhost", callback:"http://127.0.0.1:8085/api/v1/dvrs",
# vhost:"__defaultVhost", app:"live", stream:"livestream",
# wait_keyframe:true, callback:"http://127.0.0.1:8085/api/v1/dvrs",
# status:"stop"|"start"
# }]}
# method=POST
# to start dvr of specified vhost.
# request should encode in json, specifies the dvr to create, where:
# {path_tmpl:"./[15].[04].[05].[999].flv",
# wait_keyframe:true, vhost:"__defaultVhost", callback:"http://127.0.0.1:8085/api/v1/dvrs"
# vhost:"__defaultVhost", app:"live", stream:"livestream",
# wait_keyframe:true, callback:"http://127.0.0.1:8085/api/v1/dvrs"
# }
# @remark, the app and stream is optional.
# response in json, where:
# {code:0}
# method=DELETE, to stop dvr
Expand All @@ -316,7 +321,10 @@ vhost dvr.srs.com {
# {code:0}
# method=PUT, use as RPC(remote process call).
# reap_segment, the request params in json, where:
# {action:"reap_segment", vhost:"__defaultVhost", path_tmpl:"./[15].[04].[05].[999].flv"}
# {action:"reap_segment", vhost:"__defaultVhost", app:"live", stream:"livestream",
# path_tmpl:"./[15].[04].[05].[999].flv"
# }
# @remark, the app and stream is optional.
# when reap segment, the callback POST request in json:
# {action:"on_dvr_reap_segment", client_id:100, vhost:"__defaultVhost__",
# app:"live", stream:"livestream", cwd:"/home/winlin/srs", file:"./dvr.flv"
Expand Down
57 changes: 52 additions & 5 deletions trunk/src/app/srs_app_dvr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1078,6 +1078,8 @@ int SrsDvrApiPlan::dumps(stringstream& ss)
<< __SRS_JFIELD_STR("path_dvr", segment->get_path()) << __SRS_JFIELD_CONT
<< __SRS_JFIELD_BOOL("wait_keyframe", wait_keyframe) << __SRS_JFIELD_CONT
<< __SRS_JFIELD_STR("vhost", req->vhost) << __SRS_JFIELD_CONT
<< __SRS_JFIELD_STR("app", req->app) << __SRS_JFIELD_CONT
<< __SRS_JFIELD_STR("stream", req->stream) << __SRS_JFIELD_CONT
<< __SRS_JFIELD_STR("callback", callback) << __SRS_JFIELD_CONT
<< __SRS_JFIELD_STR("status", (dvr_enabled? "start":"stop"))
<< __SRS_JOBJECT_END;
Expand Down Expand Up @@ -1482,7 +1484,7 @@ int SrsApiDvrPool::add_dvr(SrsDvrApiPlan* dvr)
return ERROR_SUCCESS;
}

int SrsApiDvrPool::dumps(string vhost, stringstream& ss)
int SrsApiDvrPool::dumps(string vhost, string app, string stream, stringstream& ss)
{
int ret = ERROR_SUCCESS;

Expand All @@ -1494,6 +1496,12 @@ int SrsApiDvrPool::dumps(string vhost, stringstream& ss)
if (!vhost.empty() && plan->req->vhost != vhost) {
continue;
}
if (!app.empty() && plan->req->app != app) {
continue;
}
if (!stream.empty() && plan->req->stream != stream) {
continue;
}
plans.push_back(plan);
}

Expand All @@ -1504,7 +1512,7 @@ int SrsApiDvrPool::dumps(string vhost, stringstream& ss)
return ret;
}

if (i < (int)dvrs.size() - 1) {
if (i < (int)plans.size() - 1) {
ss << __SRS_JFIELD_CONT;
}
}
Expand Down Expand Up @@ -1534,19 +1542,33 @@ int SrsApiDvrPool::create(SrsJsonAny* json)
}

std::string vhost = prop->to_str();
std::string app, stream;
if ((prop = obj->ensure_property_string("app")) != NULL) {
app = prop->to_str();
}
if ((prop = obj->ensure_property_string("stream")) != NULL) {
stream = prop->to_str();
}

SrsDvrApiPlan* dvr = NULL;
for (int i = 0; i < (int)dvrs.size(); i++) {
SrsDvrApiPlan* plan = dvrs.at(i);
if (!vhost.empty() && plan->req->vhost != vhost) {
continue;
}
if (!app.empty() && plan->req->app != app) {
continue;
}
if (!stream.empty() && plan->req->stream != stream) {
continue;
}
dvr = plan;
break;
}

if (!dvr) {
ret = ERROR_HTTP_DVR_CREATE_REQUEST;
srs_error("dvr: api create dvr request vhost invalid. vhost=%s. ret=%d", vhost.c_str(), ret);
ret = ERROR_HTTP_DVR_NO_TAEGET;
srs_error("dvr: create not found for url=%s/%s/%s, ret=%d", vhost.c_str(), app.c_str(), stream.c_str(), ret);
return ret;
}

Expand All @@ -1570,7 +1592,7 @@ int SrsApiDvrPool::create(SrsJsonAny* json)
return dvr->start();
}

int SrsApiDvrPool::stop(string vhost)
int SrsApiDvrPool::stop(string vhost, string app, string stream)
{
int ret = ERROR_SUCCESS;

Expand All @@ -1580,9 +1602,21 @@ int SrsApiDvrPool::stop(string vhost)
if (!vhost.empty() && plan->req->vhost != vhost) {
continue;
}
if (!app.empty() && plan->req->app != app) {
continue;
}
if (!stream.empty() && plan->req->stream != stream) {
continue;
}
plans.push_back(plan);
}

if (plans.empty()) {
ret = ERROR_HTTP_DVR_NO_TAEGET;
srs_error("dvr: stop not found for url=%s/%s/%s, ret=%d", vhost.c_str(), app.c_str(), stream.c_str(), ret);
return ret;
}

for (int i = 0; i < (int)plans.size(); i++) {
SrsDvrApiPlan* plan = plans.at(i);

Expand Down Expand Up @@ -1613,6 +1647,13 @@ int SrsApiDvrPool::rpc(SrsJsonAny* json)
return ret;
}
std::string vhost = prop->to_str();
std::string app, stream;
if ((prop = obj->ensure_property_string("app")) != NULL) {
app = prop->to_str();
}
if ((prop = obj->ensure_property_string("stream")) != NULL) {
stream = prop->to_str();
}

std::vector<SrsDvrApiPlan*> plans;
for (int i = 0; i < (int)dvrs.size(); i++) {
Expand All @@ -1623,6 +1664,12 @@ int SrsApiDvrPool::rpc(SrsJsonAny* json)
plans.push_back(plan);
}

if (plans.empty()) {
ret = ERROR_HTTP_DVR_NO_TAEGET;
srs_error("dvr: rpc not found for url=%s/%s/%s, ret=%d", vhost.c_str(), app.c_str(), stream.c_str(), ret);
return ret;
}

for (int i = 0; i < (int)plans.size(); i++) {
SrsDvrApiPlan* plan = plans.at(i);

Expand Down
4 changes: 2 additions & 2 deletions trunk/src/app/srs_app_dvr.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -394,9 +394,9 @@ class SrsApiDvrPool
public:
virtual int add_dvr(SrsDvrApiPlan* dvr);
public:
virtual int dumps(std::string vhost, std::stringstream& ss);
virtual int dumps(std::string vhost, std::string app, std::string stream, std::stringstream& ss);
virtual int create(SrsJsonAny* json);
virtual int stop(std::string vhost);
virtual int stop(std::string vhost, std::string app, std::string stream);
virtual int rpc(SrsJsonAny* json);
};

Expand Down
4 changes: 2 additions & 2 deletions trunk/src/app/srs_app_http_api.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -494,7 +494,7 @@ int SrsGoApiDvrs::serve_http(ISrsGoHttpResponseWriter* w, SrsHttpMessage* r)
SrsApiDvrPool* pool = SrsApiDvrPool::instance();
if (r->is_http_get()) {
std::stringstream data;
int ret = pool->dumps(r->query_get("vhost"), data);
int ret = pool->dumps(r->query_get("vhost"), r->query_get("app"), r->query_get("stream"), data);

ss << __SRS_JOBJECT_START
<< __SRS_JFIELD_ERROR(ret) << __SRS_JFIELD_CONT
Expand All @@ -514,7 +514,7 @@ int SrsGoApiDvrs::serve_http(ISrsGoHttpResponseWriter* w, SrsHttpMessage* r)
<< __SRS_JFIELD_ERROR(ret)
<< __SRS_JOBJECT_END;
} else if (r->is_http_delete()) {
int ret = pool->stop(r->query_get("vhost"));
int ret = pool->stop(r->query_get("vhost"), r->query_get("app"), r->query_get("stream"));

ss << __SRS_JOBJECT_START
<< __SRS_JFIELD_ERROR(ret)
Expand Down
2 changes: 1 addition & 1 deletion trunk/src/core/srs_core.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
// current release version
#define VERSION_MAJOR 2
#define VERSION_MINOR 0
#define VERSION_REVISION 124
#define VERSION_REVISION 125

// server info.
#define RTMP_SIG_SRS_KEY "SRS"
Expand Down
1 change: 1 addition & 0 deletions trunk/src/kernel/srs_kernel_error.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#define ERROR_HTTP_DVR_REQUEST 3051
#define ERROR_HTTP_JSON_REQUIRED 3052
#define ERROR_HTTP_DVR_CREATE_REQUEST 3053
#define ERROR_HTTP_DVR_NO_TAEGET 3054

///////////////////////////////////////////////////////
// HTTP/StreamCaster protocol error.
Expand Down

0 comments on commit b903a7b

Please sign in to comment.