mirror of
https://github.com/ZLMediaKit/ZLMediaKit.git
synced 2024-11-26 04:31:37 +08:00
初步实现webrtc单udp端口模式
This commit is contained in:
parent
8352f119f2
commit
02da99e285
@ -25,7 +25,11 @@
|
|||||||
#include "Rtp/RtpServer.h"
|
#include "Rtp/RtpServer.h"
|
||||||
#include "WebApi.h"
|
#include "WebApi.h"
|
||||||
#include "WebHook.h"
|
#include "WebHook.h"
|
||||||
#include "../webrtc/Sdp.h"
|
|
||||||
|
#if defined(ENABLE_WEBRTC)
|
||||||
|
#include "../webrtc/WebRtcTransport.h"
|
||||||
|
#include "../webrtc/WebRtcSession.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined(ENABLE_VERSION)
|
#if defined(ENABLE_VERSION)
|
||||||
#include "Version.h"
|
#include "Version.h"
|
||||||
@ -255,13 +259,13 @@ int start_main(int argc,char *argv[]) {
|
|||||||
//加载配置文件,如果配置文件不存在就创建一个
|
//加载配置文件,如果配置文件不存在就创建一个
|
||||||
loadIniConfig(g_ini_file.data());
|
loadIniConfig(g_ini_file.data());
|
||||||
|
|
||||||
if(!File::is_dir(ssl_file.data())){
|
if (!File::is_dir(ssl_file.data())) {
|
||||||
//不是文件夹,加载证书,证书包含公钥和私钥
|
//不是文件夹,加载证书,证书包含公钥和私钥
|
||||||
SSL_Initor::Instance().loadCertificate(ssl_file.data());
|
SSL_Initor::Instance().loadCertificate(ssl_file.data());
|
||||||
}else{
|
} else {
|
||||||
//加载文件夹下的所有证书
|
//加载文件夹下的所有证书
|
||||||
File::scanDir(ssl_file,[](const string &path, bool isDir){
|
File::scanDir(ssl_file, [](const string &path, bool isDir) {
|
||||||
if(!isDir){
|
if (!isDir) {
|
||||||
//最后的一个证书会当做默认证书(客户端ssl握手时未指定主机)
|
//最后的一个证书会当做默认证书(客户端ssl握手时未指定主机)
|
||||||
SSL_Initor::Instance().loadCertificate(path.data());
|
SSL_Initor::Instance().loadCertificate(path.data());
|
||||||
}
|
}
|
||||||
@ -283,56 +287,67 @@ int start_main(int argc,char *argv[]) {
|
|||||||
|
|
||||||
//简单的telnet服务器,可用于服务器调试,但是不能使用23端口,否则telnet上了莫名其妙的现象
|
//简单的telnet服务器,可用于服务器调试,但是不能使用23端口,否则telnet上了莫名其妙的现象
|
||||||
//测试方法:telnet 127.0.0.1 9000
|
//测试方法:telnet 127.0.0.1 9000
|
||||||
TcpServer::Ptr shellSrv(new TcpServer());
|
TcpServer::Ptr shellSrv = std::make_shared<TcpServer>();
|
||||||
|
|
||||||
//rtsp[s]服务器, 可用于诸如亚马逊echo show这样的设备访问
|
//rtsp[s]服务器, 可用于诸如亚马逊echo show这样的设备访问
|
||||||
TcpServer::Ptr rtspSrv(new TcpServer());
|
TcpServer::Ptr rtspSrv = std::make_shared<TcpServer>();;
|
||||||
TcpServer::Ptr rtspSSLSrv(new TcpServer());
|
TcpServer::Ptr rtspSSLSrv = std::make_shared<TcpServer>();;
|
||||||
|
|
||||||
//rtmp[s]服务器
|
//rtmp[s]服务器
|
||||||
TcpServer::Ptr rtmpSrv(new TcpServer());
|
TcpServer::Ptr rtmpSrv = std::make_shared<TcpServer>();;
|
||||||
TcpServer::Ptr rtmpsSrv(new TcpServer());
|
TcpServer::Ptr rtmpsSrv = std::make_shared<TcpServer>();;
|
||||||
|
|
||||||
//http[s]服务器
|
//http[s]服务器
|
||||||
TcpServer::Ptr httpSrv(new TcpServer());
|
TcpServer::Ptr httpSrv = std::make_shared<TcpServer>();;
|
||||||
TcpServer::Ptr httpsSrv(new TcpServer());
|
TcpServer::Ptr httpsSrv = std::make_shared<TcpServer>();;
|
||||||
|
|
||||||
#if defined(ENABLE_RTPPROXY)
|
#if defined(ENABLE_RTPPROXY)
|
||||||
//GB28181 rtp推流端口,支持UDP/TCP
|
//GB28181 rtp推流端口,支持UDP/TCP
|
||||||
RtpServer::Ptr rtpServer = std::make_shared<RtpServer>();
|
RtpServer::Ptr rtpServer = std::make_shared<RtpServer>();
|
||||||
#endif//defined(ENABLE_RTPPROXY)
|
#endif//defined(ENABLE_RTPPROXY)
|
||||||
|
|
||||||
|
#if defined(ENABLE_WEBRTC)
|
||||||
|
//webrtc udp服务器
|
||||||
|
UdpServer::Ptr rtcSrv = std::make_shared<UdpServer>();
|
||||||
|
uint16_t rtcPort = mINI::Instance()[RTC::kPort];
|
||||||
|
#endif//defined(ENABLE_WEBRTC)
|
||||||
|
|
||||||
try {
|
try {
|
||||||
//rtsp服务器,端口默认554
|
//rtsp服务器,端口默认554
|
||||||
if(rtspPort) { rtspSrv->start<RtspSession>(rtspPort); }
|
if (rtspPort) { rtspSrv->start<RtspSession>(rtspPort); }
|
||||||
//rtsps服务器,端口默认322
|
//rtsps服务器,端口默认322
|
||||||
if(rtspsPort) { rtspSSLSrv->start<RtspSessionWithSSL>(rtspsPort); }
|
if (rtspsPort) { rtspSSLSrv->start<RtspSessionWithSSL>(rtspsPort); }
|
||||||
|
|
||||||
//rtmp服务器,端口默认1935
|
//rtmp服务器,端口默认1935
|
||||||
if(rtmpPort) { rtmpSrv->start<RtmpSession>(rtmpPort); }
|
if (rtmpPort) { rtmpSrv->start<RtmpSession>(rtmpPort); }
|
||||||
//rtmps服务器,端口默认19350
|
//rtmps服务器,端口默认19350
|
||||||
if(rtmpsPort) { rtmpsSrv->start<RtmpSessionWithSSL>(rtmpsPort); }
|
if (rtmpsPort) { rtmpsSrv->start<RtmpSessionWithSSL>(rtmpsPort); }
|
||||||
|
|
||||||
//http服务器,端口默认80
|
//http服务器,端口默认80
|
||||||
if(httpPort) { httpSrv->start<HttpSession>(httpPort); }
|
if (httpPort) { httpSrv->start<HttpSession>(httpPort); }
|
||||||
//https服务器,端口默认443
|
//https服务器,端口默认443
|
||||||
if(httpsPort) { httpsSrv->start<HttpsSession>(httpsPort); }
|
if (httpsPort) { httpsSrv->start<HttpsSession>(httpsPort); }
|
||||||
|
|
||||||
//telnet远程调试服务器
|
//telnet远程调试服务器
|
||||||
if(shellPort) { shellSrv->start<ShellSession>(shellPort); }
|
if (shellPort) { shellSrv->start<ShellSession>(shellPort); }
|
||||||
|
|
||||||
#if defined(ENABLE_RTPPROXY)
|
#if defined(ENABLE_RTPPROXY)
|
||||||
//创建rtp服务器
|
//创建rtp服务器
|
||||||
if(rtpPort){ rtpServer->start(rtpPort); }
|
if (rtpPort) { rtpServer->start(rtpPort); }
|
||||||
#endif//defined(ENABLE_RTPPROXY)
|
#endif//defined(ENABLE_RTPPROXY)
|
||||||
|
|
||||||
}catch (std::exception &ex){
|
#if defined(ENABLE_WEBRTC)
|
||||||
|
//webrtc udp服务器
|
||||||
|
if (rtcPort) { rtcSrv->start<WebRtcSession>(rtcPort); }
|
||||||
|
#endif//defined(ENABLE_WEBRTC)
|
||||||
|
|
||||||
|
} catch (std::exception &ex) {
|
||||||
WarnL << "端口占用或无权限:" << ex.what() << endl;
|
WarnL << "端口占用或无权限:" << ex.what() << endl;
|
||||||
ErrorL << "程序启动失败,请修改配置文件中端口号后重试!" << endl;
|
ErrorL << "程序启动失败,请修改配置文件中端口号后重试!" << endl;
|
||||||
sleep(1);
|
sleep(1);
|
||||||
#if !defined(_WIN32)
|
#if !defined(_WIN32)
|
||||||
if(pid != getpid()){
|
if (pid != getpid()) {
|
||||||
kill(pid,SIGINT);
|
kill(pid, SIGINT);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
return -1;
|
return -1;
|
||||||
|
65
webrtc/WebRtcSession.cpp
Normal file
65
webrtc/WebRtcSession.cpp
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2016 The ZLMediaKit project authors. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* This file is part of ZLMediaKit(https://github.com/xia-chu/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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "WebRtcSession.h"
|
||||||
|
#include "Util/util.h"
|
||||||
|
|
||||||
|
WebRtcSession::WebRtcSession(const Socket::Ptr &sock) : UdpSession(sock) {
|
||||||
|
socklen_t addr_len = sizeof(_peer_addr);
|
||||||
|
getpeername(sock->rawFD(), &_peer_addr, &addr_len);
|
||||||
|
InfoP(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
WebRtcSession::~WebRtcSession() {
|
||||||
|
InfoP(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
void WebRtcSession::onRecv(const Buffer::Ptr &buffer) {
|
||||||
|
auto buf = buffer->data();
|
||||||
|
auto len = buffer->size();
|
||||||
|
|
||||||
|
if (!_transport && RTC::StunPacket::IsStun((const uint8_t *) buf, len)) {
|
||||||
|
std::unique_ptr<RTC::StunPacket> packet(RTC::StunPacket::Parse((const uint8_t *) buf, len));
|
||||||
|
if (!packet) {
|
||||||
|
WarnL << "parse stun error";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (packet->GetClass() == RTC::StunPacket::Class::REQUEST &&
|
||||||
|
packet->GetMethod() == RTC::StunPacket::Method::BINDING) {
|
||||||
|
//收到binding request请求
|
||||||
|
_transport = createTransport(packet->GetUsername());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_transport) {
|
||||||
|
_transport->inputSockData(buf, len, &_peer_addr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void WebRtcSession::onError(const SockException &err) {
|
||||||
|
if (_transport) {
|
||||||
|
_transport->unrefSelf(err);
|
||||||
|
_transport = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void WebRtcSession::onManager() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<WebRtcTransport> WebRtcSession::createTransport(const string &user_name) {
|
||||||
|
if (user_name.empty()) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
auto vec = split(user_name, ":");
|
||||||
|
auto ret = WebRtcTransportImp::getTransport(vec[0]);
|
||||||
|
ret->setSession(this);
|
||||||
|
return ret;
|
||||||
|
}
|
39
webrtc/WebRtcSession.h
Normal file
39
webrtc/WebRtcSession.h
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2016 The ZLMediaKit project authors. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* This file is part of ZLMediaKit(https://github.com/xia-chu/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_WEBRTCSESSION_H
|
||||||
|
#define ZLMEDIAKIT_WEBRTCSESSION_H
|
||||||
|
|
||||||
|
#include "Network/Session.h"
|
||||||
|
#include "IceServer.hpp"
|
||||||
|
#include "WebRtcTransport.h"
|
||||||
|
|
||||||
|
using namespace toolkit;
|
||||||
|
|
||||||
|
class WebRtcSession : public UdpSession {
|
||||||
|
public:
|
||||||
|
WebRtcSession(const Socket::Ptr &sock);
|
||||||
|
~WebRtcSession() override;
|
||||||
|
|
||||||
|
void onRecv(const Buffer::Ptr &) override;
|
||||||
|
void onError(const SockException &err) override;
|
||||||
|
void onManager() override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::shared_ptr<WebRtcTransport> createTransport(const string &user_name);
|
||||||
|
|
||||||
|
private:
|
||||||
|
struct sockaddr _peer_addr;
|
||||||
|
std::shared_ptr<WebRtcTransport> _transport;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif //ZLMEDIAKIT_WEBRTCSESSION_H
|
@ -30,28 +30,59 @@ const string kTimeOutSec = RTC_FIELD"timeoutSec";
|
|||||||
const string kExternIP = RTC_FIELD"externIP";
|
const string kExternIP = RTC_FIELD"externIP";
|
||||||
//设置remb比特率,非0时关闭twcc并开启remb。该设置在rtc推流时有效,可以控制推流画质
|
//设置remb比特率,非0时关闭twcc并开启remb。该设置在rtc推流时有效,可以控制推流画质
|
||||||
const string kRembBitRate = RTC_FIELD"rembBitRate";
|
const string kRembBitRate = RTC_FIELD"rembBitRate";
|
||||||
|
//webrtc单端口udp服务器
|
||||||
|
const string kPort = RTC_FIELD"port";
|
||||||
|
|
||||||
static onceToken token([]() {
|
static onceToken token([]() {
|
||||||
mINI::Instance()[kTimeOutSec] = 15;
|
mINI::Instance()[kTimeOutSec] = 15;
|
||||||
mINI::Instance()[kExternIP] = "";
|
mINI::Instance()[kExternIP] = "";
|
||||||
mINI::Instance()[kRembBitRate] = 0;
|
mINI::Instance()[kRembBitRate] = 0;
|
||||||
|
mINI::Instance()[kPort] = 8000;
|
||||||
});
|
});
|
||||||
|
|
||||||
}//namespace RTC
|
}//namespace RTC
|
||||||
|
|
||||||
WebRtcTransport::WebRtcTransport(const EventPoller::Ptr &poller) {
|
WebRtcTransport::WebRtcTransport(const EventPoller::Ptr &poller) {
|
||||||
_poller = poller;
|
_poller = poller;
|
||||||
_dtls_transport = std::make_shared<RTC::DtlsTransport>(poller, this);
|
|
||||||
_ice_server = std::make_shared<RTC::IceServer>(this, makeRandStr(4), makeRandStr(28).substr(4));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void WebRtcTransport::onCreate(){
|
void WebRtcTransport::onCreate(){
|
||||||
|
_key = to_string(reinterpret_cast<uint64_t>(this));
|
||||||
|
_dtls_transport = std::make_shared<RTC::DtlsTransport>(_poller, this);
|
||||||
|
_ice_server = std::make_shared<RTC::IceServer>(this, _key, makeRandStr(24));
|
||||||
|
refSelf();
|
||||||
}
|
}
|
||||||
|
|
||||||
void WebRtcTransport::onDestory(){
|
void WebRtcTransport::onDestory(){
|
||||||
_dtls_transport = nullptr;
|
_dtls_transport = nullptr;
|
||||||
_ice_server = nullptr;
|
_ice_server = nullptr;
|
||||||
|
unrefSelf(SockException());
|
||||||
|
}
|
||||||
|
|
||||||
|
static mutex s_rtc_mtx;
|
||||||
|
static unordered_map<string, weak_ptr<WebRtcTransportImp> > s_rtc_map;
|
||||||
|
|
||||||
|
void WebRtcTransport::refSelf() {
|
||||||
|
_self = shared_from_this();
|
||||||
|
|
||||||
|
lock_guard<mutex> lck(s_rtc_mtx);
|
||||||
|
s_rtc_map[_key] = static_pointer_cast<WebRtcTransportImp>(_self);
|
||||||
|
}
|
||||||
|
|
||||||
|
void WebRtcTransport::unrefSelf(const SockException &ex) {
|
||||||
|
_self = nullptr;
|
||||||
|
|
||||||
|
lock_guard<mutex> lck(s_rtc_mtx);
|
||||||
|
s_rtc_map.erase(_key);
|
||||||
|
}
|
||||||
|
|
||||||
|
WebRtcTransportImp::Ptr WebRtcTransportImp::getTransport(const string &key){
|
||||||
|
lock_guard<mutex> lck(s_rtc_mtx);
|
||||||
|
auto it = s_rtc_map.find(key);
|
||||||
|
if (it == s_rtc_map.end()) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
return it->second.lock();
|
||||||
}
|
}
|
||||||
|
|
||||||
const EventPoller::Ptr& WebRtcTransport::getPoller() const{
|
const EventPoller::Ptr& WebRtcTransport::getPoller() const{
|
||||||
@ -299,18 +330,7 @@ WebRtcTransportImp::Ptr WebRtcTransportImp::create(const EventPoller::Ptr &polle
|
|||||||
|
|
||||||
void WebRtcTransportImp::onCreate(){
|
void WebRtcTransportImp::onCreate(){
|
||||||
WebRtcTransport::onCreate();
|
WebRtcTransport::onCreate();
|
||||||
_socket = Socket::createSocket(getPoller(), false);
|
weak_ptr<WebRtcTransportImp> weak_self = static_pointer_cast<WebRtcTransportImp>(shared_from_this());
|
||||||
//随机端口,绑定全部网卡
|
|
||||||
_socket->bindUdpSock(0);
|
|
||||||
weak_ptr<WebRtcTransportImp> weak_self = shared_from_this();
|
|
||||||
_socket->setOnRead([weak_self](const Buffer::Ptr &buf, struct sockaddr *addr, int addr_len) mutable {
|
|
||||||
auto strong_self = weak_self.lock();
|
|
||||||
if (strong_self) {
|
|
||||||
strong_self->inputSockData(buf->data(), buf->size(), addr);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
_self = shared_from_this();
|
|
||||||
|
|
||||||
GET_CONFIG(float, timeoutSec, RTC::kTimeOutSec);
|
GET_CONFIG(float, timeoutSec, RTC::kTimeOutSec);
|
||||||
_timer = std::make_shared<Timer>(timeoutSec / 2, [weak_self]() {
|
_timer = std::make_shared<Timer>(timeoutSec / 2, [weak_self]() {
|
||||||
auto strong_self = weak_self.lock();
|
auto strong_self = weak_self.lock();
|
||||||
@ -346,7 +366,7 @@ void WebRtcTransportImp::onDestory() {
|
|||||||
<< _media_info._streamid
|
<< _media_info._streamid
|
||||||
<< ")结束播放,耗时(s):" << duration;
|
<< ")结束播放,耗时(s):" << duration;
|
||||||
if (_bytes_usage >= iFlowThreshold * 1024) {
|
if (_bytes_usage >= iFlowThreshold * 1024) {
|
||||||
NoticeCenter::Instance().emitEvent(Broadcast::kBroadcastFlowReport, _media_info, _bytes_usage, duration, true, static_cast<SockInfo &>(*_socket));
|
NoticeCenter::Instance().emitEvent(Broadcast::kBroadcastFlowReport, _media_info, _bytes_usage, duration, true, *static_cast<SockInfo *>(_session));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -357,7 +377,7 @@ void WebRtcTransportImp::onDestory() {
|
|||||||
<< _media_info._streamid
|
<< _media_info._streamid
|
||||||
<< ")结束推流,耗时(s):" << duration;
|
<< ")结束推流,耗时(s):" << duration;
|
||||||
if (_bytes_usage >= iFlowThreshold * 1024) {
|
if (_bytes_usage >= iFlowThreshold * 1024) {
|
||||||
NoticeCenter::Instance().emitEvent(Broadcast::kBroadcastFlowReport, _media_info, _bytes_usage, duration, false, static_cast<SockInfo &>(*_socket));
|
NoticeCenter::Instance().emitEvent(Broadcast::kBroadcastFlowReport, _media_info, _bytes_usage, duration, false, *static_cast<SockInfo *>(_session));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -375,7 +395,7 @@ void WebRtcTransportImp::attach(const RtspMediaSource::Ptr &src, const MediaInfo
|
|||||||
void WebRtcTransportImp::onSendSockData(const char *buf, size_t len, struct sockaddr_in *dst, bool flush) {
|
void WebRtcTransportImp::onSendSockData(const char *buf, size_t len, struct sockaddr_in *dst, bool flush) {
|
||||||
auto ptr = BufferRaw::create();
|
auto ptr = BufferRaw::create();
|
||||||
ptr->assign(buf, len);
|
ptr->assign(buf, len);
|
||||||
_socket->send(ptr, (struct sockaddr *)(dst), sizeof(struct sockaddr), flush);
|
_session->send(std::move(ptr));
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////
|
||||||
@ -464,7 +484,7 @@ void WebRtcTransportImp::onStartWebRTC() {
|
|||||||
}
|
}
|
||||||
if (canSendRtp()) {
|
if (canSendRtp()) {
|
||||||
_reader = _play_src->getRing()->attach(getPoller(), true);
|
_reader = _play_src->getRing()->attach(getPoller(), true);
|
||||||
weak_ptr<WebRtcTransportImp> weak_self = shared_from_this();
|
weak_ptr<WebRtcTransportImp> weak_self = static_pointer_cast<WebRtcTransportImp>(shared_from_this());
|
||||||
_reader->setReadCB([weak_self](const RtspMediaSource::RingDataType &pkt) {
|
_reader->setReadCB([weak_self](const RtspMediaSource::RingDataType &pkt) {
|
||||||
auto strongSelf = weak_self.lock();
|
auto strongSelf = weak_self.lock();
|
||||||
if (!strongSelf) {
|
if (!strongSelf) {
|
||||||
@ -516,7 +536,9 @@ void WebRtcTransportImp::onCheckSdp(SdpType type, RtcSession &sdp){
|
|||||||
m.addr.address = extern_ip.empty() ? SockUtil::get_local_ip() : extern_ip;
|
m.addr.address = extern_ip.empty() ? SockUtil::get_local_ip() : extern_ip;
|
||||||
m.rtcp_addr.reset();
|
m.rtcp_addr.reset();
|
||||||
m.rtcp_addr.address = m.addr.address;
|
m.rtcp_addr.address = m.addr.address;
|
||||||
m.rtcp_addr.port = _socket->get_local_port();
|
|
||||||
|
GET_CONFIG(uint16_t, local_port, RTC::kPort);
|
||||||
|
m.rtcp_addr.port = local_port;
|
||||||
m.port = m.rtcp_addr.port;
|
m.port = m.rtcp_addr.port;
|
||||||
sdp.origin.address = m.addr.address;
|
sdp.origin.address = m.addr.address;
|
||||||
}
|
}
|
||||||
@ -576,7 +598,8 @@ SdpAttrCandidate::Ptr WebRtcTransportImp::getIceCandidate() const{
|
|||||||
candidate->priority = 100;
|
candidate->priority = 100;
|
||||||
GET_CONFIG(string, extern_ip, RTC::kExternIP);
|
GET_CONFIG(string, extern_ip, RTC::kExternIP);
|
||||||
candidate->address = extern_ip.empty() ? SockUtil::get_local_ip() : extern_ip;
|
candidate->address = extern_ip.empty() ? SockUtil::get_local_ip() : extern_ip;
|
||||||
candidate->port = _socket->get_local_port();
|
GET_CONFIG(uint16_t, local_port, RTC::kPort);
|
||||||
|
candidate->port = local_port;
|
||||||
candidate->type = "host";
|
candidate->type = "host";
|
||||||
return candidate;
|
return candidate;
|
||||||
}
|
}
|
||||||
@ -871,7 +894,7 @@ void WebRtcTransportImp::onSortedRtp(MediaTrack &track, const string &rid, RtpPa
|
|||||||
auto src_imp = std::make_shared<RtspMediaSourceImp>(_push_src->getVhost(), _push_src->getApp(), stream_id);
|
auto src_imp = std::make_shared<RtspMediaSourceImp>(_push_src->getVhost(), _push_src->getApp(), stream_id);
|
||||||
src_imp->setSdp(_push_src->getSdp());
|
src_imp->setSdp(_push_src->getSdp());
|
||||||
src_imp->setProtocolTranslation(_push_src->isRecording(Recorder::type_hls),_push_src->isRecording(Recorder::type_mp4));
|
src_imp->setProtocolTranslation(_push_src->isRecording(Recorder::type_hls),_push_src->isRecording(Recorder::type_mp4));
|
||||||
src_imp->setListener(shared_from_this());
|
src_imp->setListener(static_pointer_cast<WebRtcTransportImp>(shared_from_this()));
|
||||||
src = src_imp;
|
src = src_imp;
|
||||||
}
|
}
|
||||||
src->onWrite(std::move(rtp), false);
|
src->onWrite(std::move(rtp), false);
|
||||||
@ -943,7 +966,11 @@ void WebRtcTransportImp::onBeforeEncryptRtp(const char *buf, int &len, void *ctx
|
|||||||
|
|
||||||
void WebRtcTransportImp::onShutdown(const SockException &ex){
|
void WebRtcTransportImp::onShutdown(const SockException &ex){
|
||||||
WarnL << ex.what();
|
WarnL << ex.what();
|
||||||
_self = nullptr;
|
unrefSelf(ex);
|
||||||
|
if (_session) {
|
||||||
|
_session->shutdown(ex);
|
||||||
|
_session = nullptr;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
@ -975,27 +1002,9 @@ string WebRtcTransportImp::getOriginUrl(MediaSource &sender) const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<SockInfo> WebRtcTransportImp::getOriginSock(MediaSource &sender) const {
|
std::shared_ptr<SockInfo> WebRtcTransportImp::getOriginSock(MediaSource &sender) const {
|
||||||
return const_cast<WebRtcTransportImp *>(this)->shared_from_this();
|
return static_pointer_cast<SockInfo>(const_cast<Session *>(_session)->shared_from_this());
|
||||||
}
|
}
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////////////////
|
void WebRtcTransportImp::setSession(Session *session) {
|
||||||
|
_session = session;
|
||||||
string WebRtcTransportImp::get_local_ip() {
|
|
||||||
return getSdp(SdpType::answer).media[0].candidate[0].address;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint16_t WebRtcTransportImp::get_local_port() {
|
|
||||||
return _socket->get_local_port();
|
|
||||||
}
|
|
||||||
|
|
||||||
string WebRtcTransportImp::get_peer_ip() {
|
|
||||||
return SockUtil::inet_ntoa(((struct sockaddr_in *) getSelectedTuple())->sin_addr);
|
|
||||||
}
|
|
||||||
|
|
||||||
uint16_t WebRtcTransportImp::get_peer_port() {
|
|
||||||
return ntohs(((struct sockaddr_in *) getSelectedTuple())->sin_port);
|
|
||||||
}
|
|
||||||
|
|
||||||
string WebRtcTransportImp::getIdentifier() const {
|
|
||||||
return StrPrinter << this;
|
|
||||||
}
|
}
|
@ -23,16 +23,24 @@
|
|||||||
#include "Rtcp/RtcpContext.h"
|
#include "Rtcp/RtcpContext.h"
|
||||||
#include "Rtcp/RtcpFCI.h"
|
#include "Rtcp/RtcpFCI.h"
|
||||||
#include "Nack.h"
|
#include "Nack.h"
|
||||||
|
#include "Network/Session.h"
|
||||||
|
|
||||||
using namespace toolkit;
|
using namespace toolkit;
|
||||||
using namespace mediakit;
|
using namespace mediakit;
|
||||||
|
|
||||||
class WebRtcTransport : public RTC::DtlsTransport::Listener, public RTC::IceServer::Listener {
|
//RTC配置项目
|
||||||
|
namespace RTC {
|
||||||
|
extern const string kPort;
|
||||||
|
}//namespace RTC
|
||||||
|
|
||||||
|
class WebRtcTransport : public RTC::DtlsTransport::Listener, public RTC::IceServer::Listener, public std::enable_shared_from_this<WebRtcTransport> {
|
||||||
public:
|
public:
|
||||||
using Ptr = std::shared_ptr<WebRtcTransport>;
|
using Ptr = std::shared_ptr<WebRtcTransport>;
|
||||||
WebRtcTransport(const EventPoller::Ptr &poller);
|
WebRtcTransport(const EventPoller::Ptr &poller);
|
||||||
~WebRtcTransport() override = default;
|
~WebRtcTransport() override = default;
|
||||||
|
|
||||||
|
void unrefSelf(const SockException &ex);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 创建对象
|
* 创建对象
|
||||||
*/
|
*/
|
||||||
@ -115,9 +123,11 @@ protected:
|
|||||||
private:
|
private:
|
||||||
void onSendSockData(const char *buf, size_t len, bool flush = true);
|
void onSendSockData(const char *buf, size_t len, bool flush = true);
|
||||||
void setRemoteDtlsFingerprint(const RtcSession &remote);
|
void setRemoteDtlsFingerprint(const RtcSession &remote);
|
||||||
|
void refSelf();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
uint8_t _srtp_buf[2000];
|
uint8_t _srtp_buf[2000];
|
||||||
|
string _key;
|
||||||
EventPoller::Ptr _poller;
|
EventPoller::Ptr _poller;
|
||||||
std::shared_ptr<RTC::IceServer> _ice_server;
|
std::shared_ptr<RTC::IceServer> _ice_server;
|
||||||
std::shared_ptr<RTC::DtlsTransport> _dtls_transport;
|
std::shared_ptr<RTC::DtlsTransport> _dtls_transport;
|
||||||
@ -125,6 +135,8 @@ private:
|
|||||||
std::shared_ptr<RTC::SrtpSession> _srtp_session_recv;
|
std::shared_ptr<RTC::SrtpSession> _srtp_session_recv;
|
||||||
RtcSession::Ptr _offer_sdp;
|
RtcSession::Ptr _offer_sdp;
|
||||||
RtcSession::Ptr _answer_sdp;
|
RtcSession::Ptr _answer_sdp;
|
||||||
|
//保持自我强引用
|
||||||
|
WebRtcTransport::Ptr _self;
|
||||||
};
|
};
|
||||||
|
|
||||||
class RtpChannel;
|
class RtpChannel;
|
||||||
@ -149,7 +161,7 @@ public:
|
|||||||
std::shared_ptr<RtpChannel> getRtpChannel(uint32_t ssrc) const;
|
std::shared_ptr<RtpChannel> getRtpChannel(uint32_t ssrc) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
class WebRtcTransportImp : public WebRtcTransport, public MediaSourceEvent, public SockInfo, public std::enable_shared_from_this<WebRtcTransportImp>{
|
class WebRtcTransportImp : public WebRtcTransport, public MediaSourceEvent{
|
||||||
public:
|
public:
|
||||||
using Ptr = std::shared_ptr<WebRtcTransportImp>;
|
using Ptr = std::shared_ptr<WebRtcTransportImp>;
|
||||||
~WebRtcTransportImp() override;
|
~WebRtcTransportImp() override;
|
||||||
@ -160,6 +172,9 @@ public:
|
|||||||
* @return 对象
|
* @return 对象
|
||||||
*/
|
*/
|
||||||
static Ptr create(const EventPoller::Ptr &poller);
|
static Ptr create(const EventPoller::Ptr &poller);
|
||||||
|
static Ptr getTransport(const string &key);
|
||||||
|
|
||||||
|
void setSession(Session *session);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 绑定rtsp媒体源
|
* 绑定rtsp媒体源
|
||||||
@ -193,18 +208,6 @@ protected:
|
|||||||
// 获取媒体源客户端相关信息
|
// 获取媒体源客户端相关信息
|
||||||
std::shared_ptr<SockInfo> getOriginSock(MediaSource &sender) const override;
|
std::shared_ptr<SockInfo> getOriginSock(MediaSource &sender) const override;
|
||||||
|
|
||||||
///////SockInfo override///////
|
|
||||||
//获取本机ip
|
|
||||||
string get_local_ip() override;
|
|
||||||
//获取本机端口号
|
|
||||||
uint16_t get_local_port() override;
|
|
||||||
//获取对方ip
|
|
||||||
string get_peer_ip() override;
|
|
||||||
//获取对方端口号
|
|
||||||
uint16_t get_peer_port() override;
|
|
||||||
//获取标识符
|
|
||||||
string getIdentifier() const override;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
WebRtcTransportImp(const EventPoller::Ptr &poller);
|
WebRtcTransportImp(const EventPoller::Ptr &poller);
|
||||||
void onCreate() override;
|
void onCreate() override;
|
||||||
@ -225,16 +228,14 @@ private:
|
|||||||
uint64_t _bytes_usage = 0;
|
uint64_t _bytes_usage = 0;
|
||||||
//媒体相关元数据
|
//媒体相关元数据
|
||||||
MediaInfo _media_info;
|
MediaInfo _media_info;
|
||||||
//保持自我强引用
|
|
||||||
Ptr _self;
|
|
||||||
//检测超时的定时器
|
//检测超时的定时器
|
||||||
Timer::Ptr _timer;
|
Timer::Ptr _timer;
|
||||||
//刷新计时器
|
//刷新计时器
|
||||||
Ticker _alive_ticker;
|
Ticker _alive_ticker;
|
||||||
//pli rtcp计时器
|
//pli rtcp计时器
|
||||||
Ticker _pli_ticker;
|
Ticker _pli_ticker;
|
||||||
//复合udp端口,接收一切rtp与rtcp
|
//udp session
|
||||||
Socket::Ptr _socket;
|
Session *_session;
|
||||||
//推流的rtsp源
|
//推流的rtsp源
|
||||||
RtspMediaSource::Ptr _push_src;
|
RtspMediaSource::Ptr _push_src;
|
||||||
unordered_map<string/*rid*/, RtspMediaSource::Ptr> _push_src_simulcast;
|
unordered_map<string/*rid*/, RtspMediaSource::Ptr> _push_src_simulcast;
|
||||||
|
Loading…
Reference in New Issue
Block a user