123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899 |
- /**
- * libdatachannel media sender 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 <cstddef>
- #include <iostream>
- #include <memory>
- #include <stdexcept>
- #include <utility>
- #include <nlohmann/json.hpp>
- #ifdef _WIN32
- #define _WINSOCK_DEPRECATED_NO_WARNINGS
- #include <winsock2.h>
- #else
- #include <arpa/inet.h>
- #include <netinet/in.h>
- #include <sys/socket.h>
- typedef int SOCKET;
- #endif
- using nlohmann::json;
- const int BUFFER_SIZE = 2048;
- int main() {
- try {
- rtc::InitLogger(rtc::LogLevel::Debug);
- 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 << message << std::endl;
- }
- });
- SOCKET sock = socket(AF_INET, SOCK_DGRAM, 0);
- struct sockaddr_in addr = {};
- addr.sin_family = AF_INET;
- addr.sin_addr.s_addr = inet_addr("127.0.0.1");
- addr.sin_port = htons(6000);
- if (bind(sock, reinterpret_cast<const sockaddr *>(&addr), sizeof(addr)) < 0)
- throw std::runtime_error("Failed to bind UDP socket on 127.0.0.1:6000");
- int rcvBufSize = 212992;
- setsockopt(sock, SOL_SOCKET, SO_RCVBUF, reinterpret_cast<const char *>(&rcvBufSize),
- sizeof(rcvBufSize));
- const rtc::SSRC ssrc = 42;
- rtc::Description::Video media("video", rtc::Description::Direction::SendOnly);
- media.addH264Codec(96); // Must match the payload type of the external h264 RTP stream
- media.addSSRC(ssrc, "video-send");
- auto track = pc->addTrack(media);
- pc->setLocalDescription();
- std::cout << "RTP video stream expected on localhost:6000" << std::endl;
- std::cout << "Please copy/paste the answer provided by the browser: " << std::endl;
- std::string sdp;
- std::getline(std::cin, sdp);
- json j = json::parse(sdp);
- rtc::Description answer(j["sdp"].get<std::string>(), j["type"].get<std::string>());
- pc->setRemoteDescription(answer);
- // Receive from UDP
- char buffer[BUFFER_SIZE];
- int len;
- while ((len = recv(sock, buffer, BUFFER_SIZE, 0)) >= 0) {
- if (len < sizeof(rtc::RtpHeader) || !track->isOpen())
- continue;
- auto rtp = reinterpret_cast<rtc::RtpHeader *>(buffer);
- rtp->setSsrc(ssrc);
- track->send(reinterpret_cast<const std::byte *>(buffer), len);
- }
- } catch (const std::exception &e) {
- std::cerr << "Error: " << e.what() << std::endl;
- }
- }
|