From b59d9ba6a1798a7efc701f755d55f81b98bf843c Mon Sep 17 00:00:00 2001 From: winlin Date: Sat, 19 Sep 2015 13:31:57 +0800 Subject: [PATCH] support amf0 and json to convert with each other. --- README.md | 1 + trunk/src/app/srs_app_config.cpp | 8 +-- trunk/src/app/srs_app_http_api.cpp | 4 +- trunk/src/protocol/srs_protocol_json.cpp | 66 +++++++++++++++++- trunk/src/protocol/srs_protocol_json.hpp | 18 ++--- trunk/src/protocol/srs_rtmp_amf0.cpp | 88 ++++++++++++++++++++++++ trunk/src/protocol/srs_rtmp_amf0.hpp | 17 +++++ 7 files changed, 181 insertions(+), 21 deletions(-) diff --git a/README.md b/README.md index 3f52e6211..f4866fe49 100755 --- a/README.md +++ b/README.md @@ -344,6 +344,7 @@ Remark: ## History +* v3.0, 2015-09-19, support amf0 and json to convert with each other. * v3.0, 2015-09-19, json objects support dumps to string. * 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. diff --git a/trunk/src/app/srs_app_config.cpp b/trunk/src/app/srs_app_config.cpp index 274fd8d9e..6b094d10d 100644 --- a/trunk/src/app/srs_app_config.cpp +++ b/trunk/src/app/srs_app_config.cpp @@ -5573,22 +5573,22 @@ vector SrsConfig::get_exec_publishs(string vhost) vector SrsConfig::get_ingesters(string vhost) { - vector ingeters; + vector integers; SrsConfDirective* conf = get_vhost(vhost); if (!conf) { - return ingeters; + return integers; } for (int i = 0; i < (int)conf->directives.size(); i++) { SrsConfDirective* ingester = conf->directives[i]; if (ingester->name == "ingest") { - ingeters.push_back(ingester); + integers.push_back(ingester); } } - return ingeters; + return integers; } SrsConfDirective* SrsConfig::get_ingest_by_id(string vhost, string ingest_id) diff --git a/trunk/src/app/srs_app_http_api.cpp b/trunk/src/app/srs_app_http_api.cpp index f3d5a28b6..b57597c32 100644 --- a/trunk/src/app/srs_app_http_api.cpp +++ b/trunk/src/app/srs_app_http_api.cpp @@ -81,7 +81,7 @@ int srs_api_response_jsonp_code(ISrsHttpResponseWriter* w, string callback, int SrsJsonObject* obj = SrsJsonAny::object(); SrsAutoFree(SrsJsonObject, obj); - obj->set("code", SrsJsonAny::ingeter(code)); + obj->set("code", SrsJsonAny::integer(code)); return srs_api_response_jsonp(w, callback, obj->to_json()); } @@ -101,7 +101,7 @@ int srs_api_response_json_code(ISrsHttpResponseWriter* w, int code) SrsJsonObject* obj = SrsJsonAny::object(); SrsAutoFree(SrsJsonObject, obj); - obj->set("code", SrsJsonAny::ingeter(code)); + obj->set("code", SrsJsonAny::integer(code)); return srs_api_response_json(w, obj->to_json()); } diff --git a/trunk/src/protocol/srs_protocol_json.cpp b/trunk/src/protocol/srs_protocol_json.cpp index 966318cdd..91988d3a8 100644 --- a/trunk/src/protocol/srs_protocol_json.cpp +++ b/trunk/src/protocol/srs_protocol_json.cpp @@ -27,6 +27,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. using namespace std; #include +#include /* json encode cout<< SRS_JOBJECT_START @@ -357,6 +358,40 @@ string SrsJsonAny::to_json() return "null"; } +SrsAmf0Any* SrsJsonAny::to_amf0() +{ + switch (marker) { + case SRS_JSON_String: { + return SrsAmf0Any::str(to_str().c_str()); + } + case SRS_JSON_Boolean: { + return SrsAmf0Any::boolean(to_boolean()); + } + case SRS_JSON_Integer: { + return SrsAmf0Any::number(to_integer()); + } + case SRS_JSON_Number: { + return SrsAmf0Any::number(to_number()); + } + case SRS_JSON_Null: { + return SrsAmf0Any::null(); + } + case SRS_JSON_Object: { + // json object must override this method. + srs_assert(false); + } + case SRS_JSON_Array: { + // json array must override this method. + srs_assert(false); + } + default: { + break; + } + } + + return SrsAmf0Any::null(); +} + SrsJsonAny* SrsJsonAny::str(const char* value) { return new SrsJsonString(value); @@ -367,7 +402,7 @@ SrsJsonAny* SrsJsonAny::boolean(bool value) return new SrsJsonBoolean(value); } -SrsJsonAny* SrsJsonAny::ingeter(int64_t value) +SrsJsonAny* SrsJsonAny::integer(int64_t value) { return new SrsJsonInteger(value); } @@ -405,7 +440,7 @@ SrsJsonAny* srs_json_parse_tree_nx_json(const nx_json* node) case NX_JSON_STRING: return SrsJsonAny::str(node->text_value); case NX_JSON_INTEGER: - return SrsJsonAny::ingeter(node->int_value); + return SrsJsonAny::integer(node->int_value); case NX_JSON_DOUBLE: return SrsJsonAny::number(node->dbl_value); case NX_JSON_BOOL: @@ -513,6 +548,20 @@ string SrsJsonObject::to_json() return ss.str(); } +SrsAmf0Any* SrsJsonObject::to_amf0() +{ + SrsAmf0Object* obj = SrsAmf0Any::object(); + + for (int i = 0; i < (int)properties.size(); i++) { + std::string name = this->key_at(i); + SrsJsonAny* any = this->value_at(i); + + obj->set(name, any->to_amf0()); + } + + return obj; +} + void SrsJsonObject::set(string key, SrsJsonAny* value) { if (!value) { @@ -686,6 +735,19 @@ string SrsJsonArray::to_json() return ss.str(); } +SrsAmf0Any* SrsJsonArray::to_amf0() +{ + SrsAmf0StrictArray* arr = SrsAmf0Any::strict_array(); + + for (int i = 0; i < (int)properties.size(); i++) { + SrsJsonAny* any = properties[i]; + + arr->append(any->to_amf0()); + } + + return arr; +} + #ifdef SRS_JSON_USE_NXJSON //////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/trunk/src/protocol/srs_protocol_json.hpp b/trunk/src/protocol/srs_protocol_json.hpp index 28406347e..667b15387 100644 --- a/trunk/src/protocol/srs_protocol_json.hpp +++ b/trunk/src/protocol/srs_protocol_json.hpp @@ -60,6 +60,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // @see: https://bitbucket.org/yarosla/nxjson // @see: https://github.com/udp/json-parser +class SrsAmf0Any; class SrsJsonArray; class SrsJsonObject; @@ -112,16 +113,13 @@ public: * user must ensure the type is a ecma array, or assert failed. */ virtual SrsJsonArray* to_array(); -// json public: - /** - * convert the amf0 stuff to json. - */ virtual std::string to_json(); + virtual SrsAmf0Any* to_amf0(); public: static SrsJsonAny* str(const char* value = NULL); static SrsJsonAny* boolean(bool value = false); - static SrsJsonAny* ingeter(int64_t value = 0); + static SrsJsonAny* integer(int64_t value = 0); static SrsJsonAny* number(double value = 0.0); static SrsJsonAny* null(); static SrsJsonObject* object(); @@ -151,12 +149,9 @@ public: virtual std::string key_at(int index); // @remark: max index is count(). virtual SrsJsonAny* value_at(int index); -// json public: - /** - * convert the amf0 object to json. - */ virtual std::string to_json(); + virtual SrsAmf0Any* to_amf0(); public: virtual void set(std::string key, SrsJsonAny* value); virtual SrsJsonAny* get_property(std::string name); @@ -185,12 +180,9 @@ public: virtual void add(SrsJsonAny* value); // alias to add. virtual void append(SrsJsonAny* value); -// json public: - /** - * convert the amf0 ecma array to json. - */ virtual std::string to_json(); + virtual SrsAmf0Any* to_amf0(); }; //////////////////////////////////////////////////////////////////////// diff --git a/trunk/src/protocol/srs_rtmp_amf0.cpp b/trunk/src/protocol/srs_rtmp_amf0.cpp index 402521b13..39535f441 100644 --- a/trunk/src/protocol/srs_rtmp_amf0.cpp +++ b/trunk/src/protocol/srs_rtmp_amf0.cpp @@ -282,6 +282,53 @@ char* SrsAmf0Any::human_print(char** pdata, int* psize) return data; } +SrsJsonAny* SrsAmf0Any::to_json() +{ + switch (marker) { + case RTMP_AMF0_String: { + return SrsJsonAny::str(to_str().c_str()); + } + case RTMP_AMF0_Boolean: { + return SrsJsonAny::boolean(to_boolean()); + } + case RTMP_AMF0_Number: { + double dv = to_number(); + int64_t iv = (int64_t)dv; + if (iv == dv) { + return SrsJsonAny::integer(iv); + } else { + return SrsJsonAny::number(dv); + } + } + case RTMP_AMF0_Null: { + return SrsJsonAny::null(); + } + case RTMP_AMF0_Undefined: { + return SrsJsonAny::null(); + } + case RTMP_AMF0_Object: { + // amf0 object implements it. + srs_assert(false); + } + case RTMP_AMF0_EcmaArray: { + // amf0 ecma array implements it. + srs_assert(false); + } + case RTMP_AMF0_StrictArray: { + // amf0 strict array implements it. + srs_assert(false); + } + case RTMP_AMF0_Date: { + // TODO: FIXME: implements it. + return SrsJsonAny::null(); + } + default: { + return SrsJsonAny::null(); + } + } + +} + SrsAmf0Any* SrsAmf0Any::str(const char* value) { return new SrsAmf0String(value); @@ -743,6 +790,20 @@ SrsAmf0Any* SrsAmf0Object::copy() return copy; } +SrsJsonAny* SrsAmf0Object::to_json() +{ + SrsJsonObject* obj = SrsJsonAny::object(); + + for (int i = 0; i < properties->count(); i++) { + std::string name = this->key_at(i); + SrsAmf0Any* any = this->value_at(i); + + obj->set(name, any->to_json()); + } + + return obj; +} + void SrsAmf0Object::clear() { properties->clear(); @@ -944,6 +1005,20 @@ SrsAmf0Any* SrsAmf0EcmaArray::copy() return copy; } +SrsJsonAny* SrsAmf0EcmaArray::to_json() +{ + SrsJsonObject* obj = SrsJsonAny::object(); + + for (int i = 0; i < properties->count(); i++) { + std::string name = this->key_at(i); + SrsAmf0Any* any = this->value_at(i); + + obj->set(name, any->to_json()); + } + + return obj; +} + void SrsAmf0EcmaArray::clear() { properties->clear(); @@ -1119,6 +1194,19 @@ SrsAmf0Any* SrsAmf0StrictArray::copy() return copy; } +SrsJsonAny* SrsAmf0StrictArray::to_json() +{ + SrsJsonArray* arr = SrsJsonAny::array(); + + for (int i = 0; i < (int)properties.size(); i++) { + SrsAmf0Any* any = properties[i]; + + arr->append(any->to_json()); + } + + return arr; +} + void SrsAmf0StrictArray::clear() { properties.clear(); diff --git a/trunk/src/protocol/srs_rtmp_amf0.hpp b/trunk/src/protocol/srs_rtmp_amf0.hpp index 6b697c9ac..6c53d91b4 100644 --- a/trunk/src/protocol/srs_rtmp_amf0.hpp +++ b/trunk/src/protocol/srs_rtmp_amf0.hpp @@ -37,6 +37,7 @@ class SrsStream; class SrsAmf0Object; class SrsAmf0EcmaArray; class SrsAmf0StrictArray; +class SrsJsonAny; // internal objects, user should never use it. namespace _srs_internal @@ -272,6 +273,10 @@ public: * @remark user must free the data returned or output by pdata. */ virtual char* human_print(char** pdata, int* psize); + /** + * convert amf0 to json. + */ + virtual SrsJsonAny* to_json(); // create AMF0 instance. public: /** @@ -351,6 +356,10 @@ public: virtual int read(SrsStream* stream); virtual int write(SrsStream* stream); virtual SrsAmf0Any* copy(); + /** + * convert amf0 to json. + */ + virtual SrsJsonAny* to_json(); // properties iteration public: /** @@ -434,6 +443,10 @@ public: virtual int read(SrsStream* stream); virtual int write(SrsStream* stream); virtual SrsAmf0Any* copy(); + /** + * convert amf0 to json. + */ + virtual SrsJsonAny* to_json(); // properties iteration public: /** @@ -515,6 +528,10 @@ public: virtual int read(SrsStream* stream); virtual int write(SrsStream* stream); virtual SrsAmf0Any* copy(); + /** + * convert amf0 to json. + */ + virtual SrsJsonAny* to_json(); // properties iteration public: /**