/*
* libdatachannel client example
* Copyright (c) 2020 Staz Modrzynski
* Copyright (c) 2020 Paul-Louis Ageneau
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; If not, see .
*/
#define _WINSOCK_DEPRECATED_NO_WARNINGS
#include "rtc/rtc.hpp"
#include
#include
#include
using nlohmann::json;
class Sender {
rtc::PeerConnection conn;
};
struct Receiver {
std::shared_ptr conn;
std::shared_ptr track;
};
int main() {
std::vector> receivers;
try {
rtc::InitLogger(rtc::LogLevel::Info);
auto pc = std::make_shared();
pc->onStateChange(
[](rtc::PeerConnection::State state) { std::cout << "State: " << state << std::endl; });
pc->onGatheringStateChange([pc](rtc::PeerConnection::GatheringState state) {
std::cout << "Gathering State: " << state << std::endl;
if (state == rtc::PeerConnection::GatheringState::Complete) {
auto description = pc->localDescription();
json message = {{"type", description->typeString()},
{"sdp", std::string(description.value())}};
std::cout << "Please copy/paste this offer to the SENDER: " << message << std::endl;
}
});
rtc::Description::Video media("video", rtc::Description::Direction::RecvOnly);
media.addH264Codec(96);
media.setBitrate(3000); // Request 3Mbps (Browsers do not encode more than 2.5MBps from a webcam)
auto track = pc->addTrack(media);
pc->setLocalDescription();
auto session = std::make_shared();
track->setRtcpHandler(session);
const rtc::SSRC targetSSRC = 15;
track->onMessage(
[&receivers](rtc::binary message) {
// This is an RTP packet
auto rtp = (rtc::RTP*) message.data();
rtp->ssrc = htonl(targetSSRC);
for (auto pc : receivers) {
if (pc->track != nullptr && pc->track->isOpen()) {
pc->track->send(message);
}
}
},
nullptr);
// Set the SENDERS Answer
{
std::cout << "Please copy/paste the answer provided by the SENDER: " << std::endl;
std::string sdp;
std::getline(std::cin, sdp);
std::cout << "Got answer" << sdp << std::endl;
json j = json::parse(sdp);
rtc::Description answer(j["sdp"].get(), j["type"].get());
pc->setRemoteDescription(answer);
}
// For each receiver
while (true) {
auto pc = std::make_shared();
pc->conn = std::make_shared();
pc->conn->onStateChange(
[](rtc::PeerConnection::State state) { std::cout << "State: " << state << std::endl; });
pc->conn->onGatheringStateChange([pc](rtc::PeerConnection::GatheringState state) {
std::cout << "Gathering State: " << state << std::endl;
if (state == rtc::PeerConnection::GatheringState::Complete) {
auto description = pc->conn->localDescription();
json message = {{"type", description->typeString()},
{"sdp", std::string(description.value())}};
std::cout << "Please copy/paste this offer to the RECEIVER: " << message << std::endl;
}
});
rtc::Description::Video media("video", rtc::Description::Direction::SendOnly);
media.addH264Codec(96);
media.setBitrate(
3000); // Request 3Mbps (Browsers do not encode more than 2.5MBps from a webcam)
media.addSSRC(targetSSRC, "video-send");
pc->track = pc->conn->addTrack(media);
pc->conn->setLocalDescription();
auto session = std::make_shared();
pc->track->setRtcpHandler(session);
pc->track->onMessage([](rtc::binary var){}, nullptr);
std::cout << "Please copy/paste the answer provided by the RECEIVER: " << std::endl;
std::string sdp;
std::getline(std::cin, sdp);
std::cout << "Got answer" << sdp << std::endl;
json j = json::parse(sdp);
rtc::Description answer(j["sdp"].get(), j["type"].get());
pc->conn->setRemoteDescription(answer);
receivers.push_back(pc);
}
} catch (const std::exception &e) {
std::cerr << "Error: " << e.what() << std::endl;
}
}