diff --git a/api/source/mk_common.cpp b/api/source/mk_common.cpp index 0430e685..b6d99cf7 100644 --- a/api/source/mk_common.cpp +++ b/api/source/mk_common.cpp @@ -305,7 +305,7 @@ API_EXPORT void API_CALL mk_webrtc_get_answer_sdp2(void *user_data, on_user_data auto session = std::make_shared(Socket::createSocket()); std::string offer_str = offer; std::shared_ptr ptr(user_data, user_data_free ? user_data_free : [](void *) {}); - WebRtcPluginManager::Instance().getAnswerSdp(*session, type, WebRtcArgsUrl(url), + WebRtcPluginManager::Instance().handleRtcPlugin(*session, type, WebRtcArgsUrl(url), [offer_str, session, ptr, cb](const WebRtcInterface &exchanger) mutable { try { auto sdp_answer = const_cast(exchanger).getAnswerSdp(offer_str); diff --git a/server/WebApi.cpp b/server/WebApi.cpp index 887b1736..9df2e530 100755 --- a/server/WebApi.cpp +++ b/server/WebApi.cpp @@ -1591,29 +1591,47 @@ void installWebApi() { api_regist("/index/api/webrtc",[](API_ARGS_STRING_ASYNC){ CHECK_ARGS("type"); auto type = allArgs["type"]; - auto offer = allArgs.getArgs(); - CHECK(!offer.empty(), "http body(webrtc offer sdp) is empty"); - WebRtcPluginManager::Instance().getAnswerSdp(*(static_cast(&sender)), type, - WebRtcArgsImp(allArgs, sender.getIdentifier()), - [invoker, val, offer, headerOut](const WebRtcInterface &exchanger) mutable { - //设置返回类型 - headerOut["Content-Type"] = HttpFileManager::getContentType(".json"); - //设置跨域 - headerOut["Access-Control-Allow-Origin"] = "*"; + if(type == "stop") { + WebRtcPluginManager::Instance().handleRtcPlugin( + *(static_cast(&sender)), type, WebRtcArgsImp(allArgs, sender.getIdentifier()), + [invoker, val, headerOut](const WebRtcInterface &exchanger) mutable { + try { + std::string tmp = ""; + const_cast(exchanger).getAnswerSdp(tmp); - try { - val["sdp"] = const_cast(exchanger).getAnswerSdp(offer); - val["id"] = exchanger.getIdentifier(); - val["type"] = "answer"; - invoker(200, headerOut, val.toStyledString()); - } catch (std::exception &ex) { - val["code"] = API::Exception; - val["msg"] = ex.what(); - invoker(200, headerOut, val.toStyledString()); - } - }); - }); + } catch (std::exception &ex) { + val["code"] = const_cast(exchanger).getErrcode(); + val["msg"] = ex.what(); + invoker(200, headerOut, val.toStyledString()); + } + }); + + }else{ + + auto offer = allArgs.getArgs(); + CHECK(!offer.empty(), "http body(webrtc offer sdp) is empty"); + + WebRtcPluginManager::Instance().handleRtcPlugin(*(static_cast(&sender)), type, + WebRtcArgsImp(allArgs, sender.getIdentifier()), + [invoker, val, offer, headerOut](const WebRtcInterface &exchanger) mutable { + //设置返回类型 + headerOut["Content-Type"] = HttpFileManager::getContentType(".json"); + //设置跨域 + headerOut["Access-Control-Allow-Origin"] = "*"; + + try { + val["sdp"] = const_cast(exchanger).getAnswerSdp(offer); + val["id"] = exchanger.getIdentifier(); + val["type"] = "answer"; + invoker(200, headerOut, val.toStyledString()); + } catch (std::exception &ex) { + val["code"] = API::Exception; + val["msg"] = ex.what(); + invoker(200, headerOut, val.toStyledString()); + } + }); + }}); #endif #if defined(ENABLE_VERSION) diff --git a/webrtc/WebRtcTransport.cpp b/webrtc/WebRtcTransport.cpp index cb579118..863c775f 100644 --- a/webrtc/WebRtcTransport.cpp +++ b/webrtc/WebRtcTransport.cpp @@ -1130,7 +1130,7 @@ void WebRtcPluginManager::registerPlugin(const string &type, Plugin cb) { _map_creator[type] = std::move(cb); } -void WebRtcPluginManager::getAnswerSdp(Session &sender, const string &type, const WebRtcArgs &args, const onCreateRtc &cb) { +void WebRtcPluginManager::handleRtcPlugin(Session &sender, const string &type, const WebRtcArgs &args, const onRtcEvent &cb) { lock_guard lck(_mtx_creator); auto it = _map_creator.find(type); if (it == _map_creator.end()) { @@ -1140,11 +1140,31 @@ void WebRtcPluginManager::getAnswerSdp(Session &sender, const string &type, cons it->second(sender, args, cb); } -void echo_plugin(Session &sender, const WebRtcArgs &args, const WebRtcPluginManager::onCreateRtc &cb) { +void echo_plugin(Session &sender, const WebRtcArgs &args, const WebRtcPluginManager::onRtcEvent &cb) { cb(*WebRtcEchoTest::create(EventPollerPool::Instance().getPoller())); } -void push_plugin(Session &sender, const WebRtcArgs &args, const WebRtcPluginManager::onCreateRtc &cb) { +void stop_plugin(Session &sender, const WebRtcArgs &args, const WebRtcPluginManager::onRtcEvent &cb) { + MediaInfo info(args["url"]); + std::string id = args["id"]; + + bool push_exist = (bool)MediaSource::find(RTSP_SCHEMA, info._vhost, info._app, info._streamid); + if(!push_exist){ + cb(WebRtcException(SockException(Err_other, "cannot find media source"))); + return; + } + + auto rtc = WebRtcTransportManager::Instance().getItem(id); + if(!rtc){ + cb(WebRtcException(SockException(Err_other, "cannot find rtc transport"))); + return; + } + rtc->onShutdown(SockException(Err_shutdown, "http(signal) close notify received")); + cb(WebRtcException(SockException(Err_success, "success"))); + +} + +void push_plugin(Session &sender, const WebRtcArgs &args, const WebRtcPluginManager::onRtcEvent &cb) { MediaInfo info(args["url"]); bool preferred_tcp = args["preferred_tcp"]; @@ -1200,7 +1220,7 @@ void push_plugin(Session &sender, const WebRtcArgs &args, const WebRtcPluginMana } } -void play_plugin(Session &sender, const WebRtcArgs &args, const WebRtcPluginManager::onCreateRtc &cb) { +void play_plugin(Session &sender, const WebRtcArgs &args, const WebRtcPluginManager::onRtcEvent &cb) { MediaInfo info(args["url"]); bool preferred_tcp = args["preferred_tcp"]; @@ -1238,6 +1258,7 @@ static onceToken s_rtc_auto_register([]() { WebRtcPluginManager::Instance().registerPlugin("echo", echo_plugin); WebRtcPluginManager::Instance().registerPlugin("push", push_plugin); WebRtcPluginManager::Instance().registerPlugin("play", play_plugin); + WebRtcPluginManager::Instance().registerPlugin("stop", stop_plugin); }); }// namespace mediakit \ No newline at end of file diff --git a/webrtc/WebRtcTransport.h b/webrtc/WebRtcTransport.h index 30fa5a8b..e9fde234 100644 --- a/webrtc/WebRtcTransport.h +++ b/webrtc/WebRtcTransport.h @@ -40,6 +40,7 @@ public: WebRtcInterface() = default; virtual ~WebRtcInterface() = default; virtual std::string getAnswerSdp(const std::string &offer) = 0; + virtual int getErrcode(){return 0;} virtual const std::string &getIdentifier() const = 0; }; @@ -50,6 +51,11 @@ public: std::string getAnswerSdp(const std::string &offer) override { throw _ex; } + + int getErrcode() override { + return _ex.getErrCode(); + } + const std::string &getIdentifier() const override { static std::string s_null; return s_null; @@ -246,6 +252,8 @@ public: void createRtpChannel(const std::string &rid, uint32_t ssrc, MediaTrack &track); void removeTuple(RTC::TransportTuple* tuple); + void onShutdown(const SockException &ex) override; + protected: void OnIceServerSelectedTuple(const RTC::IceServer *iceServer, RTC::TransportTuple *tuple) override; WebRtcTransportImp(const EventPoller::Ptr &poller,bool preferred_tcp = false); @@ -261,7 +269,6 @@ protected: void onBeforeEncryptRtcp(const char *buf, int &len, void *ctx) override {}; void onCreate() override; void onDestory() override; - void onShutdown(const SockException &ex) override; virtual void onRecvRtp(MediaTrack &track, const std::string &rid, RtpPacket::Ptr rtp) = 0; void updateTicker(); float getLossRate(TrackType type); @@ -325,13 +332,13 @@ public: class WebRtcPluginManager { public: - using onCreateRtc = std::function; - using Plugin = std::function; + using onRtcEvent = std::function; + using Plugin = std::function; static WebRtcPluginManager &Instance(); void registerPlugin(const std::string &type, Plugin cb); - void getAnswerSdp(Session &sender, const std::string &type, const WebRtcArgs &args, const onCreateRtc &cb); + void handleRtcPlugin(Session &sender, const std::string &type, const WebRtcArgs &args, const onRtcEvent &cb); private: WebRtcPluginManager() = default;