/** * 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 #include #include #include #include #include #ifdef _WIN32 #define _WINSOCK_DEPRECATED_NO_WARNINGS #include #else #include #include #include 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(); 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(&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(&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(), j["type"].get()); 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(buffer); rtp->setSsrc(ssrc); track->send(reinterpret_cast(buffer), len); } } catch (const std::exception &e) { std::cerr << "Error: " << e.what() << std::endl; } }