123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124 |
- /**
- * libdatachannel client example
- * Copyright (c) 2020 Staz Modrzynski
- * Copyright (c) 2020 Paul-Louis Ageneau
- *
- * 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 <iostream>
- #include <memory>
- #include <vector>
- #include <nlohmann/json.hpp>
- using nlohmann::json;
- struct Receiver {
- std::shared_ptr<rtc::PeerConnection> conn;
- std::shared_ptr<rtc::Track> track;
- };
- int main() {
- std::vector<std::shared_ptr<Receiver>> receivers;
- try {
- rtc::InitLogger(rtc::LogLevel::Info);
- auto pc = std::make_shared<rtc::PeerConnection>();
- 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);
- track->setMediaHandler(std::make_shared<rtc::RtcpReceivingSession>());
- const rtc::SSRC targetSSRC = 42;
- track->onMessage(
- [&receivers, targetSSRC](rtc::binary message) {
- // This is an RTP packet
- auto rtp = reinterpret_cast<rtc::RtpHeader *>(message.data());
- rtp->setSsrc(targetSSRC);
- for (auto pc : receivers) {
- if (pc->track != nullptr && pc->track->isOpen()) {
- pc->track->send(message);
- }
- }
- },
- nullptr);
- pc->setLocalDescription();
- // Set the sender's 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<std::string>(), j["type"].get<std::string>());
- pc->setRemoteDescription(answer);
- // For each receiver
- while (true) {
- auto r = std::make_shared<Receiver>();
- r->conn = std::make_shared<rtc::PeerConnection>();
- r->conn->onStateChange([](rtc::PeerConnection::State state) {
- std::cout << "State: " << state << std::endl;
- });
- r->conn->onGatheringStateChange([r](rtc::PeerConnection::GatheringState state) {
- std::cout << "Gathering State: " << state << std::endl;
- if (state == rtc::PeerConnection::GatheringState::Complete) {
- auto description = r->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);
- media.addSSRC(targetSSRC, "video-send");
- r->track = r->conn->addTrack(media);
- r->track->onOpen([r]() {
- r->track->requestKeyframe(); // So the receiver can start playing immediately
- });
- r->track->onMessage([](rtc::binary var) {}, nullptr);
- r->conn->setLocalDescription();
- 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<std::string>(), j["type"].get<std::string>());
- r->conn->setRemoteDescription(answer);
- receivers.push_back(r);
- }
- } catch (const std::exception &e) {
- std::cerr << "Error: " << e.what() << std::endl;
- }
- }
|