/* ******************************************************************************* * INCLUDE ******************************************************************************* */ #include "Service.h" #include #include #include #include #include #include #include #include "Application.h" #include "Logger.h" #include "Poco/Dynamic/Struct.h" #include "Poco/Dynamic/Var.h" #include "Poco/Exception.h" #include "Poco/JSON/JSONException.h" #include "Poco/JSON/Object.h" #include "Poco/JSON/Parser.h" #include "Poco/JSON/Query.h" #include "Poco/Net/HTTPClientSession.h" #include "Poco/Net/HTTPRequest.h" #include "Poco/Net/HTTPServerResponse.h" #include "Poco/URI.h" namespace Video { namespace ZLMediaKit { static const std::string iniConfigFilePath = "/customer/config.ini"; static int zlHttpPort = 0; static Poco::JSON::Object::Ptr currZlConfig; /* ******************************************************************************* * CLASS DEFINE ******************************************************************************* */ Poco::Dynamic::Array Service::getMediaList(std::string schema, std::string app, std::string stream) { std::string _schema = schema == "srt" ? "ts" : schema; Poco::URI uri; addSecurityParameter(uri); uri.setPath("/index/api/getMediaList"); uri.addQueryParameter("vhost", "__defaultVhost__"); uri.addQueryParameter("schema", _schema); uri.addQueryParameter("app", app); uri.addQueryParameter("stream", stream); Poco::DynamicStruct json = sendRequest(uri.toString()); Poco::Dynamic::Array data; try { int code = json["code"]; if (0 == code) { if (json["data"].isArray()) { data = json["data"].extract(); } else { } } } catch (Poco::Exception& e) { logger().information(e.displayText()); } return data; } bool Service::isMediaOnline(std::string schema, std::string app, std::string stream) { Poco::URI uri; addSecurityParameter(uri); uri.setPath("/index/api/isMediaOnline"); uri.addQueryParameter("vhost", "__defaultVhost__"); uri.addQueryParameter("schema", schema); uri.addQueryParameter("app", app); uri.addQueryParameter("stream", stream); Poco::DynamicStruct json = sendRequest(uri.toString()); try { int code = json["code"]; if (0 == code) return json["online"]; } catch (Poco::Exception& e) { logger().information(e.displayText()); } return false; } Poco::Tuple Service::addStreamPusherProxy(std::string schema, std::string app, std::string stream, std::string url, std::string rtp_type) { std::string _schema = schema == "srt" ? "ts" : schema; _schema = (_schema == "webrtc" || _schema == "webrtcs") ? "rtsp" : _schema; Poco::URI uri; addSecurityParameter(uri); uri.setPath("/index/api/addStreamPusherProxy"); uri.addQueryParameter("vhost", "__defaultVhost__"); uri.addQueryParameter("schema", _schema); uri.addQueryParameter("app", app); uri.addQueryParameter("stream", stream); uri.addQueryParameter("dst_url", url); uri.addQueryParameter("rtp_type", rtp_type); auto json = sendRequest(uri.toString()); Poco::Tuple rv; try { int code = json["code"]; rv.set<0>(code); if (0 == code) { rv.set<1>(json["data"]["key"]); } else { logger().warning("addStreamPusherProxy %s %s/%s, error msg: " + json["msg"], _schema, app, stream); } } catch (Poco::Exception& e) { logger().warning("addStreamPusherProxy error:%s %s/%s %s", _schema, app, stream, e.displayText()); } return rv; } int Service::delStreamPusherProxy(std::string key) { if (key.empty()) { return 1; } Poco::URI uri; addSecurityParameter(uri); uri.setPath("/index/api/delStreamPusherProxy"); uri.addQueryParameter("key", key); try { auto json = sendRequest(uri.toString()); return json["code"]; } catch (Poco::Exception& e) { logger().error("zl delStreamPusherProxy:%s", std::string(e.what())); } return 1; } int Service::getStremPusherProxyInfo(std::string key, StremPusherProxyInfo& info) { Poco::URI uri; addSecurityParameter(uri); uri.setPath("/index/api/getProxyPusherInfo"); uri.addQueryParameter("key", key); auto json = sendRequest(uri.toString()); Poco::Tuple rv; try { int code = json["code"]; info.code = code; if (0 == code) { info.status = json["data"]["status"]; info.liveSeconds = json["data"]["liveSecs"]; info.republishCount = json["data"]["rePublishCount"]; } else { info.msg = json["msg"].toString(); } } catch (Poco::Exception& e) { logger().information(e.displayText()); } return json["code"]; } int Service::startSendRtp(std::string app, std::string stream, std::string ssrc, std::string url, std::string port, std::string udp) { Poco::URI uri; addSecurityParameter(uri); uri.setPath("/index/api/startSendRtp"); uri.addQueryParameter("vhost", "__defaultVhost__"); uri.addQueryParameter("app", app); uri.addQueryParameter("stream", stream); uri.addQueryParameter("ssrc", ssrc); uri.addQueryParameter("dst_url", url); uri.addQueryParameter("dst_port", port); uri.addQueryParameter("src_port", "6000"); uri.addQueryParameter("is_udp", udp); auto json = sendRequest(uri.toString()); return json["code"]; } int Service::startSendRtpPassive(std::string app, std::string stream, std::string ssrc, std::string udp) { Poco::URI uri; addSecurityParameter(uri); uri.setPath("/index/api/startSendRtpPassive"); uri.addQueryParameter("vhost", "__defaultVhost__"); uri.addQueryParameter("app", app); uri.addQueryParameter("stream", stream); uri.addQueryParameter("ssrc", ssrc); uri.addQueryParameter("src_port", "6000"); uri.addQueryParameter("is_udp", udp); auto json = sendRequest(uri.toString()); return json["code"]; } int Service::stopSendRtp(std::string app, std::string stream, std::string ssrc) { Poco::URI uri; addSecurityParameter(uri); uri.setPath("/index/api/stopSendRtp"); uri.addQueryParameter("vhost", "__defaultVhost__"); uri.addQueryParameter("app", app); uri.addQueryParameter("stream", stream); uri.addQueryParameter("ssrc", ssrc); auto json = sendRequest(uri.toString()); return json["code"]; } bool Service::isRecording(std::string app, std::string stream, int type) { Poco::URI uri; addSecurityParameter(uri); uri.setPath("/index/api/isRecording"); uri.addQueryParameter("vhost", "__defaultVhost__"); uri.addQueryParameter("app", app); uri.addQueryParameter("stream", stream); uri.addQueryParameter("type", std::to_string(type)); auto json = sendRequest(uri.toString()); if (json["code"] == 0) { return json["status"]; } return false; } bool Service::startRecord(std::string app, std::string stream, int type, std::string customized_path, int max_second) { Poco::URI uri; addSecurityParameter(uri); uri.setPath("/index/api/startRecord"); uri.addQueryParameter("vhost", "__defaultVhost__"); uri.addQueryParameter("app", app); uri.addQueryParameter("stream", stream); uri.addQueryParameter("type", std::to_string(type)); uri.addQueryParameter("customized_path", customized_path); uri.addQueryParameter("max_second", std::to_string(max_second)); auto json = sendRequest(uri.toString()); logger().information("startRecord app=%s,stream=%s, zl return: %s", app, stream, json.toString()); if (json["code"] == 0) { return json["result"]; } return false; } bool Service::stopRecord(std::string app, std::string stream, int type) { Poco::URI uri; addSecurityParameter(uri); uri.setPath("/index/api/stopRecord"); uri.addQueryParameter("vhost", "__defaultVhost__"); uri.addQueryParameter("app", app); uri.addQueryParameter("stream", stream); uri.addQueryParameter("type", std::to_string(type)); auto json = sendRequest(uri.toString()); logger().information("stopRecord app=%s,stream=%s, zl return: %s", app, stream, json.toString()); if (json["code"] == 0) { return json["result"]; } return true; } std::string Service::getMp4RecordFile(std::string app, std::string stream, std::string period, std::string customized_path) { Poco::URI uri; addSecurityParameter(uri); uri.setPath("/index/api/getMp4RecordFile"); uri.addQueryParameter("vhost", "__defaultVhost__"); uri.addQueryParameter("app", app); uri.addQueryParameter("stream", stream); uri.addQueryParameter("period", period); uri.addQueryParameter("customized_path", customized_path); auto json = sendRequest(uri.toString()); if (json["code"] == 0) { return json["data"]; } return "{}"; } Poco::Tuple Service::addStreamProxy(std::string app, std::string stream, std::string url, int auto_close, int rtp_type) { std::string _url = url; if (Poco::startsWith(Poco::toLower(_url), std::string("srt://"))) { Poco::replaceInPlace(_url, ",m=publish", ""); } Poco::URI uri; addSecurityParameter(uri); uri.setPath("/index/api/addStreamProxy"); uri.addQueryParameter("vhost", "__defaultVhost__"); uri.addQueryParameter("app", app); uri.addQueryParameter("stream", stream); uri.addQueryParameter("url", _url); uri.addQueryParameter("rtp_type", std::to_string(rtp_type)); uri.addQueryParameter("auto_close", std::to_string(auto_close)); auto json = sendRequest(uri.toString()); Poco::Tuple rv; try { int code = json["code"]; rv.set<0>(code); if (0 == code) rv.set<1>(json["data"]["key"]); } catch (Poco::Exception& e) { logger().information(e.displayText()); } return rv; } bool Service::delStreamProxy(std::string key) { if (key.empty()) { logger().warning("delStreamProxy key is empty"); return true; } Poco::URI uri; addSecurityParameter(uri); uri.setPath("/index/api/delStreamProxy"); uri.addQueryParameter("key", key); auto json = sendRequestReturnJson(uri.toString()); int code = json->get("code"); try { if (0 == code) { return json->getObject("data")->getValue("flag"); } } catch (Poco::Exception& e) { logger().error(e.displayText()); } return false; } int Service::getProxyInfo(std::string key, StreamProxyInfo& info) { Poco::URI uri; addSecurityParameter(uri); uri.setPath("/index/api/getProxyInfo"); uri.addQueryParameter("key", key); auto json = sendRequest(uri.toString()); int code = json["code"]; try { info.code = code; if (0 == code) { info.status = json["data"]["status"]; info.liveSecs = json["data"]["liveSecs"]; info.rePullCount = json["data"]["rePullCount"]; } else { info.msg = json["msg"].toString(); } } catch (Poco::Exception& e) { logger().information(e.displayText()); } return code; } Poco::Tuple Service::close_streams(std::string app, std::string stream, int force) { Poco::URI uri; addSecurityParameter(uri); uri.setPath("/index/api/close_streams"); uri.addQueryParameter("vhost", "__defaultVhost__"); uri.addQueryParameter("app", app); uri.addQueryParameter("stream", stream); uri.addQueryParameter("force", std::to_string(force)); auto json = sendRequest(uri.toString()); Poco::Tuple rv; try { int code = json["code"]; rv.set<0>(code); if (0 == code) { } } catch (Poco::Exception& e) { logger().information(e.displayText()); } return rv; } Poco::Dynamic::Array Service::listStreamProxy() { Poco::URI uri; addSecurityParameter(uri); uri.setPath("/index/api/listStreamProxy"); Poco::DynamicStruct json = sendRequest(uri.toString()); Poco::Dynamic::Array data; try { int code = json["code"]; if (0 == code) { if (json["data"].isArray()) { data = json["data"].extract(); } else { } } } catch (Poco::Exception& e) { logger().information(e.displayText()); } return data; } Poco::Dynamic::Array Service::listStreamPusherProxy() { Poco::URI uri; addSecurityParameter(uri); uri.setPath("/index/api/listStreamPusherProxy"); Poco::DynamicStruct json = sendRequest(uri.toString()); Poco::Dynamic::Array data; try { int code = json["code"]; if (0 == code) { if (json["data"].isArray()) { data = json["data"].extract(); } else { } } } catch (Poco::Exception& e) { logger().information(e.displayText()); } return data; } Poco::JSON::Object::Ptr Service::getServerConfig() { if (!currZlConfig.isNull()) { return currZlConfig; } Poco::URI uri; addSecurityParameter(uri); uri.setPath("/index/api/getServerConfig"); try { auto json = sendRequestReturnJson(uri.toString()); int code = json->get("code"); if (0 == code) { currZlConfig = json->getArray("data")->getObject(0); } } catch (std::exception& e) { logger().error("getServerConfig==========" + std::string(e.what())); } return currZlConfig; } bool Service::setServerConfig(std::string key, std::string val) { Poco::URI uri; addSecurityParameter(uri); uri.setPath("/index/api/setServerConfig"); uri.addQueryParameter(key, val); auto json = sendRequest(uri.toString()); try { int code = json["code"]; if (0 == code) { return true; } } catch (Poco::Exception& e) { logger().error(e.displayText()); } return false; } Poco::DynamicStruct Service::sendRequest(std::string uri) { Poco::Net::HTTPClientSession session("127.0.0.1", getHttpPort()); Poco::Net::HTTPRequest request(Poco::Net::HTTPRequest::HTTP_GET, uri); Poco::Net::HTTPResponse response; session.sendRequest(request); std::istream& st = session.receiveResponse(response); std::string rawData; Poco::StreamCopier::copyToString(st, rawData); Poco::DynamicStruct json = *Poco::JSON::Parser().parse(rawData).extract(); int code = json["code"]; if (0 != code) { logger().debug("zl sendRequest,uri: %s,return: %s", uri, rawData); } return json; } Poco::JSON::Object::Ptr Service::sendRequestReturnJson(std::string uri) { Poco::Net::HTTPClientSession session("127.0.0.1", getHttpPort()); Poco::Net::HTTPRequest request(Poco::Net::HTTPRequest::HTTP_GET, uri); Poco::Net::HTTPResponse response; session.sendRequest(request); std::istream& st = session.receiveResponse(response); std::string rawData; Poco::StreamCopier::copyToString(st, rawData); auto json = Poco::JSON::Parser().parse(rawData).extract(); if (0 != json->getValue("code")) { logger().debug("zl sendRequest,uri: %s,return: %s", uri, rawData); } return json; } void Service::addSecurityParameter(Poco::URI& uri) { uri.addQueryParameter("secret", "035c73f7-bb6b-4889-a715-d9eb2d1925dd"); } std::string Service::getDefaultHost() { return "__defaultVhost__"; } Poco::AutoPtr Service::loadIniFileConfig() { try { return new Poco::Util::IniFileConfiguration(iniConfigFilePath); } catch (const Poco::Exception& ex) { logger().error("Service::loadIniFileConfig, Error loading INI file:%s", ex.displayText()); return nullptr; } } int Service::getHttpPort() { if (zlHttpPort <= 0) { auto iniConfig = loadIniFileConfig(); zlHttpPort = iniConfig->getInt("http.port"); } return zlHttpPort; } } }