支持http api动态添加或关闭rtp服务器

This commit is contained in:
xiongziliang 2020-07-02 22:23:43 +08:00
parent 236219c589
commit b603b8a68d
7 changed files with 181 additions and 115 deletions

View File

@ -30,10 +30,8 @@ static TcpServer::Ptr http_server[2];
static TcpServer::Ptr shell_server; static TcpServer::Ptr shell_server;
#ifdef ENABLE_RTPPROXY #ifdef ENABLE_RTPPROXY
#include "Rtp/UdpRecver.h" #include "Rtp/RtpServer.h"
#include "Rtp/RtpSession.h" static std::shared_ptr<RtpServer> rtpServer;
static std::shared_ptr<UdpRecver> udpRtpServer;
static TcpServer::Ptr tcpRtpServer;
#endif #endif
//////////////////////////environment init/////////////////////////// //////////////////////////environment init///////////////////////////
@ -57,8 +55,7 @@ API_EXPORT void API_CALL mk_stop_all_server(){
CLEAR_ARR(rtmp_server); CLEAR_ARR(rtmp_server);
CLEAR_ARR(http_server); CLEAR_ARR(http_server);
#ifdef ENABLE_RTPPROXY #ifdef ENABLE_RTPPROXY
udpRtpServer = nullptr; rtpServer = nullptr;
tcpRtpServer = nullptr;
#endif #endif
stopAllTcpServer(); stopAllTcpServer();
} }
@ -184,18 +181,12 @@ API_EXPORT uint16_t API_CALL mk_rtmp_server_start(uint16_t port, int ssl) {
API_EXPORT uint16_t API_CALL mk_rtp_server_start(uint16_t port){ API_EXPORT uint16_t API_CALL mk_rtp_server_start(uint16_t port){
#ifdef ENABLE_RTPPROXY #ifdef ENABLE_RTPPROXY
try { try {
//创建rtp tcp服务器 //创建rtp 服务器
tcpRtpServer = std::make_shared<TcpServer>(); rtpServer = std::make_shared<RtpServer>();
tcpRtpServer->start<RtpSession>(port); rtpServer->start(port);
return rtpServer->getPort();
//创建rtp udp服务器
auto ret = tcpRtpServer->getPort();
udpRtpServer = std::make_shared<UdpRecver>();
udpRtpServer->initSock(port);
return ret;
} catch (std::exception &ex) { } catch (std::exception &ex) {
tcpRtpServer.reset(); rtpServer.reset();
udpRtpServer.reset();
WarnL << ex.what(); WarnL << ex.what();
return 0; return 0;
} }

View File

@ -34,6 +34,9 @@
#include "Thread/WorkThreadPool.h" #include "Thread/WorkThreadPool.h"
#include "Rtp/RtpSelector.h" #include "Rtp/RtpSelector.h"
#include "FFmpegSource.h" #include "FFmpegSource.h"
#if defined(ENABLE_RTPPROXY)
#include "Rtp/RtpServer.h"
#endif
using namespace Json; using namespace Json;
using namespace toolkit; using namespace toolkit;
using namespace mediakit; using namespace mediakit;
@ -244,15 +247,24 @@ bool checkArgs(Args &&args,First &&first,KeyTypes && ...keys){
} \ } \
} }
//拉流代理器列表
static unordered_map<string ,PlayerProxy::Ptr> s_proxyMap; static unordered_map<string ,PlayerProxy::Ptr> s_proxyMap;
static recursive_mutex s_proxyMapMtx; static recursive_mutex s_proxyMapMtx;
//FFmpeg拉流代理器列表
static unordered_map<string ,FFmpegSource::Ptr> s_ffmpegMap;
static recursive_mutex s_ffmpegMapMtx;
#if defined(ENABLE_RTPPROXY)
//rtp服务器列表
static unordered_map<uint16_t, RtpServer::Ptr> s_rtpServerMap;
static recursive_mutex s_rtpServerMapMtx;
#endif
static inline string getProxyKey(const string &vhost,const string &app,const string &stream){ static inline string getProxyKey(const string &vhost,const string &app,const string &stream){
return vhost + "/" + app + "/" + stream; return vhost + "/" + app + "/" + stream;
} }
static unordered_map<string ,FFmpegSource::Ptr> s_ffmpegMap;
static recursive_mutex s_ffmpegMapMtx;
/** /**
* api接口 * api接口
* api都支持GET和POST两种方式 * api都支持GET和POST两种方式
@ -745,6 +757,29 @@ void installWebApi() {
val["peer_ip"] = process->get_peer_ip(); val["peer_ip"] = process->get_peer_ip();
val["peer_port"] = process->get_peer_port(); val["peer_port"] = process->get_peer_port();
}); });
api_regist1("/index/api/openRtpServer",[](API_ARGS1){
CHECK_SECRET();
CHECK_ARGS("port", "enable_tcp");
RtpServer::Ptr server = std::make_shared<RtpServer>();
server->start(allArgs["port"], allArgs["enable_tcp"].as<bool>());
val["port"] = server->getPort();
//保存对象
lock_guard<recursive_mutex> lck(s_rtpServerMapMtx);
s_rtpServerMap.emplace(server->getPort(), server);
});
api_regist1("/index/api/closeRtpServer",[](API_ARGS1){
CHECK_SECRET();
CHECK_ARGS("port");
lock_guard<recursive_mutex> lck(s_rtpServerMapMtx);
val["hit"] = (int)s_rtpServerMap.erase(allArgs["port"].as<uint16_t>());
});
#endif//ENABLE_RTPPROXY #endif//ENABLE_RTPPROXY
// 开始录制hls或MP4 // 开始录制hls或MP4
@ -1045,4 +1080,10 @@ void unInstallWebApi(){
lock_guard<recursive_mutex> lck(s_ffmpegMapMtx); lock_guard<recursive_mutex> lck(s_ffmpegMapMtx);
s_ffmpegMap.clear(); s_ffmpegMap.clear();
} }
{
#if defined(ENABLE_RTPPROXY)
lock_guard<recursive_mutex> lck(s_rtpServerMapMtx);
s_rtpServerMap.clear();
#endif
}
} }

View File

@ -20,13 +20,11 @@
#include "Network/TcpServer.h" #include "Network/TcpServer.h"
#include "Poller/EventPoller.h" #include "Poller/EventPoller.h"
#include "Common/config.h" #include "Common/config.h"
#include "Rtsp/UDPServer.h"
#include "Rtsp/RtspSession.h" #include "Rtsp/RtspSession.h"
#include "Rtp/RtpSession.h"
#include "Rtmp/RtmpSession.h" #include "Rtmp/RtmpSession.h"
#include "Shell/ShellSession.h" #include "Shell/ShellSession.h"
#include "Http/WebSocketSession.h" #include "Http/WebSocketSession.h"
#include "Rtp/UdpRecver.h" #include "Rtp/RtpServer.h"
#include "WebApi.h" #include "WebApi.h"
#include "WebHook.h" #include "WebHook.h"
@ -283,8 +281,7 @@ int start_main(int argc,char *argv[]) {
#if defined(ENABLE_RTPPROXY) #if defined(ENABLE_RTPPROXY)
//GB28181 rtp推流端口支持UDP/TCP //GB28181 rtp推流端口支持UDP/TCP
UdpRecver recver; RtpServer::Ptr rtpServer = std::make_shared<RtpServer>();
TcpServer::Ptr tcpRtpServer(new TcpServer());
#endif//defined(ENABLE_RTPPROXY) #endif//defined(ENABLE_RTPPROXY)
try { try {
@ -307,12 +304,8 @@ int start_main(int argc,char *argv[]) {
if(shellPort) { shellSrv->start<ShellSession>(shellPort); } if(shellPort) { shellSrv->start<ShellSession>(shellPort); }
#if defined(ENABLE_RTPPROXY) #if defined(ENABLE_RTPPROXY)
if(rtpPort){ //创建rtp服务器
//创建rtp udp服务器 if(rtpPort){ rtpServer->start(rtpPort); }
recver.initSock(rtpPort);
//创建rtp tcp服务器
tcpRtpServer->start<RtpSession>(rtpPort);
}
#endif//defined(ENABLE_RTPPROXY) #endif//defined(ENABLE_RTPPROXY)
}catch (std::exception &ex){ }catch (std::exception &ex){

64
src/Rtp/RtpServer.cpp Normal file
View File

@ -0,0 +1,64 @@
/*
* Copyright (c) 2016 The ZLMediaKit project authors. All Rights Reserved.
*
* This file is part of ZLMediaKit(https://github.com/xiongziliang/ZLMediaKit).
*
* Use of this source code is governed by MIT license that can be found in the
* LICENSE file in the root of the source tree. All contributing project authors
* may be found in the AUTHORS file in the root of the source tree.
*/
#if defined(ENABLE_RTPPROXY)
#include "RtpServer.h"
#include "RtpSelector.h"
namespace mediakit{
RtpServer::RtpServer() {
}
RtpServer::~RtpServer() {
if(_udp_server){
_udp_server->setOnRead(nullptr);
}
}
void RtpServer::start(uint16_t local_port, bool enable_tcp, const char *local_ip) {
_udp_server.reset(new Socket(nullptr, false));
auto &ref = RtpSelector::Instance();
auto sock = _udp_server;
_udp_server->setOnRead([&ref, sock](const Buffer::Ptr &buf, struct sockaddr *addr, int) {
ref.inputRtp(sock, buf->data(), buf->size(), addr);
});
//创建udp服务器
if (!_udp_server->bindUdpSock(local_port, local_ip)) {
_udp_server = nullptr;
string err = (StrPrinter << "bindUdpSock on " << local_ip << ":" << local_port << " failed:" << get_uv_errmsg(true));
throw std::runtime_error(err);
}
//设置udp socket读缓存
SockUtil::setRecvBuf(_udp_server->rawFD(), 4 * 1024 * 1024);
if (enable_tcp) {
try {
//创建tcp服务器
_tcp_server = std::make_shared<TcpServer>(_udp_server->getPoller());
_tcp_server->start<RtpSession>(_udp_server->get_local_port(), local_ip);
} catch (...) {
_tcp_server = nullptr;
_udp_server = nullptr;
throw;
}
}
}
EventPoller::Ptr RtpServer::getPoller() {
return _udp_server->getPoller();
}
uint16_t RtpServer::getPort() {
return _udp_server ? _udp_server->get_local_port() : 0;
}
}//namespace mediakit
#endif//defined(ENABLE_RTPPROXY)

61
src/Rtp/RtpServer.h Normal file
View File

@ -0,0 +1,61 @@
/*
* Copyright (c) 2016 The ZLMediaKit project authors. All Rights Reserved.
*
* This file is part of ZLMediaKit(https://github.com/xiongziliang/ZLMediaKit).
*
* Use of this source code is governed by MIT license that can be found in the
* LICENSE file in the root of the source tree. All contributing project authors
* may be found in the AUTHORS file in the root of the source tree.
*/
#ifndef ZLMEDIAKIT_RTPSERVER_H
#define ZLMEDIAKIT_RTPSERVER_H
#if defined(ENABLE_RTPPROXY)
#include <memory>
#include "Network/Socket.h"
#include "Network/TcpServer.h"
#include "RtpSession.h"
using namespace std;
using namespace toolkit;
namespace mediakit{
/**
* RTP服务器UDP/TCP
*/
class RtpServer {
public:
typedef std::shared_ptr<RtpServer> Ptr;
typedef function<void(const Buffer::Ptr &buf)> onRecv;
RtpServer();
~RtpServer();
/**
*
* @param local_port 0
* @param enable_tcp tcp服务器
* @param local_ip ip
*/
void start(uint16_t local_port, bool enable_tcp = true, const char *local_ip = "0.0.0.0");
/**
*
*/
uint16_t getPort();
/**
* 线
*/
EventPoller::Ptr getPoller();
protected:
Socket::Ptr _udp_server;
TcpServer::Ptr _tcp_server;
};
}//namespace mediakit
#endif//defined(ENABLE_RTPPROXY)
#endif //ZLMEDIAKIT_RTPSERVER_H

View File

@ -1,44 +0,0 @@
/*
* Copyright (c) 2016 The ZLMediaKit project authors. All Rights Reserved.
*
* This file is part of ZLMediaKit(https://github.com/xiongziliang/ZLMediaKit).
*
* Use of this source code is governed by MIT license that can be found in the
* LICENSE file in the root of the source tree. All contributing project authors
* may be found in the AUTHORS file in the root of the source tree.
*/
#if defined(ENABLE_RTPPROXY)
#include "UdpRecver.h"
#include "RtpSelector.h"
namespace mediakit{
UdpRecver::UdpRecver() {
}
UdpRecver::~UdpRecver() {
if(_sock){
_sock->setOnRead(nullptr);
}
}
bool UdpRecver::initSock(uint16_t local_port,const char *local_ip) {
_sock.reset(new Socket(nullptr, false));
onceToken token(nullptr,[&](){
SockUtil::setRecvBuf(_sock->rawFD(),4 * 1024 * 1024);
});
auto &ref = RtpSelector::Instance();
auto sock = _sock;
_sock->setOnRead([&ref, sock](const Buffer::Ptr &buf, struct sockaddr *addr, int ){
ref.inputRtp(sock, buf->data(),buf->size(),addr);
});
return _sock->bindUdpSock(local_port,local_ip);
}
EventPoller::Ptr UdpRecver::getPoller() {
return _sock->getPoller();
}
}//namespace mediakit
#endif//defined(ENABLE_RTPPROXY)

View File

@ -1,40 +0,0 @@
/*
* Copyright (c) 2016 The ZLMediaKit project authors. All Rights Reserved.
*
* This file is part of ZLMediaKit(https://github.com/xiongziliang/ZLMediaKit).
*
* Use of this source code is governed by MIT license that can be found in the
* LICENSE file in the root of the source tree. All contributing project authors
* may be found in the AUTHORS file in the root of the source tree.
*/
#ifndef ZLMEDIAKIT_UDPRECVER_H
#define ZLMEDIAKIT_UDPRECVER_H
#if defined(ENABLE_RTPPROXY)
#include <memory>
#include "Network/Socket.h"
using namespace std;
using namespace toolkit;
namespace mediakit{
/**
*
*/
class UdpRecver {
public:
typedef std::shared_ptr<UdpRecver> Ptr;
typedef function<void(const Buffer::Ptr &buf)> onRecv;
UdpRecver();
virtual ~UdpRecver();
bool initSock(uint16_t local_port,const char *local_ip = "0.0.0.0");
EventPoller::Ptr getPoller();
protected:
Socket::Ptr _sock;
};
}//namespace mediakit
#endif//defined(ENABLE_RTPPROXY)
#endif //ZLMEDIAKIT_UDPRECVER_H