mirror of
https://github.com/ZLMediaKit/ZLMediaKit.git
synced 2026-06-19 23:02:21 +08:00
feat: 增加webrtc代理拉流 (#4389)
- 增加客户端模式,支持主动拉流、推流: - addStreamProxy接口新增支持whep主动拉流,拉流地址目前只兼容zlm的whep url。 - addStreamPusherProxy接口新增支持whip主动推流,推流地址目前只兼容zlm的whip url。 - 以上推流url格式为webrtc[s]://server_host:server_port/app/stream_id?key=value, 内部会自动转换为http[s]://server_host:server_port/index/api/[whip/whep]?app=app&stream=stream_id&key=value。 - 增加WebRtc p2p 模式: - 增加 ICE FULL模式。 - 增加STUN/TURN 服务器。 - 增加websocket 信令。 - 增加P2P代理拉流。 --------- Co-authored-by: xia-chu <771730766@qq.com> Co-authored-by: mtdxc <mtdxc@126.com> Co-authored-by: cqm <cqm@97kid.com>
This commit is contained in:
139
webrtc/IceSession.cpp
Normal file
139
webrtc/IceSession.cpp
Normal file
@@ -0,0 +1,139 @@
|
||||
/*
|
||||
* Copyright (c) 2016-present The ZLMediaKit project authors. All Rights Reserved.
|
||||
*
|
||||
* This file is part of ZLMediaKit(https://github.com/ZLMediaKit/ZLMediaKit).
|
||||
*
|
||||
* Use of this source code is governed by MIT-like 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.
|
||||
*/
|
||||
|
||||
#include "IceSession.hpp"
|
||||
#include "Util/util.h"
|
||||
#include "Common/config.h"
|
||||
#include "WebRtcTransport.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace toolkit;
|
||||
|
||||
namespace mediakit {
|
||||
|
||||
static IceSession::Ptr queryIceTransport(uint8_t *data, size_t size) {
|
||||
auto packet = RTC::StunPacket::parse((const uint8_t *)data, size);
|
||||
if (!packet) {
|
||||
WarnL << "parse stun error";
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto username = packet->getUsername();
|
||||
return IceSessionManager::Instance().getItem(username);
|
||||
}
|
||||
|
||||
//////////// IceSession //////////////////////////
|
||||
IceSession::IceSession(const Socket::Ptr &sock) : Session(sock) {
|
||||
TraceL << getIdentifier();
|
||||
_over_tcp = sock->sockType() == SockNum::Sock_TCP;
|
||||
GET_CONFIG(string, iceUfrag, Rtc::kIceUfrag);
|
||||
GET_CONFIG(string, icePwd, Rtc::kIcePwd);
|
||||
_ice_transport = std::make_shared<IceServer>(this, iceUfrag, icePwd, getPoller());
|
||||
_ice_transport->initialize();
|
||||
}
|
||||
|
||||
IceSession::~IceSession() {
|
||||
TraceL << getIdentifier();
|
||||
}
|
||||
|
||||
EventPoller::Ptr IceSession::queryPoller(const Buffer::Ptr &buffer) {
|
||||
auto transport = queryIceTransport((uint8_t *)buffer->data(), buffer->size());
|
||||
return transport ? transport->getPoller() : nullptr;
|
||||
}
|
||||
|
||||
void IceSession::onRecv(const Buffer::Ptr &buffer) {
|
||||
// TraceL;
|
||||
if (_over_tcp) {
|
||||
input(buffer->data(), buffer->size());
|
||||
}
|
||||
else{
|
||||
onRecv_l(buffer->data(), buffer->size());
|
||||
}
|
||||
}
|
||||
|
||||
void IceSession::onRecv_l(const char* buffer, size_t size) {
|
||||
if (!_session_pair) {
|
||||
_session_pair = std::make_shared<IceTransport::Pair>(shared_from_this());
|
||||
}
|
||||
_ice_transport->processSocketData((const uint8_t *)buffer, size, _session_pair);
|
||||
}
|
||||
|
||||
void IceSession::onError(const SockException &err) {
|
||||
InfoL;
|
||||
// 消除循环引用
|
||||
_session_pair = nullptr;
|
||||
}
|
||||
|
||||
void IceSession::onManager() {
|
||||
}
|
||||
|
||||
ssize_t IceSession::onRecvHeader(const char *data, size_t len) {
|
||||
onRecv_l(data + 2, len - 2);
|
||||
return 0;
|
||||
}
|
||||
|
||||
const char *IceSession::onSearchPacketTail(const char *data, size_t len) {
|
||||
if (len < 2) {
|
||||
// Not enough data
|
||||
return nullptr;
|
||||
}
|
||||
uint16_t length = (((uint8_t *)data)[0] << 8) | ((uint8_t *)data)[1];
|
||||
if (len < (size_t)(length + 2)) {
|
||||
// Not enough data
|
||||
return nullptr;
|
||||
}
|
||||
// Return the end of the RTP packet
|
||||
return data + 2 + length;
|
||||
}
|
||||
|
||||
void IceSession::onIceTransportRecvData(const toolkit::Buffer::Ptr& buffer, const IceTransport::Pair::Ptr& pair) {
|
||||
_ice_transport->processSocketData((const uint8_t *)buffer->data(), buffer->size(), pair);
|
||||
}
|
||||
|
||||
void IceSession::onIceTransportGatheringCandidate(const IceTransport::Pair::Ptr& pair, const CandidateInfo& candidate) {
|
||||
DebugL << candidate.dumpString();
|
||||
}
|
||||
|
||||
void IceSession::onIceTransportDisconnected() {
|
||||
InfoL << getIdentifier();
|
||||
}
|
||||
|
||||
void IceSession::onIceTransportCompleted() {
|
||||
InfoL << getIdentifier();
|
||||
}
|
||||
|
||||
//////////// IceSessionManager //////////////////////////
|
||||
|
||||
IceSessionManager &IceSessionManager::Instance() {
|
||||
static IceSessionManager s_instance;
|
||||
return s_instance;
|
||||
}
|
||||
|
||||
void IceSessionManager::addItem(const std::string& key, const IceSession::Ptr &ptr) {
|
||||
std::lock_guard<std::mutex> lck(_mtx);
|
||||
_map[key] = ptr;
|
||||
}
|
||||
|
||||
IceSession::Ptr IceSessionManager::getItem(const std::string& key) {
|
||||
assert(!key.empty());
|
||||
std::lock_guard<std::mutex> lck(_mtx);
|
||||
auto it = _map.find(key);
|
||||
if (it == _map.end()) {
|
||||
return nullptr;
|
||||
}
|
||||
return it->second.lock();
|
||||
}
|
||||
|
||||
void IceSessionManager::removeItem(const std::string& key) {
|
||||
std::lock_guard<std::mutex> lck(_mtx);
|
||||
_map.erase(key);
|
||||
}
|
||||
|
||||
}// namespace mediakit
|
||||
Reference in New Issue
Block a user