Skip to content

Commit

Permalink
WHEP Example
Browse files Browse the repository at this point in the history
  • Loading branch information
Sean-Der committed Apr 8, 2024
1 parent 0bb83d3 commit e7aa166
Show file tree
Hide file tree
Showing 3 changed files with 158 additions and 0 deletions.
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -547,5 +547,6 @@ if(NOT NO_EXAMPLES)
endif()
add_subdirectory(examples/copy-paste)
add_subdirectory(examples/copy-paste-capi)
add_subdirectory(examples/whep)
endif()

21 changes: 21 additions & 0 deletions examples/whep/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
cmake_minimum_required(VERSION 3.7)

add_executable(datachannel-whep main.cpp)

set_target_properties(datachannel-whep PROPERTIES
CXX_STANDARD 17
OUTPUT_NAME whep)

set_target_properties(datachannel-whep PROPERTIES
XCODE_ATTRIBUTE_PRODUCT_BUNDLE_IDENTIFIER com.github.paullouisageneau.libdatachannel.examples.whep)

find_package(Threads REQUIRED)
target_link_libraries(datachannel-whep LibDataChannel::LibDataChannel Threads::Threads)

if(MSVC)
add_custom_command(TARGET datachannel-whep POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_if_different
"$<TARGET_FILE_DIR:datachannel>/datachannel.dll"
$<TARGET_FILE_DIR:datachannel-media-sender>
)
endif()
136 changes: 136 additions & 0 deletions examples/whep/main.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
/**
* libdatachannel simulcast sender example
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/

#include "rtc/rtc.hpp"

#include <cstddef>
#include <cstring>
#include <iostream>
#include <memory>
#include <stdexcept>
#include <utility>

#ifdef _WIN32
#define _WINSOCK_DEPRECATED_NO_WARNINGS
#include <WS2tcpip.h>
#include <io.h>
#include <winsock2.h>
#else
#include <arpa/inet.h>
#include <netdb.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <unistd.h>
typedef int SOCKET;
#endif

const int BUFFER_SIZE = 4096;
const int EXTENSION_HEADER_SIZE = 8;

void do_whep(std::shared_ptr<rtc::PeerConnection> pc) {
int status;
SOCKET client_fd;
struct sockaddr_in serv_addr;
char buffer[BUFFER_SIZE] = {0};
struct addrinfo hints, *servinfo, *p;

if ((client_fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
throw std::runtime_error("Failed to create socket for WHEP client");
}

serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(80);

memset(&hints, 0, sizeof(hints));
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
if (getaddrinfo("localhost", "8081", &hints, &servinfo) != 0) {
throw std::runtime_error("Failed to resolve WHEP server");
}

for (p = servinfo; p != NULL; p = p->ai_next) {
if ((client_fd = socket(p->ai_family, p->ai_socktype, p->ai_protocol)) == -1) {
continue;
}

if (connect(client_fd, p->ai_addr, p->ai_addrlen) == -1) {
close(client_fd);
continue;
}

break;
}

if (p == NULL) {
throw std::runtime_error("Failed to connect to WHEP server");
}

auto description = std::string(pc->localDescription().value());

std::string request =
std::string("POST /doSignaling HTTP/1.1\r\n") + "Host: localhost\r\n" +
"Authorization: Bearer seanTest\r\n" + "Content-Type: application/sdp\r\n" +
"Content-Length: " + std::to_string(description.length()) + "\r\n\r\n" + description;
if (send(client_fd, request.c_str(), strlen(request.c_str()), 0) == -1) {
throw std::runtime_error("Failed to send offer to WHEP server");
}

if (read(client_fd, buffer, BUFFER_SIZE) == -1) {
throw std::runtime_error("Failed to read answer from WHEP server");
}

auto response = std::string(buffer);
response.erase(0, response.find("v=0"));

rtc::Description answer(response, "answer");
pc->setRemoteDescription(answer);

close(client_fd);
}

int main() {
try {
rtc::InitLogger(rtc::LogLevel::Debug);
auto peer_connection = std::make_shared<rtc::PeerConnection>();

peer_connection->onStateChange(
[](rtc::PeerConnection::State state) { std::cout << "State: " << state << std::endl; });

peer_connection->onGatheringStateChange([peer_connection](rtc::PeerConnection::GatheringState state) {
std::cout << "Gathering State: " << state << std::endl;
if (state == rtc::PeerConnection::GatheringState::Complete) {
do_whep(peer_connection);
}
});

rtc::Description::Audio audioMedia("0", rtc::Description::Direction::RecvOnly);
audioMedia.addOpusCodec(111);
auto audio_track = peer_connection->addTrack(audioMedia);

auto audio_session = std::make_shared<rtc::RtcpReceivingSession>();
audio_track->setMediaHandler(audio_session);
audio_track->onMessage([&](rtc::binary) {}, nullptr);

rtc::Description::Video videoMedia("1", rtc::Description::Direction::RecvOnly);
videoMedia.addH264Codec(96);
auto video_track = peer_connection->addTrack(videoMedia);

auto video_session = std::make_shared<rtc::RtcpReceivingSession>();
video_track->setMediaHandler(video_session);
video_track->onMessage([&](rtc::binary msg) { printf("\n video \n"); }, nullptr);

peer_connection->setLocalDescription();

std::promise<void>().get_future().wait();


} catch (const std::exception &e) {
std::cerr << "Error: " << e.what() << std::endl;
}
}

0 comments on commit e7aa166

Please sign in to comment.