diff --git a/api/include/mk_rtp_server.h b/api/include/mk_rtp_server.h index 60cdb43d..7a266fa5 100644 --- a/api/include/mk_rtp_server.h +++ b/api/include/mk_rtp_server.h @@ -24,6 +24,7 @@ typedef struct mk_rtp_server_t *mk_rtp_server; * @return */ API_EXPORT mk_rtp_server API_CALL mk_rtp_server_create(uint16_t port, int tcp_mode, const char *stream_id); +API_EXPORT mk_rtp_server API_CALL mk_rtp_server_create2(uint16_t port, int tcp_mode, const char *vhost, const char *app, const char *stream_id); /** * TCP 主动模式时连接到服务器是否成功的回调 diff --git a/api/source/mk_rtp_server.cpp b/api/source/mk_rtp_server.cpp index 487e09a8..4eca8844 100644 --- a/api/source/mk_rtp_server.cpp +++ b/api/source/mk_rtp_server.cpp @@ -18,7 +18,13 @@ using namespace mediakit; API_EXPORT mk_rtp_server API_CALL mk_rtp_server_create(uint16_t port, int tcp_mode, const char *stream_id) { RtpServer::Ptr *server = new RtpServer::Ptr(new RtpServer); - (*server)->start(port, stream_id, (RtpServer::TcpMode)tcp_mode); + (*server)->start(port, MediaTuple { DEFAULT_VHOST, kRtpAppName, stream_id, "" }, (RtpServer::TcpMode)tcp_mode); + return (mk_rtp_server)server; +} + +API_EXPORT mk_rtp_server API_CALL mk_rtp_server_create2(uint16_t port, int tcp_mode, const char *vhost, const char *app, const char *stream_id) { + RtpServer::Ptr *server = new RtpServer::Ptr(new RtpServer); + (*server)->start(port, MediaTuple { vhost, app, stream_id, "" }, (RtpServer::TcpMode)tcp_mode); return (mk_rtp_server)server; } @@ -71,6 +77,11 @@ API_EXPORT mk_rtp_server API_CALL mk_rtp_server_create(uint16_t port, int enable return nullptr; } +API_EXPORT mk_rtp_server API_CALL mk_rtp_server_create2(uint16_t port, int tcp_mode, const char *vhost, const char *app, const char *stream_id) { + WarnL << "请打开ENABLE_RTPPROXY后再编译"; + return nullptr; +} + API_EXPORT void API_CALL mk_rtp_server_release(mk_rtp_server ctx) { WarnL << "请打开ENABLE_RTPPROXY后再编译"; } diff --git a/server/WebApi.cpp b/server/WebApi.cpp index 5fbe4e19..b0b9b354 100755 --- a/server/WebApi.cpp +++ b/server/WebApi.cpp @@ -477,18 +477,19 @@ Value makeMediaSourceJson(MediaSource &media){ } #if defined(ENABLE_RTPPROXY) -uint16_t openRtpServer(uint16_t local_port, const string &stream_id, int tcp_mode, const string &local_ip, bool re_use_port, uint32_t ssrc, int only_track, bool multiplex) { - if (s_rtp_server.find(stream_id)) { - //为了防止RtpProcess所有权限混乱的问题,不允许重复添加相同的stream_id +uint16_t openRtpServer(uint16_t local_port, const mediakit::MediaTuple &tuple, int tcp_mode, const string &local_ip, bool re_use_port, uint32_t ssrc, int only_track, bool multiplex) { + auto key = tuple.shortUrl(); + if (s_rtp_server.find(key)) { + //为了防止RtpProcess所有权限混乱的问题,不允许重复添加相同的key return 0; } - auto server = s_rtp_server.makeWithAction(stream_id, [&](RtpServer::Ptr server) { - server->start(local_port, stream_id, (RtpServer::TcpMode)tcp_mode, local_ip.c_str(), re_use_port, ssrc, only_track, multiplex); + auto server = s_rtp_server.makeWithAction(key, [&](RtpServer::Ptr server) { + server->start(local_port, tuple, (RtpServer::TcpMode)tcp_mode, local_ip.c_str(), re_use_port, ssrc, only_track, multiplex); }); - server->setOnDetach([stream_id](const SockException &ex) { + server->setOnDetach([key](const SockException &ex) { //设置rtp超时移除事件 - s_rtp_server.erase(stream_id); + s_rtp_server.erase(key); }); //回复json @@ -1199,7 +1200,15 @@ void installWebApi() { api_regist("/index/api/getRtpInfo",[](API_ARGS_MAP){ CHECK_SECRET(); CHECK_ARGS("stream_id"); - auto src = MediaSource::find(DEFAULT_VHOST, kRtpAppName, allArgs["stream_id"]); + std::string vhost = DEFAULT_VHOST; + if (!allArgs["vhost"].empty()) { + vhost = allArgs["vhost"]; + } + std::string app = kRtpAppName; + if (!allArgs["app"].empty()) { + app = allArgs["app"]; + } + auto src = MediaSource::find(vhost, app, allArgs["stream_id"]); auto process = src ? src->getRtpProcess() : nullptr; if (!process) { val["exist"] = false; @@ -1212,7 +1221,16 @@ void installWebApi() { api_regist("/index/api/openRtpServer",[](API_ARGS_MAP){ CHECK_SECRET(); CHECK_ARGS("port", "stream_id"); + std::string vhost = DEFAULT_VHOST; + if (!allArgs["vhost"].empty()) { + vhost = allArgs["vhost"]; + } + std::string app = kRtpAppName; + if (!allArgs["app"].empty()) { + app = allArgs["app"]; + } auto stream_id = allArgs["stream_id"]; + auto tuple = MediaTuple { vhost, app, stream_id, "" }; auto tcp_mode = allArgs["tcp_mode"].as(); if (allArgs["enable_tcp"].as() && !tcp_mode) { //兼容老版本请求,新版本去除enable_tcp参数并新增tcp_mode参数 @@ -1227,40 +1245,50 @@ void installWebApi() { if (!allArgs["local_ip"].empty()) { local_ip = allArgs["local_ip"]; } - auto port = openRtpServer(allArgs["port"], stream_id, tcp_mode, local_ip, allArgs["re_use_port"].as(), + auto port = openRtpServer(allArgs["port"], tuple, tcp_mode, local_ip, allArgs["re_use_port"].as(), allArgs["ssrc"].as(), only_track); if (port == 0) { - throw InvalidArgsException("该stream_id已存在"); + throw InvalidArgsException("This stream already exists"); } //回复json val["port"] = port; }); - api_regist("/index/api/openRtpServerMultiplex", [](API_ARGS_MAP) { - CHECK_SECRET(); - CHECK_ARGS("port", "stream_id"); - auto stream_id = allArgs["stream_id"]; - auto tcp_mode = allArgs["tcp_mode"].as(); - if (allArgs["enable_tcp"].as() && !tcp_mode) { - // 兼容老版本请求,新版本去除enable_tcp参数并新增tcp_mode参数 - tcp_mode = 1; - } - auto only_track = allArgs["only_track"].as(); - if (allArgs["only_audio"].as()) { - // 兼容老版本请求,新版本去除only_audio参数并新增only_track参数 - only_track = 1; - } - std::string local_ip = "::"; - if (!allArgs["local_ip"].empty()) { - local_ip = allArgs["local_ip"]; - } - auto port = openRtpServer(allArgs["port"], stream_id, tcp_mode, local_ip, true, 0, only_track,true); - if (port == 0) { - throw InvalidArgsException("该stream_id已存在"); - } - // 回复json - val["port"] = port; - }); + api_regist("/index/api/openRtpServerMultiplex", [](API_ARGS_MAP) { + CHECK_SECRET(); + CHECK_ARGS("port", "stream_id"); + std::string vhost = DEFAULT_VHOST; + if (!allArgs["vhost"].empty()) { + vhost = allArgs["vhost"]; + } + std::string app = kRtpAppName; + if (!allArgs["app"].empty()) { + app = allArgs["app"]; + } + auto stream_id = allArgs["stream_id"]; + auto tuple = MediaTuple { vhost, app, stream_id, "" }; + auto tcp_mode = allArgs["tcp_mode"].as(); + if (allArgs["enable_tcp"].as() && !tcp_mode) { + // 兼容老版本请求,新版本去除enable_tcp参数并新增tcp_mode参数 + tcp_mode = 1; + } + auto only_track = allArgs["only_track"].as(); + if (allArgs["only_audio"].as()) { + // 兼容老版本请求,新版本去除only_audio参数并新增only_track参数 + only_track = 1; + } + std::string local_ip = "::"; + if (!allArgs["local_ip"].empty()) { + local_ip = allArgs["local_ip"]; + } + + auto port = openRtpServer(allArgs["port"], tuple, tcp_mode, local_ip, true, 0, only_track, true); + if (port == 0) { + throw InvalidArgsException("This stream already exists"); + } + // 回复json + val["port"] = port; + }); api_regist("/index/api/connectRtpServer", [](API_ARGS_MAP_ASYNC) { CHECK_SECRET(); @@ -1273,9 +1301,19 @@ void installWebApi() { invoker(200, headerOut, val.toStyledString()); }; - auto server = s_rtp_server.find(allArgs["stream_id"]); + std::string vhost = DEFAULT_VHOST; + if (!allArgs["vhost"].empty()) { + vhost = allArgs["vhost"]; + } + std::string app = kRtpAppName; + if (!allArgs["app"].empty()) { + app = allArgs["app"]; + } + auto stream_id = allArgs["stream_id"]; + auto tuple = MediaTuple { vhost, app, stream_id, "" }; + auto server = s_rtp_server.find(tuple.shortUrl()); if (!server) { - cb(SockException(Err_other, "未找到rtp服务")); + cb(SockException(Err_other, "can not find the stream")); return; } server->connectToServer(allArgs["dst_url"], allArgs["dst_port"], cb); @@ -1285,7 +1323,17 @@ void installWebApi() { CHECK_SECRET(); CHECK_ARGS("stream_id"); - if(s_rtp_server.erase(allArgs["stream_id"]) == 0){ + std::string vhost = DEFAULT_VHOST; + if (!allArgs["vhost"].empty()) { + vhost = allArgs["vhost"]; + } + std::string app = kRtpAppName; + if (!allArgs["app"].empty()) { + app = allArgs["app"]; + } + auto stream_id = allArgs["stream_id"]; + auto tuple = MediaTuple { vhost, app, stream_id, "" }; + if (s_rtp_server.erase(tuple.shortUrl()) == 0) { val["hit"] = 0; return; } @@ -1296,7 +1344,17 @@ void installWebApi() { CHECK_SECRET(); CHECK_ARGS("stream_id", "ssrc"); - auto server = s_rtp_server.find(allArgs["stream_id"]); + std::string vhost = DEFAULT_VHOST; + if (!allArgs["vhost"].empty()) { + vhost = allArgs["vhost"]; + } + std::string app = kRtpAppName; + if (!allArgs["app"].empty()) { + app = allArgs["app"]; + } + auto stream_id = allArgs["stream_id"]; + auto tuple = MediaTuple { vhost, app, stream_id, "" }; + auto server = s_rtp_server.find(tuple.shortUrl()); if (!server) { throw ApiRetException("RtpServer not found by stream_id", API::NotFound); } @@ -1308,8 +1366,11 @@ void installWebApi() { std::lock_guard lck(s_rtp_server._mtx); for (auto &pr : s_rtp_server._map) { + auto vec = split(pr.first, "/"); Value obj; - obj["stream_id"] = pr.first; + obj["vhost"] = vec[0]; + obj["app"] = vec[1]; + obj["stream_id"] = vec[2]; obj["port"] = pr.second->getPort(); val["data"].append(obj); } @@ -1438,8 +1499,16 @@ void installWebApi() { api_regist("/index/api/pauseRtpCheck", [](API_ARGS_MAP) { CHECK_SECRET(); CHECK_ARGS("stream_id"); + std::string vhost = DEFAULT_VHOST; + if (!allArgs["vhost"].empty()) { + vhost = allArgs["vhost"]; + } + std::string app = kRtpAppName; + if (!allArgs["app"].empty()) { + app = allArgs["app"]; + } //只是暂停流的检查,流媒体服务器做为流负载服务,收流就转发,RTSP/RTMP有自己暂停协议 - auto src = MediaSource::find(DEFAULT_VHOST, kRtpAppName, allArgs["stream_id"]); + auto src = MediaSource::find(vhost, app, allArgs["stream_id"]); auto process = src ? src->getRtpProcess() : nullptr; if (process) { process->setStopCheckRtp(true); @@ -1451,7 +1520,15 @@ void installWebApi() { api_regist("/index/api/resumeRtpCheck", [](API_ARGS_MAP) { CHECK_SECRET(); CHECK_ARGS("stream_id"); - auto src = MediaSource::find(DEFAULT_VHOST, kRtpAppName, allArgs["stream_id"]); + std::string vhost = DEFAULT_VHOST; + if (!allArgs["vhost"].empty()) { + vhost = allArgs["vhost"]; + } + std::string app = kRtpAppName; + if (!allArgs["app"].empty()) { + app = allArgs["app"]; + } + auto src = MediaSource::find(vhost, app, allArgs["stream_id"]); auto process = src ? src->getRtpProcess() : nullptr; if (process) { process->setStopCheckRtp(false); diff --git a/server/WebApi.h b/server/WebApi.h index 95562bbf..7ec1887e 100755 --- a/server/WebApi.h +++ b/server/WebApi.h @@ -202,7 +202,7 @@ void installWebApi(); void unInstallWebApi(); #if defined(ENABLE_RTPPROXY) -uint16_t openRtpServer(uint16_t local_port, const std::string &stream_id, int tcp_mode, const std::string &local_ip, bool re_use_port, uint32_t ssrc, int only_track, bool multiplex=false); +uint16_t openRtpServer(uint16_t local_port, const mediakit::MediaTuple &tuple, int tcp_mode, const std::string &local_ip, bool re_use_port, uint32_t ssrc, int only_track, bool multiplex=false); #endif Json::Value makeMediaSourceJson(mediakit::MediaSource &media); diff --git a/server/WebHook.cpp b/server/WebHook.cpp index aacee038..9e93cc9d 100755 --- a/server/WebHook.cpp +++ b/server/WebHook.cpp @@ -682,7 +682,9 @@ void installWebHook() { ArgsType body; body["local_port"] = local_port; - body["stream_id"] = stream_id; + body[VHOST_KEY] = tuple.vhost; + body["app"] = tuple.app; + body["stream_id"] = tuple.stream; body["tcp_mode"] = tcp_mode; body["re_use_port"] = re_use_port; body["ssrc"] = ssrc; diff --git a/src/Common/config.h b/src/Common/config.h index 6f9bed08..e456bdab 100644 --- a/src/Common/config.h +++ b/src/Common/config.h @@ -107,7 +107,7 @@ extern const std::string kBroadcastReloadConfig; // rtp server 超时 extern const std::string kBroadcastRtpServerTimeout; -#define BroadcastRtpServerTimeoutArgs uint16_t &local_port, const string &stream_id,int &tcp_mode, bool &re_use_port, uint32_t &ssrc +#define BroadcastRtpServerTimeoutArgs uint16_t &local_port, const MediaTuple &tuple, int &tcp_mode, bool &re_use_port, uint32_t &ssrc // rtc transport sctp 连接状态 extern const std::string kBroadcastRtcSctpConnecting; diff --git a/src/Rtp/RtpProcess.cpp b/src/Rtp/RtpProcess.cpp index 24c343ee..90f1057a 100644 --- a/src/Rtp/RtpProcess.cpp +++ b/src/Rtp/RtpProcess.cpp @@ -23,17 +23,14 @@ static constexpr size_t kMaxCachedFrameMS = 10 * 1000; namespace mediakit { -RtpProcess::Ptr RtpProcess::createProcess(std::string stream_id) { - RtpProcess::Ptr ret(new RtpProcess(std::move(stream_id))); - ret->createTimer(); - return ret; +RtpProcess::Ptr RtpProcess::createProcess(const MediaTuple &tuple) { + RtpProcess::Ptr ret(new RtpProcess(tuple)); + ret->createTimer(); + return ret; } -RtpProcess::RtpProcess(string stream_id) { - _media_info.schema = kRtpAppName; - _media_info.vhost = DEFAULT_VHOST; - _media_info.app = kRtpAppName; - _media_info.stream = std::move(stream_id); +RtpProcess::RtpProcess(const MediaTuple &tuple) { + static_cast(_media_info) = tuple; GET_CONFIG(string, dump_dir, RtpProxy::kDumpDir); { diff --git a/src/Rtp/RtpProcess.h b/src/Rtp/RtpProcess.h index 3f1509d0..855eddd4 100644 --- a/src/Rtp/RtpProcess.h +++ b/src/Rtp/RtpProcess.h @@ -25,7 +25,7 @@ public: using Ptr = std::shared_ptr; using onDetachCB = std::function; - static Ptr createProcess(std::string stream_id); + static Ptr createProcess(const MediaTuple &tuple); ~RtpProcess(); enum OnlyTrack { kAll = 0, kOnlyAudio = 1, kOnlyVideo = 2 }; @@ -91,7 +91,7 @@ protected: bool close(mediakit::MediaSource &sender) override; private: - RtpProcess(std::string stream_id); + RtpProcess(const MediaTuple &tuple); void emitOnPublish(); void doCachedFunc(); diff --git a/src/Rtp/RtpServer.cpp b/src/Rtp/RtpServer.cpp index bcf1675d..01afff7c 100644 --- a/src/Rtp/RtpServer.cpp +++ b/src/Rtp/RtpServer.cpp @@ -30,18 +30,18 @@ class RtcpHelper: public std::enable_shared_from_this { public: using Ptr = std::shared_ptr; - RtcpHelper(Socket::Ptr rtcp_sock, std::string stream_id) { + RtcpHelper(Socket::Ptr rtcp_sock, MediaTuple tuple) { _rtcp_sock = std::move(rtcp_sock); - _stream_id = std::move(stream_id); + _tuple = std::move(tuple); } void setRtpServerInfo(uint16_t local_port, RtpServer::TcpMode mode, bool re_use_port, uint32_t ssrc, int only_track) { _ssrc = ssrc; - _process = RtpProcess::createProcess(_stream_id); + _process = RtpProcess::createProcess(_tuple); _process->setOnlyTrack((RtpProcess::OnlyTrack)only_track); _timeout_cb = [=]() mutable { - NOTICE_EMIT(BroadcastRtpServerTimeoutArgs, Broadcast::kBroadcastRtpServerTimeout, local_port, _stream_id, (int)mode, re_use_port, ssrc); + NOTICE_EMIT(BroadcastRtpServerTimeoutArgs, Broadcast::kBroadcastRtpServerTimeout, local_port, _tuple, (int)mode, re_use_port, ssrc); }; weak_ptr weak_self = shared_from_this(); @@ -117,12 +117,12 @@ private: Ticker _ticker; Socket::Ptr _rtcp_sock; RtpProcess::Ptr _process; - std::string _stream_id; + MediaTuple _tuple; RtpProcess::onDetachCB _on_detach; std::shared_ptr _rtcp_addr; }; -void RtpServer::start(uint16_t local_port, const string &stream_id, TcpMode tcp_mode, const char *local_ip, bool re_use_port, uint32_t ssrc, int only_track, bool multiplex) { +void RtpServer::start(uint16_t local_port, const MediaTuple &tuple, TcpMode tcp_mode, const char *local_ip, bool re_use_port, uint32_t ssrc, int only_track, bool multiplex) { //创建udp服务器 auto poller = EventPollerPool::Instance().getPoller(); Socket::Ptr rtp_socket = Socket::createSocket(poller, true); @@ -148,9 +148,9 @@ void RtpServer::start(uint16_t local_port, const string &stream_id, TcpMode tcp_ UdpServer::Ptr udp_server; RtcpHelper::Ptr helper; //增加了多路复用判断,如果多路复用为true,就走else逻辑,同时保留了原来stream_id为空走else逻辑 - if (!stream_id.empty() && !multiplex) { + if (!tuple.stream.empty() && !multiplex) { //指定了流id,那么一个端口一个流(不管是否包含多个ssrc的多个流,绑定rtp源后,会筛选掉ip端口不匹配的流) - helper = std::make_shared(std::move(rtcp_socket), stream_id); + helper = std::make_shared(std::move(rtcp_socket), tuple); helper->startRtcp(); helper->setRtpServerInfo(local_port, tcp_mode, re_use_port, ssrc, only_track); bool bind_peer_addr = false; @@ -185,7 +185,9 @@ void RtpServer::start(uint16_t local_port, const string &stream_id, TcpMode tcp_ auto processor = helper ? helper->getProcess() : nullptr; // 如果共享同一个processor对象,那么tcp server深圳为单线程模式确保线程安全 tcp_server = std::make_shared(processor ? poller : nullptr); - (*tcp_server)[RtpSession::kStreamID] = stream_id; + (*tcp_server)[RtpSession::kVhost] = tuple.vhost; + (*tcp_server)[RtpSession::kApp] = tuple.app; + (*tcp_server)[RtpSession::kStreamID] = tuple.stream; (*tcp_server)[RtpSession::kSSRC] = ssrc; (*tcp_server)[RtpSession::kOnlyTrack] = only_track; if (tcp_mode == PASSIVE) { @@ -193,13 +195,13 @@ void RtpServer::start(uint16_t local_port, const string &stream_id, TcpMode tcp_ tcp_server->start(local_port, local_ip, 1024, [weak_self, processor](std::shared_ptr &session) { session->setRtpProcess(processor); }); - } else if (stream_id.empty()) { + } else if (tuple.stream.empty()) { // tcp主动模式时只能一个端口一个流,必须指定流id; 创建TcpServer对象也仅用于传参 throw std::runtime_error(StrPrinter << "tcp主动模式时必需指定流id"); } } - _on_cleanup = [rtp_socket, stream_id]() { + _on_cleanup = [rtp_socket]() { if (rtp_socket) { //去除循环引用 rtp_socket->setOnRead(nullptr); diff --git a/src/Rtp/RtpServer.h b/src/Rtp/RtpServer.h index 06a1d550..70af06de 100644 --- a/src/Rtp/RtpServer.h +++ b/src/Rtp/RtpServer.h @@ -43,7 +43,7 @@ public: * @param ssrc 指定的ssrc * @param multiplex 多路复用 */ - void start(uint16_t local_port, const std::string &stream_id = "", TcpMode tcp_mode = PASSIVE, + void start(uint16_t local_port, const MediaTuple &tuple = MediaTuple{DEFAULT_VHOST, kRtpAppName, "", ""}, TcpMode tcp_mode = PASSIVE, const char *local_ip = "::", bool re_use_port = true, uint32_t ssrc = 0, int only_track = 0, bool multiplex = false); /** diff --git a/src/Rtp/RtpSession.cpp b/src/Rtp/RtpSession.cpp index 852a8796..6b68388d 100644 --- a/src/Rtp/RtpSession.cpp +++ b/src/Rtp/RtpSession.cpp @@ -21,6 +21,8 @@ using namespace toolkit; namespace mediakit{ +const string RtpSession::kVhost = "vhost"; +const string RtpSession::kApp = "app"; const string RtpSession::kStreamID = "stream_id"; const string RtpSession::kSSRC = "ssrc"; const string RtpSession::kOnlyTrack = "only_track"; @@ -31,7 +33,9 @@ void RtpSession::attachServer(const Server &server) { } void RtpSession::setParams(mINI &ini) { - _stream_id = ini[kStreamID]; + _tuple.vhost = ini[kVhost]; + _tuple.app = ini[kApp]; + _tuple.stream = ini[kStreamID]; _ssrc = ini[kSSRC]; _only_track = ini[kOnlyTrack]; int udp_socket_buffer = ini[kUdpRecvBuffer]; @@ -63,7 +67,7 @@ void RtpSession::onError(const SockException &err) { if (_emit_detach) { _process->onDetach(err); } - WarnP(this) << _stream_id << " " << err; + WarnP(this) << _tuple.shortUrl() << " " << err; } void RtpSession::onManager() { @@ -107,12 +111,12 @@ void RtpSession::onRtpPacket(const char *data, size_t len) { } // 未指定流id就使用ssrc为流id - if (_stream_id.empty()) { - _stream_id = printSSRC(_ssrc); + if (_tuple.stream.empty()) { + _tuple.stream = printSSRC(_ssrc); } if (!_process) { - _process = RtpProcess::createProcess(_stream_id); + _process = RtpProcess::createProcess(_tuple); _process->setOnlyTrack((RtpProcess::OnlyTrack)_only_track); weak_ptr weak_self = static_pointer_cast(shared_from_this()); _process->setOnDetach([weak_self](const SockException &ex) { diff --git a/src/Rtp/RtpSession.h b/src/Rtp/RtpSession.h index 1d7fbcb3..659c816f 100644 --- a/src/Rtp/RtpSession.h +++ b/src/Rtp/RtpSession.h @@ -22,6 +22,8 @@ namespace mediakit{ class RtpSession : public toolkit::Session, public RtpSplitter { public: + static const std::string kVhost; + static const std::string kApp; static const std::string kStreamID; static const std::string kSSRC; static const std::string kOnlyTrack; @@ -54,7 +56,7 @@ private: int _only_track = 0; uint32_t _ssrc = 0; toolkit::Ticker _ticker; - std::string _stream_id; + MediaTuple _tuple; struct sockaddr_storage _addr; RtpProcess::Ptr _process; };