Why Software-Based Screen Sharing?
Traditional screen sharing relies on browser extensions, third-party services, or operating-system-specific APIs. Portable RTC offers a different approach: it captures the desktop or application window natively in C, encodes it in real time, and serves it as a standard WebRTC stream. This enables:
- Multi-Browser Broadcasting: Multiple viewers can watch the same screen share simultaneously, each receiving an independent WebRTC peer connection.
- Remote Operations Monitoring: Stream industrial HMI screens, SCADA dashboards, or control room workstations to a centralized monitoring center.
- Training & Education: Instructor shares desktop, slides, or software demos to students' browsers without installing screen sharing tools.
- Selective Window Sharing: Share only a specific application window (e.g., a spreadsheet or monitoring dashboard) without exposing the rest of the desktop.
- Low Latency: Portable RTC's C-based capture and encoding pipeline delivers sub-second latency, suitable for interactive collaboration.
Prerequisites
- Portable RTC installed and configured on the machine whose screen or window you want to share.
- Signal Server (
SignalServer.exe+signalserver.cfg) deployed and running on a machine reachable by both Portable RTC and browser clients. - Modern browser (Chrome, Firefox, Edge, Safari) on the viewer side.
Understanding Screen Capture in Portable RTC
Portable RTC supports screen and window capture through the <output> block within an <application>. The <url> field in each <output> block specifies which capture mode to use when a browser requests a stream matching that URL pattern.
<url> Value |
Capture Mode | Description |
|---|---|---|
screenlive |
Full Desktop (Primary Monitor) | Captures the entire primary display including all visible windows, taskbar, and desktop background. |
screenlive+audiodevice |
Desktop + System Audio | Captures the primary display along with system audio from the default audio device. |
screenliveN |
Specific Monitor | Captures the display at index N, where N starts from 0 for the first monitor. screenlive0 is equivalent to screenlive. screenlive1 captures the second monitor. |
window=WINDOW_TITLE |
Specific Application Window | Captures only the window whose title bar text matches WINDOW_TITLE exactly. Other windows and the desktop are not included. |
Step 1: Configure Signal Server Connection
Set the global parameters in portablertc.cfg to connect Portable RTC to the signal server and enable the HTTP server that browsers will use.
<http_enable>1</http_enable>
<http_server_ip></http_server_ip>
<http_port>80</http_port>
<https_enable>0</https_enable>
<need_auth>0</need_auth>
<ipv6_enable>1</ipv6_enable>
<data_channel>0</data_channel>
<ws_signal_server>ws://192.168.3.36:8080</ws_signal_server>
<wss_signal_server>wss://192.168.3.36:5443</wss_signal_server>
<device_name>ScreenShare-PC</device_name>
<log_enable>1</log_enable>
<log_level>1</log_level>
<log_path></log_path>
<log_mode>loop</log_mode>
<log_max_size></log_max_size>
<log_max_index></log_max_index>
Set <ws_signal_server> to the address of your SignalServer.exe. Use a descriptive <device_name> to identify this screen-share source.
Step 2: Configure Full Desktop Sharing
Define an <output> block with <url>screenlive</url> to capture the entire primary display. This is the simplest configuration and works immediately.
Full Desktop Capture
<application>
<name>myapp</name>
<!-- Full desktop capture -->
<output>
<url>screenlive</url>
<video>
<codec>H264</codec>
<width></width>
<height></height>
<framerate></framerate>
<bitrate></bitrate>
</video>
<audio>
<codec>G711A</codec>
<samplerate>8000</samplerate>
<channels>1</channels>
<bitrate></bitrate>
</audio>
</output>
</application>
When a browser accesses the stream at http://signal-server:8080/webrtc?streamid=myapp/screenlive, Portable RTC matches the screenlive suffix against this <output> block and begins capturing the entire primary display.
Leaving <width>, <height>, and <framerate> empty means the engine uses the screen's native resolution and refresh rate. The bitrate is auto-calculated when set to 0 or left empty.
Step 3: Configure Multi-Monitor Capture
If you have multiple monitors, use screenliveN with N starting from 0 to capture a specific display. Each monitor gets its own <output> block with a unique URL, enabling independent browser access to each display.
Two Monitors as Separate Streams
<application>
<name>myapp</name>
<!-- Monitor 1 (Primary) -->
<output>
<url>screenlive0</url>
<video>
<codec>H264</codec>
<width></width>
<height></height>
<framerate></framerate>
<bitrate></bitrate>
</video>
</output>
<!-- Monitor 2 (Secondary) -->
<output>
<url>screenlive1</url>
<video>
<codec>H264</codec>
<width></width>
<height></height>
<framerate></framerate>
<bitrate></bitrate>
</video>
</output>
</application>
With this configuration, browsers access the two monitors at:
- Monitor 1:
http://192.168.3.36:8080/webrtc?streamid=myapp/screenlive0 - Monitor 2:
http://192.168.3.36:8080/webrtc?streamid=myapp/screenlive1
Step 4: Configure Application Window Capture
To share only a specific application without exposing the entire desktop, use the window=WINDOW_TITLE format. The window title must match exactly as it appears in the title bar.
Single Application Window Capture
<application>
<name>myapp</name>
<!-- Share Microsoft Excel only -->
<output>
<url>window=Microsoft Excel</url>
<video>
<codec>H264</codec>
<width></width>
<height></height>
<framerate></framerate>
<bitrate></bitrate>
</video>
</output>
<!-- Share a monitoring dashboard tool -->
<output>
<url>window=SCADA Dashboard</url>
<video>
<codec>H264</codec>
<width></width>
<height></height>
<framerate></framerate>
<bitrate></bitrate>
</video>
</output>
</application>
Important window capture notes:
- The target window must be open and not minimized. If the window is closed or minimized, the stream will show a blank or frozen frame.
- The window title must match character-for-character. For example,
window=Notepadworks for an untitled Notepad window, but once the file is saved asnotes.txt, the title becomesnotes.txt - Notepadand the match will fail. - For applications with dynamic titles (e.g., browsers where the title changes with each tab), consider capturing the entire monitor with
screenliveNinstead, and position the target window on that monitor. - If two windows share the same title, the first match found by the window enumeration API is selected. This behavior is platform-dependent.
Step 5: Combine Desktop, Window, and Audio Capture
You can define multiple <output> blocks in a single application to serve different capture modes simultaneously. Below is a complete configuration combining full desktop, a second monitor, an application window, and desktop-with-audio capture — all accessible via different streamid values.
<application>
<name>myapp</name>
<!-- Full desktop (video only) -->
<output>
<url>screenlive</url>
<video>
<codec>H264</codec>
<width></width>
<height></height>
<framerate>15</framerate>
<bitrate>4096</bitrate>
</video>
</output>
<!-- Desktop + system audio (for presentations with narration) -->
<output>
<url>screenlive+audiodevice</url>
<video>
<codec>H264</codec>
<width></width>
<height></height>
<framerate>25</framerate>
<bitrate></bitrate>
</video>
<audio>
<codec>OPUS</codec>
<samplerate>48000</samplerate>
<channels>1</channels>
<bitrate></bitrate>
</audio>
</output>
<!-- Second monitor -->
<output>
<url>screenlive1</url>
<video>
<codec>H264</codec>
<width></width>
<height></height>
<framerate>10</framerate>
<bitrate>2048</bitrate>
</video>
</output>
<!-- Specific application window -->
<output>
<url>window=Microsoft Excel</url>
<video>
<codec>H264</codec>
<width></width>
<height></height>
<framerate>15</framerate>
<bitrate>2048</bitrate>
</video>
</output>
</application>
Browser access URLs for this configuration:
| Stream | Browser URL |
|---|---|
| Full Desktop | http://192.168.3.36:8080/webrtc?streamid=myapp/screenlive |
| Desktop + Audio | http://192.168.3.36:8080/webrtc?streamid=myapp/screenlive+audiodevice |
| Second Monitor | http://192.168.3.36:8080/webrtc?streamid=myapp/screenlive1 |
| Excel Window | http://192.168.3.36:8080/webrtc?streamid=myapp/window=Microsoft Excel |
Step 6: Launch and Verify
- Ensure
SignalServer.exeis running and reachable. - Save
portablertc.cfgand launch Portable RTC. Check the logs for successful signal server connection. - Open a browser on any computer that can reach the signal server and navigate to one of the stream URLs.
- Open additional browser tabs (or different browsers/computers) with the same URL. Each viewer gets an independent WebRTC peer connection, so multiple viewers can watch the same desktop simultaneously without additional load on the screen-share host.
Output Parameter Tuning for Screen Content
Screen content (text, UI elements, dashboards) has different characteristics than natural video. Tune the encoding parameters accordingly:
| Scenario | Recommended Settings | Rationale |
|---|---|---|
| Static dashboards / text-heavy screens | framerate=10, bitrate=2048 |
Low framerate is sufficient for mostly static content. Higher bitrate ensures text remains legible. |
| Software demos / training | framerate=15, bitrate=4096 |
Moderate framerate for smooth cursor and window movement. Higher bitrate preserves UI detail. |
| Full-motion content (videos, animations) | framerate=25, bitrate=8192 |
High framerate for smooth motion. Maximum bitrate to avoid compression artifacts on fast-changing content. |
| 4K / high-DPI displays | width=1920, height=1080 |
Downscale to 1080p to reduce bandwidth. Most browsers display WebRTC in a viewport smaller than 4K anyway. |
| Low-bandwidth links | framerate=5, bitrate=1024, width=1280, height=720 |
Minimum settings for watchable screen sharing over constrained networks (e.g., mobile, satellite). |
Troubleshooting
| Issue | Possible Cause | Resolution |
|---|---|---|
| Stream shows a black screen | The display is off, the monitor is disconnected, or the target window is minimized. | Ensure the monitor is powered on and connected. For window capture, make sure the target window is open and visible (not minimized). Check that the display is not locked or in screensaver mode. |
| Window capture shows wrong window or no window | Window title does not match exactly, or the window was closed or renamed. | Copy the exact title from the title bar. Use Task Manager to verify the process and window title. For dynamic titles, switch to screenliveN mode and dedicate a monitor to that application. |
| High CPU usage during full desktop capture | Screen resolution or framerate is too high for the encoding hardware. | Reduce <framerate> (e.g., from 25 to 15) and/or set explicit <width> and <height> (e.g., 1920x1080) to lower the encoding workload. |
| Multiple viewers cause lag on the host | Each additional WebRTC peer connection adds encoding overhead when transcoding is required. | The demo version supports up to 4 concurrent streams. If viewers exceed this limit, upgrade to the release version (up to 100 streams). Reduce <framerate> and <bitrate> to lower per-stream encoding cost. |
| No audio in the stream | Basic screenlive captures video only. |
Use screenlive+audiodevice to include system audio. Verify that the system audio device is enabled and not muted in the OS sound settings. |
| Text in the stream is blurry or unreadable | Bitrate too low for the screen resolution, or resolution downscaling is too aggressive. | Increase <bitrate> (try 4096-8192 kb/s for 1080p). Avoid setting <width>/<height> smaller than 1280x720 for text-heavy content. Consider using H.265 if the camera supports it and browser compatibility is not a concern. |
Best Practices
- Use Separate Output Blocks for Different Quality Tiers: Configure one
<output>at full quality for local/LAN viewers and another at reduced quality for remote viewers. Point different browser groups to different stream URLs. - Avoid Sharing Sensitive Information: Full desktop capture exposes everything — browser tabs, notifications, file names. Use
window=capture for presentations and demos to limit what viewers can see. - Set Appropriate Framerate for the Content: 10-15 fps for static dashboards and documents. 25-30 fps only if you are sharing video or highly animated content. Higher framerates increase CPU and bandwidth proportionally.
- Test Window Titles Before Production: Run the window capture configuration, verify the correct window is streamed, then save the exact title string. Window titles can include trailing spaces or invisible Unicode characters that cause matching failures.
- Use WSS for Production: In deployments where browsers access the signal server over the internet, enable HTTPS in
signalserver.cfg(<https_enable>1</https_enable>) and configure<wss_signal_server>inportablertc.cfg. This encrypts both signaling and media. - Monitor CPU Usage on the Host: Use a single stream initially and monitor CPU usage. Each additional concurrent viewer can increase encoding load. On resource-constrained hosts (embedded, low-power PCs), limit concurrent streams or reduce encoding quality.