main.cpp 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. /*
  2. * libdatachannel client example
  3. * Copyright (c) 2020 Staz Modrzynski
  4. * Copyright (c) 2020 Paul-Louis Ageneau
  5. *
  6. * This program is free software; you can redistribute it and/or
  7. * modify it under the terms of the GNU General Public License
  8. * as published by the Free Software Foundation; either version 2
  9. * of the License, or (at your option) any later version.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with this program; If not, see <http://www.gnu.org/licenses/>.
  18. */
  19. #define _WINSOCK_DEPRECATED_NO_WARNINGS
  20. #include "rtc/rtc.hpp"
  21. #include <iostream>
  22. #include <memory>
  23. #include <nlohmann/json.hpp>
  24. using nlohmann::json;
  25. class Sender {
  26. rtc::PeerConnection conn;
  27. };
  28. struct Receiver {
  29. // TODO @paul.
  30. std::shared_ptr<rtc::PeerConnection> conn;
  31. std::shared_ptr<rtc::Track> track;
  32. };
  33. int main() {
  34. std::vector<std::shared_ptr<Receiver>> receivers;
  35. try {
  36. rtc::InitLogger(rtc::LogLevel::Info);
  37. auto pc = std::make_shared<rtc::PeerConnection>();
  38. pc->onStateChange(
  39. [](rtc::PeerConnection::State state) { std::cout << "State: " << state << std::endl; });
  40. pc->onGatheringStateChange([pc](rtc::PeerConnection::GatheringState state) {
  41. std::cout << "Gathering State: " << state << std::endl;
  42. if (state == rtc::PeerConnection::GatheringState::Complete) {
  43. auto description = pc->localDescription();
  44. json message = {{"type", description->typeString()},
  45. {"sdp", std::string(description.value())}};
  46. std::cout << "Please copy/paste this offer to the SENDER: " << message << std::endl;
  47. }
  48. });
  49. rtc::Description::Video media("video", rtc::Description::Direction::RecvOnly);
  50. media.addH264Codec(96);
  51. media.setBitrate(3000); // Request 3Mbps (Browsers do not encode more than 2.5MBps from a webcam)
  52. auto track = pc->addTrack(media);
  53. pc->setLocalDescription();
  54. auto session = std::make_shared<rtc::RtcpSession>();
  55. track->setRtcpHandler(session);
  56. const rtc::SSRC targetSSRC = 4;
  57. track->onMessage(
  58. [&receivers](rtc::binary message) {
  59. // This is an RTP packet
  60. auto rtp = (rtc::RTP*) message.data();
  61. rtp->ssrc = htonl(targetSSRC);
  62. for (auto pc : receivers) {
  63. if (pc->track != nullptr && pc->track->isOpen()) {
  64. pc->track->send(message);
  65. }
  66. }
  67. },
  68. nullptr);
  69. // Set the SENDERS Answer
  70. {
  71. std::cout << "Please copy/paste the answer provided by the SENDER: " << std::endl;
  72. std::string sdp;
  73. std::getline(std::cin, sdp);
  74. std::cout << "Got answer" << sdp << std::endl;
  75. json j = json::parse(sdp);
  76. rtc::Description answer(j["sdp"].get<std::string>(), j["type"].get<std::string>());
  77. pc->setRemoteDescription(answer);
  78. }
  79. // For each receiver
  80. while (true) {
  81. auto pc = std::make_shared<Receiver>();
  82. pc->conn = std::make_shared<rtc::PeerConnection>();
  83. pc->conn->onStateChange(
  84. [](rtc::PeerConnection::State state) { std::cout << "State: " << state << std::endl; });
  85. pc->conn->onGatheringStateChange([pc](rtc::PeerConnection::GatheringState state) {
  86. std::cout << "Gathering State: " << state << std::endl;
  87. if (state == rtc::PeerConnection::GatheringState::Complete) {
  88. auto description = pc->conn->localDescription();
  89. json message = {{"type", description->typeString()},
  90. {"sdp", std::string(description.value())}};
  91. std::cout << "Please copy/paste this offer to the RECEIVER: " << message << std::endl;
  92. }
  93. });
  94. rtc::Description::Video media("video", rtc::Description::Direction::SendOnly);
  95. media.addH264Codec(96);
  96. media.setBitrate(
  97. 3000); // Request 3Mbps (Browsers do not encode more than 2.5MBps from a webcam)
  98. media.addSSRC(targetSSRC, "video-send");
  99. pc->track = pc->conn->addTrack(media);
  100. pc->conn->setLocalDescription();
  101. auto session = std::make_shared<rtc::RtcpSession>();
  102. pc->track->setRtcpHandler(session);
  103. pc->track->onMessage([](rtc::binary var){}, nullptr);
  104. std::cout << "Please copy/paste the answer provided by the RECEIVER: " << std::endl;
  105. std::string sdp;
  106. std::getline(std::cin, sdp);
  107. std::cout << "Got answer" << sdp << std::endl;
  108. json j = json::parse(sdp);
  109. rtc::Description answer(j["sdp"].get<std::string>(), j["type"].get<std::string>());
  110. pc->conn->setRemoteDescription(answer);
  111. receivers.push_back(pc);
  112. }
  113. } catch (const std::exception &e) {
  114. std::cerr << "Error: " << e.what() << std::endl;
  115. }
  116. }