Baike.dev
All toolsAI codingTrendingOpen sourceNewsSubmit
Log in
< Back to tools
I

icey

> 编程语言
Open source

Real-time media stack and lightweight libwebrtc alternative, built in C++20

1.4K stars0 likes0 views
WebsiteGitHub

About

Real-time media stack and lightweight libwebrtc alternative, built in C++20

icey

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.

// HEVC + AAC, captured through encoder to network in one zero-copy pipeline
av::EncoderOptions opts;
opts.oformat = {"mpegts", "mpegts",
    {"H265", "hevc_videotoolbox", 1920, 1080, 60},
    {"AAC",  "aac", 2, 48000}};

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

icey is the connective tissue: a modular C++20 toolkit that pulls FFmpeg, libuv, OpenSSL, llhttp, libdatachannel, Symple, STUN, and TURN into one runtime model. Capture, encode, transport, signalling, and relay. Core third-party code is pulled in by CMake; system TLS and media dependencies are auto-detected. Builds in minutes.

Documentation | Changelog | Contributing | LGPL-2.1+

Rust Bindings

Rust bindings are split into two crates:

  • icey is the safe Rust wrapper most users should depend on.
  • icey-sys is the raw bindgen layer over icey's graft C ABI.

Both crates use https://0state.com/icey as their Cargo homepage and https://0state.com/icey/docs as their Cargo documentation URL so crates.io, docs.rs, lib.rs, Libraries.io, and other registry crawlers resolve the Rust package listings back to the product and docs surfaces.

Fastest Path

If you want the shortest path from zero to browser video, use the published icey-server image from the separate icey-cli repo.

One command. One URL. One click.

docker run --rm --network host 0state/icey-server:latest

Then open http://localhost:4500 and click Watch on the icey peer.

This express path ships from nilstate/icey-cli and starts stream mode with the bundled demo source. If you want the repo-backed app path for local edits or richer runtime control, use the separate icey-cli app surface on top of the core icey modules.

Why icey

libWebRTC (Google) libdatachannel GStreamer icey 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. icey gives you the pipe, the water, and the faucet.

Architecture

Everything flows through PacketStream. Plug in a source, chain processors, attach a sink. Borrowed packets stay zero-copy until the first queue or retained adapter; that boundary is explicit in the graph. The pipeline handles backpressure, frame dropping, and teardown so you don't. Nothing runs that you didn't ask for. Decoded branches can feed vision and speech processors without changing the transport path.

…

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. Includes a simple data channel for control messages alongside the media stream.

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 icey 72,209 1.43ms Go 1.25 net/http 53,878 2.31ms Node.js v20 45,514 3.56ms

icey 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/perf/ for the cross-stack methodology, and src/http/bench/ for the reportable HTTP microbenchmarks.

Docs Start Here

If you just want the right page:

  • Run icey-server: docs/run/index.md
  • Install icey-server: docs/run/install.md
  • Deploy to production: docs/operate/deploy.md
  • Use icey as a library: Quick Start below
  • Recipes (HTTP, WebSocket, TURN, WebRTC): docs/recipes/
  • Module map and dependency picture: docs/modules.md
  • HTTP and WebSocket: docs/modules/http.md
  • TURN relay: docs/modules/turn.md
  • WebRTC media flows: docs/modules/webrtc.md
  • Full docs landing page: docs/index.md

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. icey fetches its core bundled third-party code automatically:

Dependency Version libuv 1.50 llhttp 9.2.1 nlohmann/json 3.11.3 zlib 1.3.1

System dependencies such as OpenSSL 3.x, FFmpeg 5+/6+/7+, and OpenCV 3.0+ are auto-detected when present. libdatachannel is fetched automatically when building the webrtc module.

Build from source

git clone https://github.com/nilstate/icey.git
cd icey
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(icey
  GIT_REPOSITORY https://github.com/nilstate/icey.git
  GIT_TAG 2.5.0
)
FetchContent_MakeAvailable(icey)
target_link_libraries(myapp PRIVATE icey::base icey::net icey::http)

find_package

After installing (cmake --install build):

find_package(icey REQUIRED)
target_link_libraries(myapp PRIVATE icey::base icey::net icey::http)

Package Managers

Public registry submission is not live yet, but the repo now carries local package-manager support:

…

The Conan recipe lives at packaging/conan/conanfile.py, the vcpkg overlay port lives at packaging/vcpkg/icey/, the Arch packaging files live at packaging/arch/, the Homebrew tap formulae live at packaging/homebrew/Formula/, and the Debian / PPA seed lives at packaging/debian/debian/.

For the release/tag/archive-pin flow behind those package managers, use docs/releasing.md.

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.media.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

16 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) speech Audio intelligence primitives for decoded media streams vision Video intelligence primitives for sampled decoded frames 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 graft Native plugin ABI and 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

GitHub Issues· 0 open

View all on GitHub

No open issues yet, or sync has not completed.

Highlights

  • •icey is the safe Rust wrapper most users
  • •icey-sys is the raw bindgen layer
  • •Run icey-server: docs/run/index.md
  • •Install icey-server: docs/run/install.md
  • •Deploy to production: docs/operate/deploy.md
  • •Use icey as a library: Quick Start below
  • •Recipes (HTTP, WebSocket, TURN, WebRTC): docs/recipes/
  • •Module map and dependency picture: docs/modules.md
  • •HTTP and WebSocket: docs/modules/http.md
  • •TURN relay: docs/modules/turn.md

> Tags

C++

No comments yet. Be the first to share.

> Details

PublishedAug 1, 2026
UpdatedSep 17, 2026
Category编程语言
PricingOpen source

> Related tools

T
TypeScript
JavaScript 的超集,为前端与全栈提供静态类型
P
Python
通用编程语言,广泛用于 Web、数据与 AI
G
Go
Google 推出的简洁高效系统语言