WebStream
The WebStream plugin enables Tellusim applications to stream real-time rendered output directly to modern web browsers. It uses MP4 segmented streaming to deliver low-latency video over the network, making it ideal for remote rendering, application mirroring, and embedding live 3D visualizations into web-based dashboards or control systems.
The plugin receives encoded rendered frames, transmits them to connected browsers, and handles input events (mouse and keyboard) from the web session to remotely control the application.
The hardware H264 encoder plugin can be used as a stream supplier for efficient video encoding.
#include <network/webstream/include/TellusimWebStream.h>
Example
The following example demonstrates how to set up Tellusim application with the WebStream plugin to stream rendered frames to a browser in real time:
// Initialize the WebStream application with command-line arguments
WebStreamApp stream(argc, argv);
// If this process is the server
if(!stream.isSession()) {
// Create the web server instance with the stream app configuration
WebStreamServer server(stream);
// Set the web server document root directory
server.setRoot(String("www/"));
// Initialize the web server on the configured port
if(!server.init(stream.getPort())) return false;
// Start running the web server to listen for browser connections
if(!server.run()) return false;
return true;
}
// If this process is a client session
// Create Tellusim application instance
App app(argc, argv);
if(!app.create()) return false;
// Open a socket connection to the local web server
Socket socket;
if(!socket.open("localhost", stream.getPort())) return false;
if(!socket.connect(2) || !socket.setBlock(false) || !socket.setDelay(false)) return false;
// Create an encoder window to capture and encode rendered frames
ENCODER_WINDOW window = ENCODER_WINDOW(app.getPlatform(), app.getDevice());
// Configure encoder parameters from the stream app settings
window.setFramerate(stream.getFramerate());
window.setBitrate(stream.getBitrate() * 1024 * 1024);
window.setKeyrate(stream.getKeyrate());
window.setSize(app.getWidth(), app.getHeight());
// Define the encoder callback to send encoded frames to the browser via the socket
window.setEncoderCallback([&](const uint8_t *data, size_t size, uint64_t frame) {
if(socket.isOpened()) {
Blob stream_blob;
stream_blob.writeu64(window.getPresentTime());
stream_blob.writeu32((uint32_t)size);
stream_blob.write(data, size);
if(socket.write(stream_blob.getData(), stream_blob.getSize()) != stream_blob.getSize()) {
TS_LOGF(Error, "%s: can't write encoded stream\n", argv[0]);
window.stop();
}
}
});