How to Share Desktop Screen and Application Windows to Multiple Browsers via WebRTC

A practical guide to using Happytime Portable RTC to capture your full desktop, a specific monitor, or an application window and stream it via WebRTC to multiple browser clients simultaneously. No plugins, no desktop sharing extensions — just standard WebRTC.

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

  1. Portable RTC installed and configured on the machine whose screen or window you want to share.
  2. Signal Server (SignalServer.exe + signalserver.cfg) deployed and running on a machine reachable by both Portable RTC and browser clients.
  3. 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.

portablertc.cfg — Global Settings
<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

portablertc.cfg — Full Desktop Output
<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

portablertc.cfg — Multi-Monitor Output
<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

portablertc.cfg — Window Capture Examples
<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=Notepad works for an untitled Notepad window, but once the file is saved as notes.txt, the title becomes notes.txt - Notepad and 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 screenliveN instead, 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.

portablertc.cfg — Multi-Source Desktop/Window/Audio
<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 Desktophttp://192.168.3.36:8080/webrtc?streamid=myapp/screenlive
Desktop + Audiohttp://192.168.3.36:8080/webrtc?streamid=myapp/screenlive+audiodevice
Second Monitorhttp://192.168.3.36:8080/webrtc?streamid=myapp/screenlive1
Excel Windowhttp://192.168.3.36:8080/webrtc?streamid=myapp/window=Microsoft Excel

Step 6: Launch and Verify

  1. Ensure SignalServer.exe is running and reachable.
  2. Save portablertc.cfg and launch Portable RTC. Check the logs for successful signal server connection.
  3. Open a browser on any computer that can reach the signal server and navigate to one of the stream URLs.
  4. 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> in portablertc.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.