新增openRtpServerMultiplex接口,支持创建多路复用RTP服务器端口 (#2954)

#2953
This commit is contained in:
waken 2023-11-09 11:26:13 +08:00 committed by GitHub
parent f8285a3f6c
commit 6888f20d74
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 78 additions and 10 deletions

View File

@ -1,9 +1,10 @@
{ {
"info": { "info": {
"_postman_id": "39e8a1df-cc8e-4e3f-bf5e-197c86e7bf0f", "_postman_id": "509e5f6b-728c-4d5f-b3e8-521d76b2cc7a",
"name": "ZLMediaKit", "name": "ZLMediaKit",
"description": "媒体服务器", "description": "媒体服务器",
"schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json" "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json",
"_exporter_id": "29185956"
}, },
"item": [ "item": [
{ {
@ -918,7 +919,7 @@
"method": "GET", "method": "GET",
"header": [], "header": [],
"url": { "url": {
"raw": "{{ZLMediaKit_URL}}/index/api/broadcastMessage?secret={{ZLMediaKit_secret}}&schema=rtsp&vhost={{defaultVhost}}&app=live&stream=test&msg=Hello zlmediakit123", "raw": "{{ZLMediaKit_URL}}/index/api/broadcastMessage?secret={{ZLMediaKit_secret}}&schema=rtsp&vhost={{defaultVhost}}&app=live&stream=test&msg=Hello ZLMediakit",
"host": [ "host": [
"{{ZLMediaKit_URL}}" "{{ZLMediaKit_URL}}"
], ],
@ -1247,7 +1248,7 @@
}, },
{ {
"key": "stamp", "key": "stamp",
"value": 1000, "value": "1000",
"description": "要设置的录像播放位置" "description": "要设置的录像播放位置"
} }
] ]
@ -1478,6 +1479,53 @@
}, },
"response": [] "response": []
}, },
{
"name": "创建多路复用RTP服务器(openRtpServerMultiplex)",
"request": {
"method": "GET",
"header": [],
"url": {
"raw": "{{ZLMediaKit_URL}}/index/api/openRtpServer?secret={{ZLMediaKit_secret}}&port=0&tcp_mode=1&stream_id=test",
"host": [
"{{ZLMediaKit_URL}}"
],
"path": [
"index",
"api",
"openRtpServer"
],
"query": [
{
"key": "secret",
"value": "{{ZLMediaKit_secret}}",
"description": "api操作密钥(配置文件配置)"
},
{
"key": "port",
"value": "0",
"description": "绑定的端口0时为随机端口"
},
{
"key": "tcp_mode",
"value": "1",
"description": "tcp模式0时为不启用tcp监听1时为启用tcp监听"
},
{
"key": "stream_id",
"value": "test",
"description": "该端口绑定的流id\n"
},
{
"key": "only_audio",
"value": "0",
"description": "是否为单音频track用于语音对讲",
"disabled": true
}
]
}
},
"response": []
},
{ {
"name": "连接RTP服务器(connectRtpServer)", "name": "连接RTP服务器(connectRtpServer)",
"request": { "request": {

View File

@ -404,7 +404,7 @@ Value makeMediaSourceJson(MediaSource &media){
} }
#if defined(ENABLE_RTPPROXY) #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, bool only_audio) { 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, bool only_audio, bool multiplex) {
lock_guard<recursive_mutex> lck(s_rtpServerMapMtx); lock_guard<recursive_mutex> lck(s_rtpServerMapMtx);
if (s_rtpServerMap.find(stream_id) != s_rtpServerMap.end()) { if (s_rtpServerMap.find(stream_id) != s_rtpServerMap.end()) {
//为了防止RtpProcess所有权限混乱的问题不允许重复添加相同的stream_id //为了防止RtpProcess所有权限混乱的问题不允许重复添加相同的stream_id
@ -412,7 +412,7 @@ uint16_t openRtpServer(uint16_t local_port, const string &stream_id, int tcp_mod
} }
RtpServer::Ptr server = std::make_shared<RtpServer>(); RtpServer::Ptr server = std::make_shared<RtpServer>();
server->start(local_port, stream_id, (RtpServer::TcpMode)tcp_mode, local_ip.c_str(), re_use_port, ssrc, only_audio); server->start(local_port, stream_id, (RtpServer::TcpMode)tcp_mode, local_ip.c_str(), re_use_port, ssrc, only_audio, multiplex);
server->setOnDetach([stream_id]() { server->setOnDetach([stream_id]() {
//设置rtp超时移除事件 //设置rtp超时移除事件
lock_guard<recursive_mutex> lck(s_rtpServerMapMtx); lock_guard<recursive_mutex> lck(s_rtpServerMapMtx);
@ -1182,6 +1182,24 @@ void installWebApi() {
//回复json //回复json
val["port"] = port; val["port"] = port;
}); });
api_regist("/media/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<int>();
if (allArgs["enable_tcp"].as<int>() && !tcp_mode) {
// 兼容老版本请求新版本去除enable_tcp参数并新增tcp_mode参数
tcp_mode = 1;
}
auto port = openRtpServer(
allArgs["port"], stream_id, tcp_mode, "::", true, 0, allArgs["only_audio"].as<bool>(),true);
if (port == 0) {
throw InvalidArgsException("该stream_id已存在");
}
// 回复json
val["port"] = port;
});
api_regist("/index/api/connectRtpServer", [](API_ARGS_MAP_ASYNC) { api_regist("/index/api/connectRtpServer", [](API_ARGS_MAP_ASYNC) {
CHECK_SECRET(); CHECK_SECRET();

View File

@ -239,7 +239,7 @@ void installWebApi();
void unInstallWebApi(); void unInstallWebApi();
#if defined(ENABLE_RTPPROXY) #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, bool only_audio); 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, bool only_audio, bool multiplex=false);
void connectRtpServer(const std::string &stream_id, const std::string &dst_url, uint16_t dst_port, const std::function<void(const toolkit::SockException &ex)> &cb); void connectRtpServer(const std::string &stream_id, const std::string &dst_url, uint16_t dst_port, const std::function<void(const toolkit::SockException &ex)> &cb);
bool closeRtpServer(const std::string &stream_id); bool closeRtpServer(const std::string &stream_id);
#endif #endif

View File

@ -156,7 +156,7 @@ private:
EventPoller::DelayTask::Ptr _delay_task; EventPoller::DelayTask::Ptr _delay_task;
}; };
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, bool only_audio) { 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, bool only_audio, bool multiplex) {
//创建udp服务器 //创建udp服务器
Socket::Ptr rtp_socket = Socket::createSocket(nullptr, true); Socket::Ptr rtp_socket = Socket::createSocket(nullptr, true);
Socket::Ptr rtcp_socket = Socket::createSocket(nullptr, true); Socket::Ptr rtcp_socket = Socket::createSocket(nullptr, true);
@ -195,7 +195,8 @@ void RtpServer::start(uint16_t local_port, const string &stream_id, TcpMode tcp_
//创建udp服务器 //创建udp服务器
UdpServer::Ptr udp_server; UdpServer::Ptr udp_server;
RtcpHelper::Ptr helper; RtcpHelper::Ptr helper;
if (!stream_id.empty()) { //增加了多路复用判断如果多路复用为true就走else逻辑同时保留了原来stream_id为空走else逻辑
if (!stream_id.empty() && !multiplex) {
//指定了流id那么一个端口一个流(不管是否包含多个ssrc的多个流绑定rtp源后会筛选掉ip端口不匹配的流) //指定了流id那么一个端口一个流(不管是否包含多个ssrc的多个流绑定rtp源后会筛选掉ip端口不匹配的流)
helper = std::make_shared<RtcpHelper>(std::move(rtcp_socket), stream_id); helper = std::make_shared<RtcpHelper>(std::move(rtcp_socket), stream_id);
helper->startRtcp(); helper->startRtcp();

View File

@ -42,9 +42,10 @@ public:
* @param local_ip ip * @param local_ip ip
* @param re_use_port socket为re_use属性 * @param re_use_port socket为re_use属性
* @param ssrc ssrc * @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 std::string &stream_id = "", TcpMode tcp_mode = PASSIVE,
const char *local_ip = "::", bool re_use_port = true, uint32_t ssrc = 0, bool only_audio = false); const char *local_ip = "::", bool re_use_port = true, uint32_t ssrc = 0, bool only_audio = false, bool multiplex = false);
/** /**
* tcp服务(tcp主动模式) * tcp服务(tcp主动模式)