GitHub - sourcey/libsourcey: C++14 evented IO libraries for high performance networking and media based applications

CI License: LGPL-2.1+

The C++ Media Stack

WebRTC, FFmpeg, and async networking in one toolkit. No Google monolith. No dependency hell. No fighting three build systems to get a frame on screen.

// The core of a WebRTC media server
PacketStream stream;
stream.attachSource(capture.get());
stream.attach(&session->media().videoSender(), 5);
stream.start();

LibSourcey is the connective tissue: a modular C++20 toolkit that unifies FFmpeg, libuv, OpenSSL, and libdatachannel into a single composable pipeline. Capture, encode, transport, signalling, and relay. All dependencies managed via CMake FetchContent. Builds in minutes.

Documentation | Changelog | Contributing | LGPL-2.1+

Why LibSourcey

libWebRTC (Google) libdatachannel GStreamer LibSourcey
Build system GN/Ninja CMake Meson CMake
Build time Hours Minutes 30+ min Minutes
Binary size 50MB+ Small Large Small
SSL BoringSSL (conflicts) OpenSSL OpenSSL OpenSSL
Media codecs Bundled None GObject plugins FFmpeg (any codec)
Capture/encode Included No Plugin pipeline PacketStream pipeline
Signalling No No No Symple (built-in)
TURN server No No No RFC 5766 (built-in)
Language C++ C++17 C/GObject C++20

libdatachannel gives you the WebRTC transport pipe. LibSourcey gives you the pipe, the water, and the faucet.

Architecture

Everything flows through PacketStream. Plug in a source, chain processors, attach a sink. The pipeline handles backpressure, frame dropping, and teardown so you don't. Nothing runs that you didn't ask for.

┌─────────────────────────────────────────────────────────────────┐
│                        PacketStream                             │
│                                                                 │
│  ┌──────────┐    ┌──────────────┐    ┌───────────────────────┐  │
│  │  Source  │───▶│  Processor   │───▶│        Sink           │  │
│  │          │    │              │    │                       │  │
│  │ Camera   │    │ FFmpeg H.264 │    │ WebRTC Track Sender   │  │
│  │ File     │    │ Opus encode  │    │ Network socket        │  │
│  │ Network  │    │ OpenCV       │    │ File recorder         │  │
│  │ Device   │    │ Custom       │    │ HTTP response         │  │
│  └──────────┘    └──────────────┘    └───────────────────────┘  │
└─────────────────────────────────────────────────────────────────┘

WebRTC send path:
  MediaCapture → VideoEncoder → WebRtcTrackSender → [libdatachannel]
                                                        │
  Browser ◀── RTP/SRTP ◀── DTLS ◀── ICE (libjuice) ◀───┘
                                      │
                              LibSourcey TURN server
                              (relay for symmetric NATs)

WebRTC receive path:
  [libdatachannel] → WebRtcTrackReceiver → FFmpeg decode → file/display
        │
        └─── ICE → DTLS → SRTP decrypt → RTP depacketise → raw frames

Signalling (Symple v4):
  C++ server/client ◀──── WebSocket ────▶ Browser (symple-client-player)
  Auth, presence, rooms, call protocol (init/accept/offer/answer/candidate)

Camera to browser in 150 lines. Browser to file in 130. The pipeline handles the plumbing.

What You Can Build

Stream a webcam to any browser

150 lines of C++. Camera capture, H.264 encoding, WebRTC transport, Symple signalling. Open a browser, see video. No plugins, no Google, no pain.

// Accept call, wire up the pipeline, stream
session.IncomingCall += [&](const std::string& peerId) {
    session.accept();
};

session.StateChanged += [&](wrtc::PeerSession::State state) {
    if (state == wrtc::PeerSession::State::Active) {
        stream.attachSource(capture.get());
        stream.attach(&session->media().videoSender(), 5);
        stream.start();
    }
};

See src/webrtc/samples/webcam-streamer/ or read WebRTC in 150 Lines of C++.

Record a browser's camera server-side

Browser sends WebRTC, your C++ server decodes with FFmpeg, writes to any format. Video depositions, telehealth recording, proctoring - server-side recording without cloud vendor lock-in.

See src/webrtc/samples/media-recorder/.

Stream any video file to a browser

Feed an MP4 in, get a real-time WebRTC stream out. Data channel for seek commands. Build your own streaming service.

See src/webrtc/samples/file-streamer/.

Run your own TURN relay

Production-grade RFC 5766 TURN server with channel binding and TCP support. Stop paying for hosted TURN. ~30% of real-world WebRTC connections need relay through symmetric NATs; this handles them.

See src/turn/samples/turnserver/.

HTTP that outperforms Go

72,000 req/s with keep-alive on a single-core micro VM. Built on the same libuv + llhttp that powers Node.js, minus the runtime, GC, and language bridge.

Server Req/sec Latency
Raw libuv+llhttp 96,088 1.04ms
LibSourcey 72,209 1.43ms
Go 1.25 net/http 53,878 2.31ms
Node.js v20 45,514 3.56ms

LibSourcey delivers 75% of raw libuv throughput while providing a complete HTTP stack (connection management, header construction, WebSocket upgrade, streaming responses). It outperforms Go's net/http by 34% and Node.js by 59%. All three share the same foundation (libuv for async IO, llhttp for HTTP parsing); the difference is pure runtime overhead.

See src/http/samples/httpbenchmark/ for methodology.

Quick Start

Requirements

Platform Compiler
Linux GCC 12+ or Clang 15+
macOS AppleClang 15+ (Xcode 15+)
Windows MSVC 2022 (Visual Studio 17+)

CMake 3.21+ and pkg-config (Linux/macOS) required. Everything else is fetched automatically:

Dependency Version
libuv 1.50
llhttp 9.2.1
OpenSSL 3.x
nlohmann/json 3.11.3
zlib 1.3.1

Optional: FFmpeg 5+/6+/7+ (-DWITH_FFMPEG=ON), OpenCV 3.0+ (-DWITH_OPENCV=ON), libdatachannel (-DWITH_LIBDATACHANNEL=ON).

Build from source

git clone https://github.com/sourcey/libsourcey.git
cd libsourcey
cmake -B build -DCMAKE_BUILD_TYPE=Release -DBUILD_TESTS=ON
cmake --build build --parallel $(nproc)
ctest --test-dir build --output-on-failure

CMake FetchContent

include(FetchContent)
FetchContent_Declare(libsourcey
  GIT_REPOSITORY https://github.com/sourcey/libsourcey.git
  GIT_TAG v2.1.0
)
FetchContent_MakeAvailable(libsourcey)
target_link_libraries(myapp PRIVATE scy_base scy_net scy_http)

find_package

After installing (cmake --install build):

find_package(LibSourcey REQUIRED)
target_link_libraries(myapp PRIVATE scy_base scy_net scy_http)

Code Examples

Media pipeline

Camera to encoder to network:

PacketStream stream;
stream.attachSource(videoCapture);
stream.attach(new av::MultiplexPacketEncoder(opts), 5);
stream.attach(socket, 10);
stream.start();

HTTP server

http::Server srv{ "127.0.0.1", 1337 };
srv.Connection += [](http::ServerConnection::Ptr conn) {
    conn->Payload += [](http::ServerConnection& conn, const MutableBuffer& buffer) {
        conn.send(bufferCast<const char*>(buffer), buffer.size());
        conn.close();
    };
};
srv.start();

WebRTC peer session

wrtc::PeerSession::Config config;
config.rtcConfig.iceServers.emplace_back("stun:stun.l.google.com:19302");
config.mediaOpts.videoCodec = av::VideoCodec("H264", "libx264", 1280, 720, 30);

wrtc::SympleSignaller signaller(client);
wrtc::PeerSession session(signaller, config);

session.IncomingCall += [&](const std::string& peerId) {
    session.accept();
};

session.StateChanged += [&](wrtc::PeerSession::State state) {
    if (state == wrtc::PeerSession::State::Active)
        startStreaming(session);
};

Modules

14 modules. Include only what you need; dependencies resolve automatically.

Module What it does
base Event loop (libuv), signals, streams, logging, filesystem, timers
crypto Hashing, HMAC, RSA, X509 (OpenSSL 3.x)
net TCP, SSL/TLS, UDP sockets, DNS
http HTTP server/client, WebSocket, cookies, streaming, keep-alive
json JSON serialisation (nlohmann/json)
av FFmpeg capture, encode, decode, record, stream (FFmpeg 5/6/7)
symple Real-time messaging, presence, rooms, WebRTC call signalling
stun RFC 5389 STUN for NAT traversal
turn RFC 5766 TURN relay server
webrtc WebRTC via libdatachannel: media bridge, peer sessions, codec negotiation
archo ZIP/archive handling
pluga Plugin system (shared library loading)
pacm Package manager for plugin distribution
sched Task scheduler for deferred/periodic jobs

Contributors

  • Kam Low (@auscaster) - Creator and primary developer
  • Sergey Parfenyuk (@sparfenyuk) - macOS compile fixes, type corrections, buffer handling
  • Yury Shubin (@yuryshubin) - iOS build toolchain and platform fixes
  • Norm Ovenseri (@normano) - Apple/FFmpeg builds, AVFoundation support, verbose logging
  • Igor Lutsyk (@lutsykigor) - WebRTC/WebSocket fixes, OpenCV+WebRTC sample app, Firefox compatibility
  • Kryton (@Malesio) - Segfault fixes and Valgrind cleanup
  • Vinci Xu (@VinciShark) - Windows documentation, testing and updates
  • Michael Fig (@michael-fig) - Compiler flags for building without FFmpeg
  • Stanislav Kapulkin (@kapulkin) - WebRTC modernisation and macOS compile definitions
  • Thomas Reichhart (@blackforest-tom) - FFmpeg constant updates and ARM build fixes
  • Artem Suprunov (@artemiuzzz) - WebRTC null pointer fix and library path resolution
  • Hyunuk Kim (@surinkim) - Windows std::codecvt unicode conversion fix
  • Cameron Smith (@cksmith) - Git line ending normalisation
  • Damian Zelim (@ZelimDamian) - OS X compiler flag fixes
  • Alexey (@deilos) - Cross-platform FFmpeg build script fixes

Contributing

PRs welcome. See the contributing guide for code style, tests, and workflow.