int SrsDvrPlan::open_new_segment() { int ret = ERROR_SUCCESS; SrsRequest* req = _req; // new flv file std::stringstream path; path << _srs_config->get_dvr_path(req->vhost) << "/" << req->app << "/" << req->stream << "." << srs_get_system_time_ms() << ".flv"; if ((ret = flv_open(req->get_stream_url(), path.str())) != ERROR_SUCCESS) { return ret; } dvr_enabled = true; return ret; }
int SrsHttpStreamServer::on_reload_vhost_http_remux_updated(string vhost) { int ret = ERROR_SUCCESS; if (tflvs.find(vhost) == tflvs.end()) { if ((ret = initialize_flv_entry(vhost)) != ERROR_SUCCESS) { return ret; } // http mount need SrsRequest and SrsSource param, only create a mapping template entry // and do mount automatically on playing http flv if this stream is a new http_remux stream. return ret; } SrsLiveEntry* tmpl = tflvs[vhost]; SrsRequest* req = tmpl->req; SrsSource* source = tmpl->source; if (source && req) { // cleanup the exists http remux. http_unmount(source, req); } if (!_srs_config->get_vhost_http_remux_enabled(vhost)) { return ret; } string old_tmpl_mount = tmpl->mount; string new_tmpl_mount = _srs_config->get_vhost_http_remux_mount(vhost); bool hstrs = _srs_config->get_vhost_http_remux_hstrs(vhost); tmpl->reset_hstrs(hstrs); /** * TODO: not support to reload different mount url for the time being. * if the mount is change, need more logical thing to deal with. * such as erase stream from sflvs and free all related resource. */ srs_assert(old_tmpl_mount == new_tmpl_mount); // do http mount directly with SrsRequest and SrsSource if stream is played already. if (req) { std::string sid = req->get_stream_url(); if (sflvs.find(sid) != sflvs.end()) { SrsLiveEntry* stream = sflvs[sid]; stream->reset_hstrs(hstrs); } // remount stream. if ((ret = http_mount(source, req)) != ERROR_SUCCESS) { srs_trace("vhost %s http_remux reload failed", vhost.c_str()); return ret; } } else { // for without SrsRequest and SrsSource if stream is not played yet, do http mount automatically // when start play this http flv stream. } srs_trace("vhost %s http_remux reload success", vhost.c_str()); return ret; }
int SrsHttpStreamServer::hijack(ISrsHttpMessage* request, ISrsHttpHandler** ph) { int ret = ERROR_SUCCESS; // when handler not the root, we think the handler is ok. ISrsHttpHandler* h = *ph? *ph : NULL; if (h && h->entry && h->entry->pattern != "/") { return ret; } // only hijack for http streaming, http-flv/ts/mp3/aac. std::string ext = request->ext(); if (ext.empty()) { return ret; } // find the actually request vhost. SrsConfDirective* vhost = _srs_config->get_vhost(request->host()); if (!vhost || !_srs_config->get_vhost_enabled(vhost)) { return ret; } // find the entry template for the stream. SrsLiveEntry* entry = NULL; if (true) { // no http streaming on vhost, ignore. std::map<std::string, SrsLiveEntry*>::iterator it = tflvs.find(vhost->arg0()); if (it == tflvs.end()) { return ret; } // hstrs not enabled, ignore. // for origin, the http stream will be mount already when publish, // so it must never enter this line for stream already mounted. // for edge, the http stream is trigger by hstrs and mount by it, // so we only hijack when only edge and hstrs is on. entry = it->second; if (!entry->hstrs) { return ret; } // check entry and request extension. if (entry->is_flv()) { if (ext != ".flv") { return ret; } } else if (entry->is_ts()) { if (ext != ".ts") { return ret; } } else if (entry->is_mp3()) { if (ext != ".mp3") { return ret; } } else if (entry->is_aac()) { if (ext != ".aac") { return ret; } } else { return ret; } } // convert to concreate class. SrsHttpMessage* hreq = dynamic_cast<SrsHttpMessage*>(request); srs_assert(hreq); // hijack for entry. SrsRequest* r = hreq->to_request(vhost->arg0()); SrsAutoFree(SrsRequest, r); std::string sid = r->get_stream_url(); // check whether the http remux is enabled, // for example, user disable the http flv then reload. if (sflvs.find(sid) != sflvs.end()) { SrsLiveEntry* s_entry = sflvs[sid]; if (!s_entry->stream->entry->enabled) { // only when the http entry is disabled, check the config whether http flv disable, // for the http flv edge use hijack to trigger the edge ingester, we always mount it // eventhough the origin does not exists the specified stream. if (!_srs_config->get_vhost_http_remux_enabled(r->vhost)) { srs_error("stream is disabled, hijack failed. ret=%d", ret); return ret; } } } SrsSource* s = SrsSource::fetch(r); if (!s) { if ((ret = SrsSource::create(r, server, server, &s)) != ERROR_SUCCESS) { return ret; } } srs_assert(s != NULL); // create http streaming handler. if ((ret = http_mount(s, r)) != ERROR_SUCCESS) { return ret; } // use the handler if exists. if (ph) { if (sflvs.find(sid) != sflvs.end()) { entry = sflvs[sid]; *ph = entry->stream; } } // trigger edge to fetch from origin. bool vhost_is_edge = _srs_config->get_vhost_is_edge(r->vhost); srs_trace("hstrs: source url=%s, is_edge=%d, source_id=%d[%d]", r->get_stream_url().c_str(), vhost_is_edge, s->source_id(), s->source_id()); return ret; }