main.cpp 3.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  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 <utility>
  24. #include <nlohmann/json.hpp>
  25. #ifdef _WIN32
  26. #include <winsock2.h>
  27. #else
  28. #include <arpa/inet.h>
  29. typedef int SOCKET;
  30. #endif
  31. using nlohmann::json;
  32. int main() {
  33. try {
  34. rtc::InitLogger(rtc::LogLevel::Debug);
  35. auto pc = std::make_shared<rtc::PeerConnection>();
  36. pc->onStateChange(
  37. [](rtc::PeerConnection::State state) { std::cout << "State: " << state << std::endl; });
  38. pc->onGatheringStateChange([pc](rtc::PeerConnection::GatheringState state) {
  39. std::cout << "Gathering State: " << state << std::endl;
  40. if (state == rtc::PeerConnection::GatheringState::Complete) {
  41. auto description = pc->localDescription();
  42. json message = {{"type", description->typeString()},
  43. {"sdp", std::string(description.value())}};
  44. std::cout << message << std::endl;
  45. }
  46. });
  47. SOCKET sock = socket(AF_INET, SOCK_DGRAM, 0);
  48. sockaddr_in addr;
  49. addr.sin_addr.s_addr = inet_addr("127.0.0.1");
  50. addr.sin_port = htons(5000);
  51. addr.sin_family = AF_INET;
  52. rtc::Description::Video media("video", rtc::Description::Direction::RecvOnly);
  53. media.addH264Codec(96);
  54. media.setBitrate(
  55. 3000); // Request 3Mbps (Browsers do not encode more than 2.5MBps from a webcam)
  56. auto track = pc->addTrack(media);
  57. auto session = std::make_shared<rtc::RtcpReceivingSession>();
  58. track->setRtcpHandler(session);
  59. track->onMessage(
  60. [session, sock, addr](rtc::binary message) {
  61. // This is an RTP packet
  62. sendto(sock, reinterpret_cast<const char *>(message.data()), message.size(), 0,
  63. reinterpret_cast<const struct sockaddr *>(&addr), sizeof(addr));
  64. },
  65. nullptr);
  66. pc->setLocalDescription();
  67. std::cout << "Expect RTP video traffic on localhost:5000" << std::endl;
  68. std::cout << "Please copy/paste the answer provided by the browser: " << std::endl;
  69. std::string sdp;
  70. std::getline(std::cin, sdp);
  71. std::cout << "Got answer" << sdp << std::endl;
  72. json j = json::parse(sdp);
  73. rtc::Description answer(j["sdp"].get<std::string>(), j["type"].get<std::string>());
  74. pc->setRemoteDescription(answer);
  75. std::cout << "Press any key to exit." << std::endl;
  76. std::cin >> sdp;
  77. } catch (const std::exception &e) {
  78. std::cerr << "Error: " << e.what() << std::endl;
  79. }
  80. }