main.cpp 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. /**
  2. * libdatachannel client example
  3. * Copyright (c) 2020 Staz Modrzynski
  4. * Copyright (c) 2020 Paul-Louis Ageneau
  5. *
  6. * This Source Code Form is subject to the terms of the Mozilla Public
  7. * License, v. 2.0. If a copy of the MPL was not distributed with this
  8. * file, You can obtain one at https://mozilla.org/MPL/2.0/.
  9. */
  10. #include "rtc/rtc.hpp"
  11. #include <iostream>
  12. #include <memory>
  13. #include <vector>
  14. #include <nlohmann/json.hpp>
  15. using nlohmann::json;
  16. struct Receiver {
  17. std::shared_ptr<rtc::PeerConnection> conn;
  18. std::shared_ptr<rtc::Track> track;
  19. };
  20. int main() {
  21. std::vector<std::shared_ptr<Receiver>> receivers;
  22. try {
  23. rtc::InitLogger(rtc::LogLevel::Info);
  24. auto pc = std::make_shared<rtc::PeerConnection>();
  25. pc->onStateChange(
  26. [](rtc::PeerConnection::State state) { std::cout << "State: " << state << std::endl; });
  27. pc->onGatheringStateChange([pc](rtc::PeerConnection::GatheringState state) {
  28. std::cout << "Gathering State: " << state << std::endl;
  29. if (state == rtc::PeerConnection::GatheringState::Complete) {
  30. auto description = pc->localDescription();
  31. json message = {{"type", description->typeString()},
  32. {"sdp", std::string(description.value())}};
  33. std::cout << "Please copy/paste this offer to the SENDER: " << message << std::endl;
  34. }
  35. });
  36. rtc::Description::Video media("video", rtc::Description::Direction::RecvOnly);
  37. media.addH264Codec(96);
  38. media.setBitrate(
  39. 3000); // Request 3Mbps (Browsers do not encode more than 2.5MBps from a webcam)
  40. auto track = pc->addTrack(media);
  41. auto session = std::make_shared<rtc::RtcpReceivingSession>();
  42. track->setMediaHandler(session);
  43. const rtc::SSRC targetSSRC = 42;
  44. track->onMessage(
  45. [&receivers, targetSSRC](rtc::binary message) {
  46. // This is an RTP packet
  47. auto rtp = reinterpret_cast<rtc::RtpHeader *>(message.data());
  48. rtp->setSsrc(targetSSRC);
  49. for (auto pc : receivers) {
  50. if (pc->track != nullptr && pc->track->isOpen()) {
  51. pc->track->send(message);
  52. }
  53. }
  54. },
  55. nullptr);
  56. pc->setLocalDescription();
  57. // Set the sender's answer
  58. std::cout << "Please copy/paste the answer provided by the SENDER: " << std::endl;
  59. std::string sdp;
  60. std::getline(std::cin, sdp);
  61. std::cout << "Got answer" << sdp << std::endl;
  62. json j = json::parse(sdp);
  63. rtc::Description answer(j["sdp"].get<std::string>(), j["type"].get<std::string>());
  64. pc->setRemoteDescription(answer);
  65. // For each receiver
  66. while (true) {
  67. auto r = std::make_shared<Receiver>();
  68. r->conn = std::make_shared<rtc::PeerConnection>();
  69. r->conn->onStateChange([](rtc::PeerConnection::State state) {
  70. std::cout << "State: " << state << std::endl;
  71. });
  72. r->conn->onGatheringStateChange([r](rtc::PeerConnection::GatheringState state) {
  73. std::cout << "Gathering State: " << state << std::endl;
  74. if (state == rtc::PeerConnection::GatheringState::Complete) {
  75. auto description = r->conn->localDescription();
  76. json message = {{"type", description->typeString()},
  77. {"sdp", std::string(description.value())}};
  78. std::cout << "Please copy/paste this offer to the RECEIVER: " << message
  79. << std::endl;
  80. }
  81. });
  82. rtc::Description::Video media("video", rtc::Description::Direction::SendOnly);
  83. media.addH264Codec(96);
  84. media.setBitrate(3000);
  85. media.addSSRC(targetSSRC, "video-send");
  86. r->track = r->conn->addTrack(media);
  87. r->track->onOpen([session]() {
  88. session->requestKeyframe(); // So the receiver can start playing immediately
  89. });
  90. r->track->onMessage([](rtc::binary var) {}, nullptr);
  91. r->conn->setLocalDescription();
  92. std::cout << "Please copy/paste the answer provided by the RECEIVER: " << std::endl;
  93. std::string sdp;
  94. std::getline(std::cin, sdp);
  95. std::cout << "Got answer" << sdp << std::endl;
  96. json j = json::parse(sdp);
  97. rtc::Description answer(j["sdp"].get<std::string>(), j["type"].get<std::string>());
  98. r->conn->setRemoteDescription(answer);
  99. receivers.push_back(r);
  100. }
  101. } catch (const std::exception &e) {
  102. std::cerr << "Error: " << e.what() << std::endl;
  103. }
  104. }