link
This commit is contained in:
+24
-3
@@ -1,7 +1,16 @@
|
||||
# TODO
|
||||
# This file clearly need rework
|
||||
# Build system to make it works on every platform
|
||||
# Also mb automatically download prebuild libwebrtc binary so the users can directly start coding..
|
||||
|
||||
cmake_minimum_required(VERSION 3.22)
|
||||
project(livekit-native)
|
||||
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
set(CMAKE_BUILD_TYPE Release)
|
||||
set(CMAKE_CXX_STANDARD 14)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
|
||||
add_definitions(-DWEBRTC_POSIX=1 -DWEBRTC_MAC=1 -DGLIBCXX_USE_CXX11_ABI=0)
|
||||
|
||||
find_package(Boost COMPONENTS system REQUIRED)
|
||||
include_directories(${Boost_INCLUDE_DIRS})
|
||||
@@ -13,7 +22,19 @@ find_package(spdlog CONFIG REQUIRED)
|
||||
|
||||
include_directories(thirdparty/webrtc/include)
|
||||
|
||||
|
||||
file(GLOB_RECURSE SRC src/*)
|
||||
add_executable(livekit-native ${SRC} main.cpp)
|
||||
target_link_libraries(livekit-native PRIVATE ${Boost_LIBRARIES} ${Protobuf_LIBRARIES} spdlog::spdlog)
|
||||
|
||||
# for cocoa
|
||||
find_library(CORE_FOUNDATION Foundation)
|
||||
find_library(APPLICATION_SERVICES ApplicationServices)
|
||||
find_library(CORE_SERVICES CoreServices)
|
||||
|
||||
target_link_libraries(livekit-native PRIVATE
|
||||
spdlog::spdlog
|
||||
${Boost_LIBRARIES}
|
||||
${Protobuf_LIBRARIES}
|
||||
${CORE_FOUNDATION} ${APPLICATION_SERVICES} ${CORE_SERVICES}
|
||||
${CMAKE_CURRENT_LIST_DIR}/thirdparty/webrtc/lib/libboringssl.a
|
||||
${CMAKE_CURRENT_LIST_DIR}/thirdparty/webrtc/lib/libwebrtc.a
|
||||
)
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
//
|
||||
// Created by Théo Monnom on 21/05/2022.
|
||||
//
|
||||
|
||||
#include "peer_observer.h"
|
||||
|
||||
namespace livekit {
|
||||
|
||||
|
||||
} // livekit
|
||||
@@ -0,0 +1,52 @@
|
||||
//
|
||||
// Created by Théo Monnom on 21/05/2022.
|
||||
//
|
||||
|
||||
#ifndef LIVEKIT_NATIVE_PEER_OBSERVER_H
|
||||
#define LIVEKIT_NATIVE_PEER_OBSERVER_H
|
||||
|
||||
#include <api/create_peerconnection_factory.h>
|
||||
|
||||
namespace livekit {
|
||||
|
||||
class PeerObserver : public webrtc::PeerConnectionObserver {
|
||||
public:
|
||||
|
||||
|
||||
|
||||
void OnSignalingChange(webrtc::PeerConnectionInterface::SignalingState new_state) override {
|
||||
|
||||
};
|
||||
|
||||
void OnAddStream(rtc::scoped_refptr<webrtc::MediaStreamInterface> stream) override {
|
||||
|
||||
};
|
||||
|
||||
void OnRemoveStream(rtc::scoped_refptr<webrtc::MediaStreamInterface> stream) override {
|
||||
|
||||
};
|
||||
|
||||
void OnDataChannel(rtc::scoped_refptr<webrtc::DataChannelInterface> data_channel) override {
|
||||
|
||||
};
|
||||
|
||||
void OnRenegotiationNeeded() override {
|
||||
|
||||
};
|
||||
|
||||
void OnIceConnectionChange(webrtc::PeerConnectionInterface::IceConnectionState new_state) override {
|
||||
|
||||
};
|
||||
|
||||
void OnIceGatheringChange(webrtc::PeerConnectionInterface::IceGatheringState new_state) override {
|
||||
|
||||
};
|
||||
|
||||
void OnIceCandidate(const webrtc::IceCandidateInterface *candidate) override {
|
||||
|
||||
};
|
||||
};
|
||||
|
||||
} // livekit
|
||||
|
||||
#endif //LIVEKIT_NATIVE_PEER_OBSERVER_H
|
||||
+1
-11
@@ -9,19 +9,9 @@
|
||||
#include "signal_client.h"
|
||||
|
||||
namespace livekit{
|
||||
/*class Room {
|
||||
Room();
|
||||
~Room();
|
||||
|
||||
void Connect(const std::string &url, const std::string &token);
|
||||
|
||||
|
||||
|
||||
private:
|
||||
SignalClient m_Client;
|
||||
};*/
|
||||
|
||||
}
|
||||
} // livekit
|
||||
|
||||
|
||||
#endif //LIVEKIT_NATIVE_ROOM_H
|
||||
|
||||
+72
-2
@@ -3,12 +3,82 @@
|
||||
//
|
||||
|
||||
#include "rtc_engine.h"
|
||||
#include <rtc_base/ssl_adapter.h>
|
||||
#include <spdlog/spdlog.h>
|
||||
|
||||
namespace livekit{
|
||||
|
||||
void RTCEngine::configure() {
|
||||
RTCEngine::RTCEngine() {
|
||||
|
||||
}
|
||||
|
||||
void RTCEngine::Join(const std::string &url, const std::string &token){
|
||||
client_.Connect(url, token);
|
||||
}
|
||||
|
||||
void RTCEngine::Update(){
|
||||
client_.update();
|
||||
|
||||
// Fetch SignalResponse ( The whole protocol is async )
|
||||
auto res = client_.poll();
|
||||
if(res.has_join())
|
||||
OnJoin(res.join());
|
||||
}
|
||||
|
||||
void RTCEngine::OnJoin(const JoinResponse &res){
|
||||
rtc::InitializeSSL();
|
||||
|
||||
for(auto& is : res.ice_servers()){
|
||||
webrtc::PeerConnectionInterface::IceServer ice_server;
|
||||
for(auto& url : is.urls())
|
||||
ice_server.urls.push_back(url);
|
||||
|
||||
ice_server.username = is.username();
|
||||
ice_server.password = is.credential();
|
||||
|
||||
configuration_.servers.push_back(ice_server);
|
||||
}
|
||||
|
||||
network_thread_ = rtc::Thread::CreateWithSocketServer();
|
||||
network_thread_->Start();
|
||||
worker_thread_ = rtc::Thread::Create();
|
||||
worker_thread_->Start();
|
||||
signaling_thread_ = rtc::Thread::Create();
|
||||
signaling_thread_->Start();
|
||||
|
||||
webrtc::PeerConnectionFactoryDependencies dependencies;
|
||||
dependencies.network_thread = network_thread_.get();
|
||||
dependencies.worker_thread = worker_thread_.get();
|
||||
dependencies.signaling_thread = signaling_thread_.get();
|
||||
peer_factory_ = webrtc::CreateModularPeerConnectionFactory(std::move(dependencies));
|
||||
|
||||
if (peer_factory_.get() == nullptr) {
|
||||
// TODO Make error callback
|
||||
spdlog::error("Error on CreateModularPeerConnectionFactory");
|
||||
return;
|
||||
}
|
||||
|
||||
subscriber_ = std::make_unique<PeerTransport>(*this);
|
||||
publisher_ = std::make_unique<PeerTransport>(*this);
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
void RTCEngine::Configure() {
|
||||
|
||||
}
|
||||
|
||||
RTCEngine::PeerTransport::PeerTransport(const RTCEngine &rtc_engine) {
|
||||
observer = std::make_unique<PeerObserver>();
|
||||
webrtc::PeerConnectionDependencies peer_configuration{observer.get()};
|
||||
|
||||
webrtc::RTCErrorOr<rtc::scoped_refptr<webrtc::PeerConnectionInterface>> opt_peer = rtc_engine.peer_factory_->CreatePeerConnectionOrError(
|
||||
rtc_engine.configuration_, std::move(peer_configuration));
|
||||
|
||||
if (!opt_peer.ok()) {
|
||||
throw std::runtime_error{"Failed to create a peer connection"};
|
||||
}
|
||||
|
||||
peer_connection = opt_peer.value();
|
||||
}
|
||||
} // livekit
|
||||
|
||||
+29
-5
@@ -6,20 +6,44 @@
|
||||
#define LIVEKIT_NATIVE_RTC_ENGINE_H
|
||||
|
||||
#include "signal_client.h"
|
||||
#include "peer_observer.h"
|
||||
#include <api/peer_connection_interface.h>
|
||||
|
||||
namespace livekit{
|
||||
|
||||
class RTCEngine {
|
||||
|
||||
public:
|
||||
RTCEngine();
|
||||
|
||||
void Join(const std::string &url, const std::string &token);
|
||||
void Update();
|
||||
|
||||
private:
|
||||
void configure();
|
||||
void Configure();
|
||||
void OnJoin(const JoinResponse &res);
|
||||
|
||||
private:
|
||||
SignalClient m_Client;
|
||||
// Wrapper for our PeerConnection ( Int. Impl. )
|
||||
class PeerTransport {
|
||||
public:
|
||||
explicit PeerTransport(const RTCEngine &rtc_engine);
|
||||
|
||||
rtc::scoped_refptr<webrtc::PeerConnectionInterface> peer_connection;
|
||||
std::unique_ptr<PeerObserver> observer;
|
||||
};
|
||||
|
||||
SignalClient client_;
|
||||
|
||||
rtc::scoped_refptr<webrtc::PeerConnectionFactoryInterface> peer_factory_;
|
||||
webrtc::PeerConnectionInterface::RTCConfiguration configuration_;
|
||||
std::unique_ptr<rtc::Thread> network_thread_;
|
||||
std::unique_ptr<rtc::Thread> worker_thread_;
|
||||
std::unique_ptr<rtc::Thread> signaling_thread_;
|
||||
|
||||
std::unique_ptr<PeerTransport> publisher_;
|
||||
std::unique_ptr<PeerTransport> subscriber_;
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
} // livekit
|
||||
|
||||
#endif //LIVEKIT_NATIVE_RTC_ENGINE_H
|
||||
|
||||
+12
-4
@@ -23,10 +23,10 @@ namespace livekit {
|
||||
m_URL = ParseURL(url);
|
||||
m_Token = token;
|
||||
|
||||
Start(); // We don't need a thread, everything is async ( + easier to maintain )
|
||||
start(); // We don't need a thread, everything is async ( + easier to maintain )
|
||||
}
|
||||
|
||||
void SignalClient::Update() {
|
||||
void SignalClient::update() {
|
||||
beast::error_code ec;
|
||||
m_IOContext.poll(ec);
|
||||
|
||||
@@ -59,7 +59,15 @@ namespace livekit {
|
||||
}
|
||||
}
|
||||
|
||||
void SignalClient::Start() {
|
||||
SignalResponse SignalClient::poll(){
|
||||
|
||||
|
||||
auto& r = m_ReadQueue.front();
|
||||
m_ReadQueue.pop();
|
||||
return r;
|
||||
}
|
||||
|
||||
void SignalClient::start() {
|
||||
m_Resolver.async_resolve(m_URL.host, m_URL.port, beast::bind_front_handler(&SignalClient::OnResolve, this));
|
||||
}
|
||||
|
||||
@@ -128,4 +136,4 @@ namespace livekit {
|
||||
if (ec)
|
||||
throw std::runtime_error{"SignalClient::OnWrite - " + ec.message()};
|
||||
}
|
||||
}
|
||||
} // livekit
|
||||
+5
-4
@@ -17,6 +17,7 @@ namespace websocket = beast::websocket; // from <boost/beast/websocket.hpp>
|
||||
namespace net = boost::asio; // from <boost/asio.hpp>
|
||||
using tcp = boost::asio::ip::tcp; // from <boost/asio/ip/tcp.hpp>
|
||||
|
||||
// If we keep the code singled threaded here, it'll be easily used in wasm ( Need ws bindings ), tho not sure
|
||||
namespace livekit {
|
||||
class SignalClient {
|
||||
|
||||
@@ -26,12 +27,12 @@ namespace livekit {
|
||||
|
||||
void Connect(const std::string &url, const std::string &token);
|
||||
void Disconnect();
|
||||
void Update();
|
||||
void update();
|
||||
void Send(SignalRequest req);
|
||||
SignalResponse Poll();
|
||||
SignalResponse poll();
|
||||
|
||||
private:
|
||||
void Start();
|
||||
void start();
|
||||
|
||||
// beast handlers
|
||||
void OnResolve(beast::error_code ec, tcp::resolver::results_type results);
|
||||
@@ -59,6 +60,6 @@ namespace livekit {
|
||||
tcp::resolver m_Resolver{m_IOContext};
|
||||
websocket::stream <beast::tcp_stream> m_WebSocket{m_IOContext};
|
||||
};
|
||||
}
|
||||
} // livekit
|
||||
|
||||
#endif //LIVEKIT_NATIVE_SIGNAL_CLIENT_H
|
||||
+1
-1
@@ -31,6 +31,6 @@ namespace livekit {
|
||||
|
||||
throw std::runtime_error{"failed to parse url"};
|
||||
}
|
||||
}
|
||||
} // livekit
|
||||
|
||||
#endif //LIVEKIT_NATIVE_UTILS_H
|
||||
|
||||
Reference in New Issue
Block a user