srs_amf0_t srs_amf0_ecma_array_property_value_at(srs_amf0_t amf0, int index) { SrsAmf0Any* any = (SrsAmf0Any*)amf0; srs_assert(any->is_ecma_array()); SrsAmf0EcmaArray* obj = (SrsAmf0EcmaArray*)amf0; return (srs_amf0_t)obj->value_at(index); }
srs_amf0_t srs_amf0_ecma_array_property(srs_amf0_t amf0, const char* name) { SrsAmf0Any* any = (SrsAmf0Any*)amf0; srs_assert(any->is_ecma_array()); SrsAmf0EcmaArray* obj = (SrsAmf0EcmaArray*)amf0; return (srs_amf0_t)obj->get_property(name); }
int srs_amf0_ecma_array_property_count(srs_amf0_t amf0) { SrsAmf0Any* any = (SrsAmf0Any*)amf0; srs_assert(any->is_ecma_array()); SrsAmf0EcmaArray * obj = (SrsAmf0EcmaArray*)amf0; return obj->count(); }
const char* srs_amf0_ecma_array_property_name_at(srs_amf0_t amf0, int index) { SrsAmf0Any* any = (SrsAmf0Any*)amf0; srs_assert(any->is_ecma_array()); SrsAmf0EcmaArray* obj = (SrsAmf0EcmaArray*)amf0; return obj->key_raw_at(index); }
void srs_amf0_ecma_array_property_set(srs_amf0_t amf0, const char* name, srs_amf0_t value) { SrsAmf0Any* any = (SrsAmf0Any*)amf0; srs_assert(any->is_ecma_array()); SrsAmf0EcmaArray* obj = (SrsAmf0EcmaArray*)amf0; any = (SrsAmf0Any*)value; obj->set(name, any); }
void srs_amf0_do_print(SrsAmf0Any* any, stringstream& ss, int level) { if (any->is_boolean()) { ss << "Boolean " << (any->to_boolean()? "true":"false") << endl; } else if (any->is_number()) { ss << "Number " << std::fixed << any->to_number() << endl; } else if (any->is_string()) { ss << "String " << any->to_str() << endl; } else if (any->is_date()) { ss << "Date " << std::hex << any->to_date() << "/" << std::hex << any->to_date_time_zone() << endl; } else if (any->is_null()) { ss << "Null" << endl; } else if (any->is_ecma_array()) { SrsAmf0EcmaArray* obj = any->to_ecma_array(); ss << "EcmaArray " << "(" << obj->count() << " items)" << endl; for (int i = 0; i < obj->count(); i++) { srs_fill_level_spaces(ss, level + 1); ss << "Elem '" << obj->key_at(i) << "' "; if (obj->value_at(i)->is_complex_object()) { srs_amf0_do_print(obj->value_at(i), ss, level + 1); } else { srs_amf0_do_print(obj->value_at(i), ss, 0); } } } else if (any->is_strict_array()) { SrsAmf0StrictArray* obj = any->to_strict_array(); ss << "StrictArray " << "(" << obj->count() << " items)" << endl; for (int i = 0; i < obj->count(); i++) { srs_fill_level_spaces(ss, level + 1); ss << "Elem "; if (obj->at(i)->is_complex_object()) { srs_amf0_do_print(obj->at(i), ss, level + 1); } else { srs_amf0_do_print(obj->at(i), ss, 0); } } } else if (any->is_object()) { SrsAmf0Object* obj = any->to_object(); ss << "Object " << "(" << obj->count() << " items)" << endl; for (int i = 0; i < obj->count(); i++) { srs_fill_level_spaces(ss, level + 1); ss << "Property '" << obj->key_at(i) << "' "; if (obj->value_at(i)->is_complex_object()) { srs_amf0_do_print(obj->value_at(i), ss, level + 1); } else { srs_amf0_do_print(obj->value_at(i), ss, 0); } } } else { ss << "Unknown" << endl; } }
int SrsRtmpServer::response_connect_app(SrsRequest *req, const char* server_ip) { int ret = ERROR_SUCCESS; SrsConnectAppResPacket* pkt = new SrsConnectAppResPacket(); pkt->props->set("fmsVer", SrsAmf0Any::str("FMS/"RTMP_SIG_FMS_VER)); pkt->props->set("capabilities", SrsAmf0Any::number(127)); pkt->props->set("mode", SrsAmf0Any::number(1)); pkt->info->set(StatusLevel, SrsAmf0Any::str(StatusLevelStatus)); pkt->info->set(StatusCode, SrsAmf0Any::str(StatusCodeConnectSuccess)); pkt->info->set(StatusDescription, SrsAmf0Any::str("Connection succeeded")); pkt->info->set("objectEncoding", SrsAmf0Any::number(req->objectEncoding)); SrsAmf0EcmaArray* data = SrsAmf0Any::ecma_array(); pkt->info->set("data", data); data->set("version", SrsAmf0Any::str(RTMP_SIG_FMS_VER)); data->set("srs_sig", SrsAmf0Any::str(RTMP_SIG_SRS_KEY)); data->set("srs_server", SrsAmf0Any::str(RTMP_SIG_SRS_KEY" "RTMP_SIG_SRS_VERSION" ("RTMP_SIG_SRS_URL_SHORT")")); data->set("srs_license", SrsAmf0Any::str(RTMP_SIG_SRS_LICENSE)); data->set("srs_role", SrsAmf0Any::str(RTMP_SIG_SRS_ROLE)); data->set("srs_url", SrsAmf0Any::str(RTMP_SIG_SRS_URL)); data->set("srs_version", SrsAmf0Any::str(RTMP_SIG_SRS_VERSION)); data->set("srs_site", SrsAmf0Any::str(RTMP_SIG_SRS_WEB)); data->set("srs_email", SrsAmf0Any::str(RTMP_SIG_SRS_EMAIL)); data->set("srs_copyright", SrsAmf0Any::str(RTMP_SIG_SRS_COPYRIGHT)); data->set("srs_primary_authors", SrsAmf0Any::str(RTMP_SIG_SRS_PRIMARY_AUTHROS)); if (server_ip) { data->set("srs_server_ip", SrsAmf0Any::str(server_ip)); } // for edge to directly get the id of client. data->set("srs_pid", SrsAmf0Any::number(getpid())); data->set("srs_id", SrsAmf0Any::number(_srs_context->get_id())); if ((ret = protocol->send_and_free_packet(pkt, 0)) != ERROR_SUCCESS) { srs_error("send connect app response message failed. ret=%d", ret); return ret; } srs_info("send connect app response message success."); return ret; }
int SrsRtmpClient::connect_app2( string app, string tc_url, SrsRequest* req, bool debug_srs_upnode, string& srs_server_ip, string& srs_server, string& srs_primary_authors, string& srs_version, int& srs_id, int& srs_pid ){ int ret = ERROR_SUCCESS; // Connect(vhost, app) if (true) { SrsConnectAppPacket* pkt = new SrsConnectAppPacket(); pkt->command_object->set("app", SrsAmf0Any::str(app.c_str())); pkt->command_object->set("flashVer", SrsAmf0Any::str("WIN 12,0,0,41")); if (req) { pkt->command_object->set("swfUrl", SrsAmf0Any::str(req->swfUrl.c_str())); } else { pkt->command_object->set("swfUrl", SrsAmf0Any::str()); } pkt->command_object->set("tcUrl", SrsAmf0Any::str(tc_url.c_str())); pkt->command_object->set("fpad", SrsAmf0Any::boolean(false)); pkt->command_object->set("capabilities", SrsAmf0Any::number(239)); pkt->command_object->set("audioCodecs", SrsAmf0Any::number(3575)); pkt->command_object->set("videoCodecs", SrsAmf0Any::number(252)); pkt->command_object->set("videoFunction", SrsAmf0Any::number(1)); if (req) { pkt->command_object->set("pageUrl", SrsAmf0Any::str(req->pageUrl.c_str())); } else { pkt->command_object->set("pageUrl", SrsAmf0Any::str()); } pkt->command_object->set("objectEncoding", SrsAmf0Any::number(0)); // @see https://github.com/winlinvip/simple-rtmp-server/issues/160 // the debug_srs_upnode is config in vhost and default to true. if (debug_srs_upnode && req && req->args) { srs_freep(pkt->args); pkt->args = req->args->copy()->to_object(); } if ((ret = protocol->send_and_free_packet(pkt, 0)) != ERROR_SUCCESS) { return ret; } } // Set Window Acknowledgement size(2500000) if (true) { SrsSetWindowAckSizePacket* pkt = new SrsSetWindowAckSizePacket(); pkt->ackowledgement_window_size = 2500000; if ((ret = protocol->send_and_free_packet(pkt, 0)) != ERROR_SUCCESS) { return ret; } } // expect connect _result SrsMessage* msg = NULL; SrsConnectAppResPacket* pkt = NULL; if ((ret = expect_message<SrsConnectAppResPacket>(&msg, &pkt)) != ERROR_SUCCESS) { srs_error("expect connect app response message failed. ret=%d", ret); return ret; } SrsAutoFree(SrsMessage, msg); SrsAutoFree(SrsConnectAppResPacket, pkt); // server info SrsAmf0Any* data = pkt->info->get_property("data"); if (data && data->is_ecma_array()) { SrsAmf0EcmaArray* arr = data->to_ecma_array(); SrsAmf0Any* prop = NULL; if ((prop = arr->ensure_property_string("srs_primary_authors")) != NULL) { srs_primary_authors = prop->to_str(); } if ((prop = arr->ensure_property_string("srs_version")) != NULL) { srs_version = prop->to_str(); } if ((prop = arr->ensure_property_string("srs_server_ip")) != NULL) { srs_server_ip = prop->to_str(); } if ((prop = arr->ensure_property_string("srs_server")) != NULL) { srs_server = prop->to_str(); } if ((prop = arr->ensure_property_number("srs_id")) != NULL) { srs_id = (int)prop->to_number(); } if ((prop = arr->ensure_property_number("srs_pid")) != NULL) { srs_pid = (int)prop->to_number(); } } srs_trace("connected, version=%s, ip=%s, pid=%d, id=%d, dsu=%d", srs_version.c_str(), srs_server_ip.c_str(), srs_pid, srs_id, debug_srs_upnode); return ret; }
VOID TEST(AMF0Test, ApiEcmaArrayProps) { SrsAmf0EcmaArray* o = NULL; // get/set property if (true) { o = SrsAmf0Any::ecma_array(); SrsAutoFree(SrsAmf0EcmaArray, o); EXPECT_TRUE(NULL == o->get_property("name")); o->set("name", SrsAmf0Any::str("winlin")); EXPECT_TRUE(NULL != o->get_property("name")); EXPECT_TRUE(NULL == o->get_property("age")); o->set("age", SrsAmf0Any::number(100)); EXPECT_TRUE(NULL != o->get_property("age")); } // index property if (true) { o = SrsAmf0Any::ecma_array(); SrsAutoFree(SrsAmf0EcmaArray, o); o->set("name", SrsAmf0Any::str("winlin")); EXPECT_STREQ("name", o->key_at(0).c_str()); ASSERT_TRUE(o->value_at(0)->is_string()); EXPECT_STREQ("winlin", o->value_at(0)->to_str().c_str()); o->set("age", SrsAmf0Any::number(100)); EXPECT_STREQ("name", o->key_at(0).c_str()); ASSERT_TRUE(o->value_at(0)->is_string()); EXPECT_STREQ("winlin", o->value_at(0)->to_str().c_str()); EXPECT_STREQ("age", o->key_at(1).c_str()); ASSERT_TRUE(o->value_at(1)->is_number()); EXPECT_DOUBLE_EQ(100, o->value_at(1)->to_number()); } // ensure property if (true) { o = SrsAmf0Any::ecma_array(); SrsAutoFree(SrsAmf0EcmaArray, o); EXPECT_TRUE(NULL == o->ensure_property_string("name")); EXPECT_TRUE(NULL == o->ensure_property_number("age")); o->set("name", SrsAmf0Any::str("winlin")); EXPECT_TRUE(NULL != o->ensure_property_string("name")); EXPECT_TRUE(NULL == o->ensure_property_number("name")); EXPECT_TRUE(NULL == o->ensure_property_number("age")); o->set("age", SrsAmf0Any::number(100)); EXPECT_TRUE(NULL != o->ensure_property_string("name")); EXPECT_TRUE(NULL == o->ensure_property_number("name")); EXPECT_TRUE(NULL != o->ensure_property_number("age")); EXPECT_TRUE(NULL == o->ensure_property_string("age")); } // count if (true) { o = SrsAmf0Any::ecma_array(); SrsAutoFree(SrsAmf0EcmaArray, o); EXPECT_EQ(0, o->count()); o->set("name", SrsAmf0Any::str("winlin")); EXPECT_EQ(1, o->count()); o->set("name", SrsAmf0Any::str("winlin")); EXPECT_EQ(1, o->count()); o->set("age", SrsAmf0Any::number(100)); EXPECT_EQ(2, o->count()); } }
// user scenario: coding and decoding with amf0 VOID TEST(AMF0Test, ScenarioMain) { // coded amf0 object int nb_bytes = 0; char* bytes = NULL; // coding data to binaries by amf0 // for example, send connect app response to client. if (true) { // props: object // fmsVer: string // capabilities: number // mode: number // info: object // level: string // code: string // descrption: string // objectEncoding: number // data: array // version: string // srs_sig: string SrsAmf0Object* props = SrsAmf0Any::object(); SrsAutoFree(SrsAmf0Object, props); props->set("fmsVer", SrsAmf0Any::str("FMS/3,5,3,888")); props->set("capabilities", SrsAmf0Any::number(253)); props->set("mode", SrsAmf0Any::number(123)); SrsAmf0Object* info = SrsAmf0Any::object(); SrsAutoFree(SrsAmf0Object, info); info->set("level", SrsAmf0Any::str("info")); info->set("code", SrsAmf0Any::str("NetStream.Connnect.Success")); info->set("descrption", SrsAmf0Any::str("connected")); info->set("objectEncoding", SrsAmf0Any::number(3)); SrsAmf0EcmaArray* data = SrsAmf0Any::ecma_array(); info->set("data", data); data->set("version", SrsAmf0Any::str("FMS/3,5,3,888")); data->set("srs_sig", SrsAmf0Any::str("srs")); // buf store the serialized props/info nb_bytes = props->total_size() + info->total_size(); ASSERT_GT(nb_bytes, 0); bytes = new char[nb_bytes]; // use SrsStream to write props/info to binary buf. SrsStream s; EXPECT_EQ(ERROR_SUCCESS, s.initialize(bytes, nb_bytes)); EXPECT_EQ(ERROR_SUCCESS, props->write(&s)); EXPECT_EQ(ERROR_SUCCESS, info->write(&s)); EXPECT_TRUE(s.empty()); // now, user can use the buf EXPECT_EQ(0x03, bytes[0]); EXPECT_EQ(0x09, bytes[nb_bytes - 1]); } SrsAutoFree(char, bytes); // decoding amf0 object from bytes // when user know the schema if (true) { ASSERT_TRUE(NULL != bytes); // use SrsStream to assist amf0 object to read from bytes. SrsStream s; EXPECT_EQ(ERROR_SUCCESS, s.initialize(bytes, nb_bytes)); // decoding // if user know the schema, for instance, it's an amf0 object, // user can use specified object to decoding. SrsAmf0Object* props = SrsAmf0Any::object(); SrsAutoFree(SrsAmf0Object, props); EXPECT_EQ(ERROR_SUCCESS, props->read(&s)); // user can use specified object to decoding. SrsAmf0Object* info = SrsAmf0Any::object(); SrsAutoFree(SrsAmf0Object, info); EXPECT_EQ(ERROR_SUCCESS, info->read(&s)); // use the decoded data. SrsAmf0Any* prop = NULL; // if user requires specified property, use ensure of amf0 object EXPECT_TRUE(NULL != (prop = props->ensure_property_string("fmsVer"))); // the property can assert to string. ASSERT_TRUE(prop->is_string()); // get the prop string value. EXPECT_STREQ("FMS/3,5,3,888", prop->to_str().c_str()); // get other type property value EXPECT_TRUE(NULL != (prop = info->get_property("data"))); // we cannot assert the property is ecma array if (prop->is_ecma_array()) { SrsAmf0EcmaArray* data = prop->to_ecma_array(); // it must be a ecma array. ASSERT_TRUE(NULL != data); // get property of array EXPECT_TRUE(NULL != (prop = data->ensure_property_string("srs_sig"))); ASSERT_TRUE(prop->is_string()); EXPECT_STREQ("srs", prop->to_str().c_str()); } // confidence about the schema EXPECT_TRUE(NULL != (prop = info->ensure_property_string("level"))); ASSERT_TRUE(prop->is_string()); EXPECT_STREQ("info", prop->to_str().c_str()); } // use any to decoding it, // if user donot know the schema if (true) { ASSERT_TRUE(NULL != bytes); // use SrsStream to assist amf0 object to read from bytes. SrsStream s; EXPECT_EQ(ERROR_SUCCESS, s.initialize(bytes, nb_bytes)); // decoding a amf0 any, for user donot know SrsAmf0Any* any = NULL; EXPECT_EQ(ERROR_SUCCESS, srs_amf0_read_any(&s, &any)); SrsAutoFree(SrsAmf0Any, any); // for amf0 object if (any->is_object()) { SrsAmf0Object* obj = any->to_object(); ASSERT_TRUE(NULL != obj); // use foreach to process properties for (int i = 0; i < obj->count(); ++i) { string name = obj->key_at(i); SrsAmf0Any* value = obj->value_at(i); // use the property name EXPECT_TRUE("" != name); // use the property value EXPECT_TRUE(NULL != value); } } } }
VOID TEST(AMF0Test, ApiSize) { // size of elem EXPECT_EQ(2+6, SrsAmf0Size::utf8("winlin")); EXPECT_EQ(2+0, SrsAmf0Size::utf8("")); EXPECT_EQ(1+2+6, SrsAmf0Size::str("winlin")); EXPECT_EQ(1+2+0, SrsAmf0Size::str("")); EXPECT_EQ(1+8, SrsAmf0Size::number()); EXPECT_EQ(1, SrsAmf0Size::null()); EXPECT_EQ(1, SrsAmf0Size::undefined()); EXPECT_EQ(1+1, SrsAmf0Size::boolean()); // object: empty if (true) { int size = 1+3; SrsAmf0Object* o = SrsAmf0Any::object(); SrsAutoFree(SrsAmf0Object, o); EXPECT_EQ(size, SrsAmf0Size::object(o)); } // object: elem if (true) { int size = 1+3; SrsAmf0Object* o = SrsAmf0Any::object(); SrsAutoFree(SrsAmf0Object, o); size += SrsAmf0Size::utf8("name")+SrsAmf0Size::str("winlin"); o->set("name", SrsAmf0Any::str("winlin")); EXPECT_EQ(size, SrsAmf0Size::object(o)); } if (true) { int size = 1+3; SrsAmf0Object* o = SrsAmf0Any::object(); SrsAutoFree(SrsAmf0Object, o); size += SrsAmf0Size::utf8("age")+SrsAmf0Size::number(); o->set("age", SrsAmf0Any::number(9)); EXPECT_EQ(size, SrsAmf0Size::object(o)); } if (true) { int size = 1+3; SrsAmf0Object* o = SrsAmf0Any::object(); SrsAutoFree(SrsAmf0Object, o); size += SrsAmf0Size::utf8("email")+SrsAmf0Size::null(); o->set("email", SrsAmf0Any::null()); EXPECT_EQ(size, SrsAmf0Size::object(o)); } if (true) { int size = 1+3; SrsAmf0Object* o = SrsAmf0Any::object(); SrsAutoFree(SrsAmf0Object, o); size += SrsAmf0Size::utf8("email")+SrsAmf0Size::undefined(); o->set("email", SrsAmf0Any::undefined()); EXPECT_EQ(size, SrsAmf0Size::object(o)); } if (true) { int size = 1+3; SrsAmf0Object* o = SrsAmf0Any::object(); SrsAutoFree(SrsAmf0Object, o); size += SrsAmf0Size::utf8("sex")+SrsAmf0Size::boolean(); o->set("sex", SrsAmf0Any::boolean(true)); EXPECT_EQ(size, SrsAmf0Size::object(o)); } // array: empty if (true) { int size = 1+4+3; SrsAmf0EcmaArray* o = SrsAmf0Any::ecma_array(); SrsAutoFree(SrsAmf0EcmaArray, o); EXPECT_EQ(size, SrsAmf0Size::ecma_array(o)); } // array: elem if (true) { int size = 1+4+3; SrsAmf0EcmaArray* o = SrsAmf0Any::ecma_array(); SrsAutoFree(SrsAmf0EcmaArray, o); size += SrsAmf0Size::utf8("name")+SrsAmf0Size::str("winlin"); o->set("name", SrsAmf0Any::str("winlin")); EXPECT_EQ(size, SrsAmf0Size::ecma_array(o)); } if (true) { int size = 1+4+3; SrsAmf0EcmaArray* o = SrsAmf0Any::ecma_array(); SrsAutoFree(SrsAmf0EcmaArray, o); size += SrsAmf0Size::utf8("age")+SrsAmf0Size::number(); o->set("age", SrsAmf0Any::number(9)); EXPECT_EQ(size, SrsAmf0Size::ecma_array(o)); } if (true) { int size = 1+4+3; SrsAmf0EcmaArray* o = SrsAmf0Any::ecma_array(); SrsAutoFree(SrsAmf0EcmaArray, o); size += SrsAmf0Size::utf8("email")+SrsAmf0Size::null(); o->set("email", SrsAmf0Any::null()); EXPECT_EQ(size, SrsAmf0Size::ecma_array(o)); } if (true) { int size = 1+4+3; SrsAmf0EcmaArray* o = SrsAmf0Any::ecma_array(); SrsAutoFree(SrsAmf0EcmaArray, o); size += SrsAmf0Size::utf8("email")+SrsAmf0Size::undefined(); o->set("email", SrsAmf0Any::undefined()); EXPECT_EQ(size, SrsAmf0Size::ecma_array(o)); } if (true) { int size = 1+4+3; SrsAmf0EcmaArray* o = SrsAmf0Any::ecma_array(); SrsAutoFree(SrsAmf0EcmaArray, o); size += SrsAmf0Size::utf8("sex")+SrsAmf0Size::boolean(); o->set("sex", SrsAmf0Any::boolean(true)); EXPECT_EQ(size, SrsAmf0Size::ecma_array(o)); } // object: array if (true) { int size = 1+3; SrsAmf0Object* o = SrsAmf0Any::object(); SrsAutoFree(SrsAmf0Object, o); size += SrsAmf0Size::utf8("name")+SrsAmf0Size::str("winlin"); o->set("name", SrsAmf0Any::str("winlin")); SrsAmf0EcmaArray* args = SrsAmf0Any::ecma_array(); args->set("p0", SrsAmf0Any::str("function")); size += SrsAmf0Size::utf8("args")+SrsAmf0Size::ecma_array(args); o->set("args", args); EXPECT_EQ(size, SrsAmf0Size::object(o)); } if (true) { int size = 1+3; SrsAmf0Object* o = SrsAmf0Any::object(); SrsAutoFree(SrsAmf0Object, o); size += SrsAmf0Size::utf8("name")+SrsAmf0Size::str("winlin"); o->set("name", SrsAmf0Any::str("winlin")); SrsAmf0EcmaArray* args = SrsAmf0Any::ecma_array(); args->set("p0", SrsAmf0Any::str("function")); size += SrsAmf0Size::utf8("args")+SrsAmf0Size::ecma_array(args); o->set("args", args); SrsAmf0EcmaArray* params = SrsAmf0Any::ecma_array(); params->set("p1", SrsAmf0Any::number(10)); size += SrsAmf0Size::utf8("params")+SrsAmf0Size::ecma_array(params); o->set("params", params); EXPECT_EQ(size, SrsAmf0Size::object(o)); } // array: object if (true) { int size = 1+4+3; SrsAmf0EcmaArray* o = SrsAmf0Any::ecma_array(); SrsAutoFree(SrsAmf0EcmaArray, o); size += SrsAmf0Size::utf8("name")+SrsAmf0Size::str("winlin"); o->set("name", SrsAmf0Any::str("winlin")); SrsAmf0Object* args = SrsAmf0Any::object(); args->set("p0", SrsAmf0Any::str("function")); size += SrsAmf0Size::utf8("args")+SrsAmf0Size::object(args); o->set("args", args); EXPECT_EQ(size, SrsAmf0Size::ecma_array(o)); } if (true) { int size = 1+4+3; SrsAmf0EcmaArray* o = SrsAmf0Any::ecma_array(); SrsAutoFree(SrsAmf0EcmaArray, o); size += SrsAmf0Size::utf8("name")+SrsAmf0Size::str("winlin"); o->set("name", SrsAmf0Any::str("winlin")); SrsAmf0Object* args = SrsAmf0Any::object(); args->set("p0", SrsAmf0Any::str("function")); size += SrsAmf0Size::utf8("args")+SrsAmf0Size::object(args); o->set("args", args); SrsAmf0Object* params = SrsAmf0Any::object(); params->set("p1", SrsAmf0Any::number(10)); size += SrsAmf0Size::utf8("params")+SrsAmf0Size::object(params); o->set("params", params); EXPECT_EQ(size, SrsAmf0Size::ecma_array(o)); } // object: object if (true) { int size = 1+3; SrsAmf0Object* o = SrsAmf0Any::object(); SrsAutoFree(SrsAmf0Object, o); size += SrsAmf0Size::utf8("name")+SrsAmf0Size::str("winlin"); o->set("name", SrsAmf0Any::str("winlin")); SrsAmf0Object* args = SrsAmf0Any::object(); args->set("p0", SrsAmf0Any::str("function")); size += SrsAmf0Size::utf8("args")+SrsAmf0Size::object(args); o->set("args", args); SrsAmf0Object* params = SrsAmf0Any::object(); params->set("p1", SrsAmf0Any::number(10)); size += SrsAmf0Size::utf8("params")+SrsAmf0Size::object(params); o->set("params", params); EXPECT_EQ(size, SrsAmf0Size::object(o)); } // array: array if (true) { int size = 1+4+3; SrsAmf0EcmaArray* o = SrsAmf0Any::ecma_array(); SrsAutoFree(SrsAmf0EcmaArray, o); size += SrsAmf0Size::utf8("name")+SrsAmf0Size::str("winlin"); o->set("name", SrsAmf0Any::str("winlin")); SrsAmf0EcmaArray* args = SrsAmf0Any::ecma_array(); args->set("p0", SrsAmf0Any::str("function")); size += SrsAmf0Size::utf8("args")+SrsAmf0Size::ecma_array(args); o->set("args", args); SrsAmf0EcmaArray* params = SrsAmf0Any::ecma_array(); params->set("p1", SrsAmf0Any::number(10)); size += SrsAmf0Size::utf8("params")+SrsAmf0Size::ecma_array(params); o->set("params", params); EXPECT_EQ(size, SrsAmf0Size::ecma_array(o)); } }
int SrsRtmpClient::connect_app(string app, string tc_url) { int ret = ERROR_SUCCESS; // Connect(vhost, app) if (true) { SrsConnectAppPacket* pkt = new SrsConnectAppPacket(); pkt->command_object->set("app", SrsAmf0Any::str(app.c_str())); pkt->command_object->set("flashVer", SrsAmf0Any::str("WIN 12,0,0,41")); pkt->command_object->set("swfUrl", SrsAmf0Any::str()); pkt->command_object->set("tcUrl", SrsAmf0Any::str(tc_url.c_str())); pkt->command_object->set("fpad", SrsAmf0Any::boolean(false)); pkt->command_object->set("capabilities", SrsAmf0Any::number(239)); pkt->command_object->set("audioCodecs", SrsAmf0Any::number(3575)); pkt->command_object->set("videoCodecs", SrsAmf0Any::number(252)); pkt->command_object->set("videoFunction", SrsAmf0Any::number(1)); pkt->command_object->set("pageUrl", SrsAmf0Any::str()); pkt->command_object->set("objectEncoding", SrsAmf0Any::number(0)); if ((ret = protocol->send_and_free_packet(pkt, 0)) != ERROR_SUCCESS) { return ret; } } // Set Window Acknowledgement size(2500000) if (true) { SrsSetWindowAckSizePacket* pkt = new SrsSetWindowAckSizePacket(); pkt->ackowledgement_window_size = 2500000; if ((ret = protocol->send_and_free_packet(pkt, 0)) != ERROR_SUCCESS) { return ret; } } // expect connect _result SrsMessage* msg = NULL; SrsConnectAppResPacket* pkt = NULL; if ((ret = srs_rtmp_expect_message<SrsConnectAppResPacket>(protocol, &msg, &pkt)) != ERROR_SUCCESS) { srs_error("expect connect app response message failed. ret=%d", ret); return ret; } SrsAutoFree(SrsMessage, msg); SrsAutoFree(SrsConnectAppResPacket, pkt); // server info std::string srs_version; std::string srs_server_ip; int srs_id = 0; int srs_pid = 0; SrsAmf0Any* data = pkt->info->get_property("data"); if (data && data->is_ecma_array()) { SrsAmf0EcmaArray* arr = data->to_ecma_array(); SrsAmf0Any* prop = NULL; if ((prop = arr->ensure_property_string("srs_version")) != NULL) { srs_version = prop->to_str(); } if ((prop = arr->ensure_property_string("srs_server_ip")) != NULL) { srs_server_ip = prop->to_str(); } if ((prop = arr->ensure_property_number("srs_id")) != NULL) { srs_id = (int)prop->to_number(); } if ((prop = arr->ensure_property_number("srs_pid")) != NULL) { srs_pid = (int)prop->to_number(); } } srs_trace("connected, version=%s, ip=%s, pid=%d, id=%d", srs_version.c_str(), srs_server_ip.c_str(), srs_pid, srs_id); return ret; }