diff --git a/CMakeLists.txt b/CMakeLists.txt index e49b4bc..a7db552 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -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 +) diff --git a/src/peer_observer.cpp b/src/peer_observer.cpp new file mode 100644 index 0000000..7b5e485 --- /dev/null +++ b/src/peer_observer.cpp @@ -0,0 +1,10 @@ +// +// Created by Théo Monnom on 21/05/2022. +// + +#include "peer_observer.h" + +namespace livekit { + + +} // livekit diff --git a/src/peer_observer.h b/src/peer_observer.h new file mode 100644 index 0000000..a320714 --- /dev/null +++ b/src/peer_observer.h @@ -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 + +namespace livekit { + + class PeerObserver : public webrtc::PeerConnectionObserver { + public: + + + + void OnSignalingChange(webrtc::PeerConnectionInterface::SignalingState new_state) override { + + }; + + void OnAddStream(rtc::scoped_refptr stream) override { + + }; + + void OnRemoveStream(rtc::scoped_refptr stream) override { + + }; + + void OnDataChannel(rtc::scoped_refptr 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 diff --git a/src/room.h b/src/room.h index 2b305f9..5d0ee87 100644 --- a/src/room.h +++ b/src/room.h @@ -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 diff --git a/src/rtc_engine.cpp b/src/rtc_engine.cpp index d654e16..6b5657b 100644 --- a/src/rtc_engine.cpp +++ b/src/rtc_engine.cpp @@ -3,12 +3,82 @@ // #include "rtc_engine.h" +#include +#include 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(*this); + publisher_ = std::make_unique(*this); } -} + void RTCEngine::Configure() { + + } + + RTCEngine::PeerTransport::PeerTransport(const RTCEngine &rtc_engine) { + observer = std::make_unique(); + webrtc::PeerConnectionDependencies peer_configuration{observer.get()}; + + webrtc::RTCErrorOr> 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 diff --git a/src/rtc_engine.h b/src/rtc_engine.h index 37c7439..4f1b690 100644 --- a/src/rtc_engine.h +++ b/src/rtc_engine.h @@ -6,20 +6,44 @@ #define LIVEKIT_NATIVE_RTC_ENGINE_H #include "signal_client.h" +#include "peer_observer.h" +#include 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 peer_connection; + std::unique_ptr observer; + }; + + SignalClient client_; + + rtc::scoped_refptr peer_factory_; + webrtc::PeerConnectionInterface::RTCConfiguration configuration_; + std::unique_ptr network_thread_; + std::unique_ptr worker_thread_; + std::unique_ptr signaling_thread_; + + std::unique_ptr publisher_; + std::unique_ptr subscriber_; }; -}; - - +} // livekit #endif //LIVEKIT_NATIVE_RTC_ENGINE_H diff --git a/src/signal_client.cpp b/src/signal_client.cpp index 3cc5af4..26020a2 100644 --- a/src/signal_client.cpp +++ b/src/signal_client.cpp @@ -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()}; } -} \ No newline at end of file +} // livekit \ No newline at end of file diff --git a/src/signal_client.h b/src/signal_client.h index 344e542..855d46b 100644 --- a/src/signal_client.h +++ b/src/signal_client.h @@ -17,6 +17,7 @@ namespace websocket = beast::websocket; // from namespace net = boost::asio; // from using tcp = boost::asio::ip::tcp; // from +// 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 m_WebSocket{m_IOContext}; }; -} +} // livekit #endif //LIVEKIT_NATIVE_SIGNAL_CLIENT_H \ No newline at end of file diff --git a/src/utils.h b/src/utils.h index 51762b3..b823e78 100644 --- a/src/utils.h +++ b/src/utils.h @@ -31,6 +31,6 @@ namespace livekit { throw std::runtime_error{"failed to parse url"}; } -} +} // livekit #endif //LIVEKIT_NATIVE_UTILS_H