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

LibSourcey

C++ Networking Evolved

Circle CI Doxygen

LibSourcey is a collection of cross platform C++14 modules and classes that provide developers with an arsenal for rapidly developing high performance network based p2p and media streaming applications. Think of it as the power and performance of libuv combined with the features of FFmpeg, OpenCV and WebRTC, all integrated with the ease and readability of the stl (C++ Standard Library).

Basic features

Getting started

See the installation guides in the docs to get started playing with LibSourcey.

A few examples

What better way to get acquainted with a new library then with some tasty code examples.

HTTP echo server

Lets start with the classic HTTP echo server, which looks something like this:

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();

Pretty neat right? Its crazy fast too, especially on Linux kernel 3.9 or newer where its optimized to use of kernel level multicore socket load balancing. Don't take our word for it though, here are some benchmarks using wrk:

LibSourcey httpechoserver

$ wrk -d10s --timeout 2s http://localhost:1337 Running 10s test @ http://localhost:1337 2 threads and 10 connections Thread Stats Avg Stdev Max +/- Stdev Latency 265.76us 472.62us 12.42ms 97.51% Req/Sec 18.84k 1.26k 21.57k 74.50% 375060 requests in 10.01s, 20.39MB read Requests/sec: 37461.50 Transfer/sec: 2.04MB

Nodejs echo server

$ wrk -d10s --timeout 2s http://localhost:1337 Running 10s test @ http://localhost:1337 2 threads and 10 connections Thread Stats Avg Stdev Max +/- Stdev Latency 502.70us 715.11us 14.83ms 97.90% Req/Sec 11.69k 1.46k 14.52k 70.50% 232667 requests in 10.01s, 21.97MB read Requests/sec: 23236.33 Transfer/sec: 2.19MB

As you can see the httpechoserver is almost twice as fast as the dead simple nodejs echo server, which is not a bad performance gain over one of the web's leading technologies thats touted for it's performance. Check the httpechoserver sample for the full code, including the nodejs echo server we used for benchmarking.

Processes

Interacting with system processes and piping IO doesn't have to be painful. The following code will run the ping sourcey.com and with stdio and exit callbacks:

Process proc{ "ping", "sourcey.com" }; proc.onstdout = [](std::string line) { // handle process output }; proc.onexit = [](std::int64_t status) { // handle process exit }; proc.spawn();

// write some random data to the stdin pipe proc.in() << "random data"

Packet Stream

A good starting point for learning LibSourcey is the PacketStream, which lets you create a dynamic delegate chain for piping, processing and outputting arbitrary data packets. This method of layering packet processors and makes it possible to develop complex data processing applications on the fly.

For example, the code below captures a live webcam stream, encodes it into H.264, and then finally broadcasts it in realtime over the internet:

// Create a PacketStream to pass packets from the // input device captures -> encoder -> socket PacketStream stream;

// Setup the encoder options av::EncoderOptions options; options.oformat = av::Format{"MP4", "mp4", { "H.264", "libx264", 640, 480, 25, 48000, 128000, "yuv420p" }, { "AAC", "aac", 2, 44100, 64000, "fltp" }};

// Create a device manager instance to enumerate system devices av::DeviceManager devman; av::Device device;

// Create and attach the default video capture av::VideoCapture::Ptr video; if (devman.getDefaultCamera(device)) { video.open(device.id, 640, 480); video.getEncoderFormat(options.iformat); stream.attachSource(video, true); }

// Create and attach the default audio capture av::AudioCapture::Ptr audio; if (devman.getDefaultMicrophone(device)) { audio.open(device.id, 2, 44100); audio.getEncoderFormat(options.iformat); stream.attachSource(audio, true); }

// Create and attach the multiplex encoder av::MultiplexPacketEncoder::Ptr encoder(options); stream.attach(encoder);

// Attach the output net::Socket instance (instantiated elsewhere) // to broadcast encoded packets over the network stream.attach(socket);

// Start the stream // This method call will start the device captures and begin // pumping encoded media into the output socket stream.start();

There are plenty more demos and sample code to play with over on the examples page.

Contributors

A massive thanks to everyone who has contributed to making LibSourcey awesome:

Contributing

Pull Requests are always welcome, so if you fix or make anything better then feel free to float a PR back upstream :)

  1. Fork LibSourcey on Github
  2. Create your feature branch (git checkout -b my-new-feature)
  3. Commit your changes (git commit -am 'Add some feature')
  4. Push to the branch (git push origin my-new-feature)
  5. Create new Pull Request