srs_amf0_t srs_amf0_parse(char* data, int size, int* nparsed) { int ret = ERROR_SUCCESS; srs_amf0_t amf0 = NULL; SrsStream stream; if ((ret = stream.initialize(data, size)) != ERROR_SUCCESS) { return amf0; } SrsAmf0Any* any = NULL; if ((ret = SrsAmf0Any::discovery(&stream, &any)) != ERROR_SUCCESS) { return amf0; } stream.reset(); if ((ret = any->read(&stream)) != ERROR_SUCCESS) { srs_freep(any); return amf0; } *nparsed = stream.pos(); amf0 = (srs_amf0_t)any; return amf0; }
srs_amf0_t srs_amf0_strict_array_property_at(srs_amf0_t amf0, int index) { SrsAmf0Any* any = (SrsAmf0Any*)amf0; srs_assert(any->is_strict_array()); SrsAmf0StrictArray* obj = (SrsAmf0StrictArray*)amf0; return (srs_amf0_t)obj->at(index); }
int srs_amf0_strict_array_property_count(srs_amf0_t amf0) { SrsAmf0Any* any = (SrsAmf0Any*)amf0; srs_assert(any->is_strict_array()); SrsAmf0StrictArray * obj = (SrsAmf0StrictArray*)amf0; return obj->count(); }
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); }
srs_amf0_t srs_amf0_object_property(srs_amf0_t amf0, const char* name) { SrsAmf0Any* any = (SrsAmf0Any*)amf0; srs_assert(any->is_object()); SrsAmf0Object* obj = (SrsAmf0Object*)amf0; return (srs_amf0_t)obj->get_property(name); }
srs_amf0_t srs_amf0_object_property_value_at(srs_amf0_t amf0, int index) { SrsAmf0Any* any = (SrsAmf0Any*)amf0; srs_assert(any->is_object()); SrsAmf0Object* obj = (SrsAmf0Object*)amf0; return (srs_amf0_t)obj->value_at(index); }
const char* srs_amf0_object_property_name_at(srs_amf0_t amf0, int index) { SrsAmf0Any* any = (SrsAmf0Any*)amf0; srs_assert(any->is_object()); SrsAmf0Object* obj = (SrsAmf0Object*)amf0; return obj->key_raw_at(index); }
void srs_amf0_object_clear(srs_amf0_t amf0) { SrsAmf0Any* any = (SrsAmf0Any*)amf0; srs_assert(any->is_object()); SrsAmf0Object* obj = (SrsAmf0Object*)amf0; obj->clear(); }
int srs_amf0_object_property_count(srs_amf0_t amf0) { SrsAmf0Any* any = (SrsAmf0Any*)amf0; srs_assert(any->is_object()); SrsAmf0Object* obj = (SrsAmf0Object*)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); }
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(); }
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); }
void srs_amf0_object_property_set(srs_amf0_t amf0, const char* name, srs_amf0_t value) { SrsAmf0Any* any = (SrsAmf0Any*)amf0; srs_assert(any->is_object()); SrsAmf0Object* obj = (SrsAmf0Object*)amf0; any = (SrsAmf0Any*)value; obj->set(name, any); }
void srs_amf0_strict_array_append(srs_amf0_t amf0, srs_amf0_t value) { SrsAmf0Any* any = (SrsAmf0Any*)amf0; srs_assert(any->is_strict_array()); SrsAmf0StrictArray* obj = (SrsAmf0StrictArray*)amf0; any = (SrsAmf0Any*)value; obj->append(any); }
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); }
char* srs_amf0_human_print(srs_amf0_t amf0, char** pdata, int* psize) { if (!amf0) { return NULL; } SrsAmf0Any* any = (SrsAmf0Any*)amf0; return any->human_print(pdata, psize); }
void SrsUnSortedHashtable::copy(SrsUnSortedHashtable* src) { std::vector<SrsAmf0ObjectPropertyType>::iterator it; for (it = src->properties.begin(); it != src->properties.end(); ++it) { SrsAmf0ObjectPropertyType& elem = *it; std::string key = elem.first; SrsAmf0Any* any = elem.second; set(key, any->copy()); } }
int SrsFlvSegment::update_flv_metadata() { int ret = ERROR_SUCCESS; // no duration or filesize specified. if (!duration_offset || !filesize_offset) { return ret; } int64_t cur = fs->tellg(); // buffer to write the size. char* buf = new char[SrsAmf0Size::number()]; SrsAutoFreeA(char, buf); SrsBuffer stream; if ((ret = stream.initialize(buf, SrsAmf0Size::number())) != ERROR_SUCCESS) { return ret; } // filesize to buf. SrsAmf0Any* size = SrsAmf0Any::number((double)cur); SrsAutoFree(SrsAmf0Any, size); stream.skip(-1 * stream.pos()); if ((ret = size->write(&stream)) != ERROR_SUCCESS) { return ret; } // update the flesize. fs->lseek(filesize_offset); if ((ret = fs->write(buf, SrsAmf0Size::number(), NULL)) != ERROR_SUCCESS) { return ret; } // duration to buf SrsAmf0Any* dur = SrsAmf0Any::number((double)duration / 1000.0); SrsAutoFree(SrsAmf0Any, dur); stream.skip(-1 * stream.pos()); if ((ret = dur->write(&stream)) != ERROR_SUCCESS) { return ret; } // update the duration fs->lseek(duration_offset); if ((ret = fs->write(buf, SrsAmf0Size::number(), NULL)) != ERROR_SUCCESS) { return ret; } // reset the offset. fs->lseek(cur); return ret; }
int SrsAmf0StrictArray::total_size() { int size = 1 + 4; for (int i = 0; i < (int)properties.size(); i++){ SrsAmf0Any* any = properties[i]; size += any->total_size(); } return size; }
SrsAmf0Any* SrsAmf0StrictArray::copy() { SrsAmf0StrictArray* copy = new SrsAmf0StrictArray(); std::vector<SrsAmf0Any*>::iterator it; for (it = properties.begin(); it != properties.end(); ++it) { SrsAmf0Any* any = *it; copy->append(any->copy()); } copy->_count = _count; return copy; }
int SrsRtmpServer::connect_app(SrsRequest* req) { int ret = ERROR_SUCCESS; SrsMessage* msg = NULL; SrsConnectAppPacket* pkt = NULL; if ((ret = expect_message<SrsConnectAppPacket>(&msg, &pkt)) != ERROR_SUCCESS) { srs_error("expect connect app message failed. ret=%d", ret); return ret; } SrsAutoFree(SrsMessage, msg); SrsAutoFree(SrsConnectAppPacket, pkt); srs_info("get connect app message"); SrsAmf0Any* prop = NULL; if ((prop = pkt->command_object->ensure_property_string("tcUrl")) == NULL) { ret = ERROR_RTMP_REQ_CONNECT; srs_error("invalid request, must specifies the tcUrl. ret=%d", ret); return ret; } req->tcUrl = prop->to_str(); if ((prop = pkt->command_object->ensure_property_string("pageUrl")) != NULL) { req->pageUrl = prop->to_str(); } if ((prop = pkt->command_object->ensure_property_string("swfUrl")) != NULL) { req->swfUrl = prop->to_str(); } if ((prop = pkt->command_object->ensure_property_number("objectEncoding")) != NULL) { req->objectEncoding = prop->to_number(); } if (pkt->args) { srs_freep(req->args); req->args = pkt->args->copy()->to_object(); srs_info("copy edge traverse to origin auth args."); } srs_info("get connect app message params success."); srs_discovery_tc_url(req->tcUrl, req->schema, req->host, req->vhost, req->app, req->port, req->param); req->strip(); return ret; }
SrsAmf0Any* SrsUnSortedHashtable::ensure_property_number(string name) { SrsAmf0Any* prop = get_property(name); if (!prop) { return NULL; } if (!prop->is_number()) { return NULL; } return prop; }
int srs_amf0_serialize(srs_amf0_t amf0, char* data, int size) { int ret = ERROR_SUCCESS; SrsAmf0Any* any = (SrsAmf0Any*)amf0; SrsStream stream; if ((ret = stream.initialize(data, size)) != ERROR_SUCCESS) { return ret; } if ((ret = any->write(&stream)) != ERROR_SUCCESS) { return ret; } return ret; }
int SrsRtmpServer::connect_app(SrsRequest* req) { int ret = ERROR_SUCCESS; SrsMessage* msg = NULL; SrsConnectAppPacket* pkt = NULL; if ((ret = srs_rtmp_expect_message<SrsConnectAppPacket>(protocol, &msg, &pkt)) != ERROR_SUCCESS) { srs_error("expect connect app message failed. ret=%d", ret); return ret; } SrsAutoFree(SrsMessage, msg, false); SrsAutoFree(SrsConnectAppPacket, pkt, false); srs_info("get connect app message"); SrsAmf0Any* prop = NULL; if ((prop = pkt->command_object->ensure_property_string("tcUrl")) == NULL) { ret = ERROR_RTMP_REQ_CONNECT; srs_error("invalid request, must specifies the tcUrl. ret=%d", ret); return ret; } req->tcUrl = prop->to_str(); if ((prop = pkt->command_object->ensure_property_string("pageUrl")) != NULL) { req->pageUrl = prop->to_str(); } if ((prop = pkt->command_object->ensure_property_string("swfUrl")) != NULL) { req->swfUrl = prop->to_str(); } if ((prop = pkt->command_object->ensure_property_number("objectEncoding")) != NULL) { req->objectEncoding = prop->to_number(); } srs_info("get connect app message params success."); return req->discovery_app(); }
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; }
// TODO: return detail message when error for client. int SrsRtmpConn::do_cycle() { int ret = ERROR_SUCCESS; srs_trace("RTMP client ip=%s", ip.c_str()); rtmp->set_recv_timeout(SRS_CONSTS_RTMP_RECV_TIMEOUT_US); rtmp->set_send_timeout(SRS_CONSTS_RTMP_SEND_TIMEOUT_US); if ((ret = rtmp->handshake()) != ERROR_SUCCESS) { srs_error("rtmp handshake failed. ret=%d", ret); return ret; } srs_verbose("rtmp handshake success"); if ((ret = rtmp->connect_app(req)) != ERROR_SUCCESS) { srs_error("rtmp connect vhost/app failed. ret=%d", ret); return ret; } srs_verbose("rtmp connect app success"); // discovery vhost, resolve the vhost from config SrsConfDirective* parsed_vhost = _srs_config->get_vhost(req->vhost); if (parsed_vhost) { req->vhost = parsed_vhost->arg0(); } srs_info("discovery app success. schema=%s, vhost=%s, port=%s, app=%s", req->schema.c_str(), req->vhost.c_str(), req->port.c_str(), req->app.c_str()); if (req->schema.empty() || req->vhost.empty() || req->port.empty() || req->app.empty()) { ret = ERROR_RTMP_REQ_TCURL; srs_error("discovery tcUrl failed. " "tcUrl=%s, schema=%s, vhost=%s, port=%s, app=%s, ret=%d", req->tcUrl.c_str(), req->schema.c_str(), req->vhost.c_str(), req->port.c_str(), req->app.c_str(), ret); return ret; } // check vhost if ((ret = check_vhost()) != ERROR_SUCCESS) { srs_error("check vhost failed. ret=%d", ret); return ret; } srs_verbose("check vhost success."); srs_trace("connect app, " "tcUrl=%s, pageUrl=%s, swfUrl=%s, schema=%s, vhost=%s, port=%s, app=%s, args=%s", req->tcUrl.c_str(), req->pageUrl.c_str(), req->swfUrl.c_str(), req->schema.c_str(), req->vhost.c_str(), req->port.c_str(), req->app.c_str(), (req->args? "(obj)":"null")); // show client identity if(req->args) { std::string srs_version; std::string srs_server_ip; int srs_pid = 0; int srs_id = 0; SrsAmf0Any* prop = NULL; if ((prop = req->args->ensure_property_string("srs_version")) != NULL) { srs_version = prop->to_str(); } if ((prop = req->args->ensure_property_string("srs_server_ip")) != NULL) { srs_server_ip = prop->to_str(); } if ((prop = req->args->ensure_property_number("srs_pid")) != NULL) { srs_pid = (int)prop->to_number(); } if ((prop = req->args->ensure_property_number("srs_id")) != NULL) { srs_id = (int)prop->to_number(); } srs_info("edge-srs ip=%s, version=%s, pid=%d, id=%d", srs_server_ip.c_str(), srs_version.c_str(), srs_pid, srs_id); if (srs_pid > 0) { srs_trace("edge-srs ip=%s, version=%s, pid=%d, id=%d", srs_server_ip.c_str(), srs_version.c_str(), srs_pid, srs_id); } } ret = service_cycle(); http_hooks_on_close(); return ret; }
const char* srs_amf0_to_string(srs_amf0_t amf0) { SrsAmf0Any* any = (SrsAmf0Any*)amf0; return any->to_str_raw(); }
amf0_bool srs_amf0_to_boolean(srs_amf0_t amf0) { SrsAmf0Any* any = (SrsAmf0Any*)amf0; return any->to_boolean(); }
amf0_number srs_amf0_to_number(srs_amf0_t amf0) { SrsAmf0Any* any = (SrsAmf0Any*)amf0; return any->to_number(); }
void srs_amf0_set_number(srs_amf0_t amf0, amf0_number value) { SrsAmf0Any* any = (SrsAmf0Any*)amf0; any->set_number(value); }