npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

electron-window-rtc

v1.1.3

Published

Exchange media streams between Electron windows with WebRTC.

Downloads

48

Readme

electron-window-rtc

Inspired by electron-peer-connection, electron-window-rtc is a zero-dependency package that allows sharing medias between Electron windows through WebRTC with (almost) zero-latency, depending on application configuration.

It works by creating a main process events hub that acts as a signaling server for the windows through Electron's IPC. Once windows are registered, each renderer process creates a WindowRTCPeerConnection to another window and begins to send/receive media streams.

This package was primarily released to handle video/canvas manipulation before sending it to a window rendered offscreen passed to the Syphon framework with same author's node-syphon package.

Donate

If you find this package useful, contribute to the author's open source work by donating here! Thank you!

paypal

Table of Contents

Install

npm i -s electron-window-rtc
yarn add electron-window-rtc

Usage

See Electron+Vue example for a complete integration example.

Main process

// WindowRTCMain is a singleton.
import { WindowRTCMain } from 'electron-window-rtc';

const senderWindow: BrowserWindow = createWindow(); // Left to application.
const receiverWindow: BrowserWindow = createWindow();

// Note that windows can both send and receive by creating two connection (see below in 'renderer process' section).

WindowRTCMain.register('sender', senderWindow);
WindowRTCMain.register('receiver', receiverWindow);

Renderer process

Sender

import {
  WindowRTCPeerConnection,
  defineIpc,
} from 'electron-window-rtc/renderer';

// Important: define early how to access to IPC object, according to application 'preload' script.
// The IPC object must at least expose `on`, `removeListener`, `send` and `invoke` methods (see IPCObject below).
defineIpc(window.electron.ipcRenderer);

document.addEventListener('DOMContentLoaded', (event) => {
  const windowConnection = new WindowRTCPeerConnection('receiver');

  // Canvas for example...
  const canvas: HTMLCanvasElement = document.getElementById('canvas');

  // Add track from canvas: this will create an 'offer' for 'receiver' window.
  // Note the '240' fps framerate: leaving it empty creates latency in the receiver.
  windowConnection.addStream(canvas.captureStream(240));
});

Receiver

import {
  WindowRTCPeerConnection,
  defineIpc,
} from 'electron-window-rtc/renderer';

// Important: define early how to access to IPC object, according to application 'preload' script.
// The IPC object must at least expose `on`, `removeListener`, `send` and `invoke` methods (see IPCObject below).
defineIpc(window.electron.ipcRenderer);

document.addEventListener('DOMContentLoaded', (event) => {
  const windowConnection = new WindowRTCPeerConnection('sender');

  // Listen to 'track' added by 'sender' window.
  windowConnection.on('track', (event: EventManagerDTO) => {
    const video: HTMLVideoElement = document.getElementById('video');

    const trackEvent: RTCTrackEvent = event.payload;
    const streams = trackEvent.streams;
    for (const stream of streams) {
      // For the sake of this example, keep only one stream, we could also get `streams[0]`.
      video.srcObject = null;
      video.srcObject = stream;
    }
  });
});

API

Main process

Import the singleton.

import { WindowRTCMain } from 'electron-window-rtc';

WindowRTCMain.register

Registers a BrowserWindow for message passing with a unique name.

Parameters

| Name | Type | Default | Optional | | -------- | --------------- | ----------- | -------- | | name | string | undefined | false | | window | BrowserWindow | undefined | false |

Returns void

Throws Error if a window with this name or this window has already been registered.

WindowRTCMain.unregister

Unregister a BrowserWindow from message passing. Fails silently if window can not be found.

Parameters

| Name | Type | Default | Optional | | ------ | -------- | ----------- | -------- | | name | string | undefined | false |

Returns void

WindowRTCMain.dispose

Dispose the WindowRTCMain singleton by unregistering windows and removing IpcMain listeners.

Returns void

Renderer process

import { WindowRTCPeerConnection, defineIpc } from 'electron-window-rtc/renderer';

defineIpc

Define the global IpcObject to use for thiw window for communicating with main process.

Parameters

| Name | Type | Default | Optional | | ----- | ----------- | ----------- | -------- | | ipc | IpcObject | undefined | false |

Returns void

WindowRTCPeerConnection.with

Create a WindowRTCPeerConnection with window of given name.

Parameters

| Name | Type | Default | Optional | | ------ | -------- | ----------- | -------- | | name | string | undefined | false |

Returns Promise<WindowRTCPeerConnection> An instance of WindowRTCPeerConnection.

Throws Error if IpcObject was not defined with defineIpc, or if the window with name was not registered, or if this window was not registered.

windowPeerConnectionInstance.addStream

Add a stream to send to connected window and create an offer sent to receiving window.

Parameters

| Name | Type | Default | Optional | | ------------ | ----------------------------------- | ---------------------- | -------- | | stream | MediaStream | undefined | false | | maxBitrate | { audio: number; video: number; } | 5000 (Kbps) for both | true |

Returns Promise<void>

windowPeerConnectionInstance.requestOffer

Request the peer window to send an offer.

Returns Promise<void>

windowPeerConnectionInstance.on

Register a listener to WindowRTCPeerConnection instance's events.

Parameters

| Name | Type | Default | Optional | | ---------- | --------------------------------- | ----------- | -------- | | channel | WindowRTCEventChannel | undefined | false | | listener | (event: WindowRTCEvent) => void | undefined | false |

Returns void

windowPeerConnectionInstance.off

Unregister a listener or a whole channel from WindowRTCPeerConnection instance's events. If listener is left undefined, unregisters all listeners for this channel.

Parameters

| Name | Type | Default | Optional | | ----------- | --------------------------------- | ----------- | -------- | | channel | WindowRTCEventChannel | undefined | false | | listener? | (event: WindowRTCEvent) => void | undefined | true |

Returns void

windowPeerConnectionInstance.dispose

Close the connection with the other window and remove all listeners.

Returns void

Events

WindowRTCEvent (see below) sent by WindowRTCPeerConnection with different payloads according to the event emitted.

| Channel | Payload Type | Emitted | | -------------------------- | --------------------------------------------------------- | ----------------------------------------------------------- | | * | any | For each event. | | icecandidate | RTCIceCandidate | On icecandidate RTCPeerConnection event. | | iceconnectionstatechange | Event | On iceconnectionstatechange RTCPeerConnection event. | | icecandidateerror | RTCPeerConnectionIceErrorEvent | On icecandidateerror RTCPeerConnection event. | | icegatheringstatechange | Event | On icegatheringstatechange RTCPeerConnection event. | | negotiationneeded | Event | On negotiationneeded RTCPeerConnection event. | | signalingstatechange | Event | On signalingstatechange RTCPeerConnection event. | | track | RTCTrackEvent | On track RTCPeerConnection event. | | leave | undefined | Error | When local window leaves. | | peer-left | undefined | Error | When remote window leaves. | | request-offer | undefined | When a window requests an offer from its peer window. | | sent-offer | RTCSessionDescriptionInit | When a window has sent an offer. | | received-offer | { offer: SdpObject, answer: RTCSessionDescriptionInit } | When a window has received an offer and sent an answer. | | received-answer | SdpObject | When a window has received an answer. | | received-candidate | RTCIceCandidate | When a window has received an ICE candidate. | | error | Error | When an error occurred in IPC communication. |

Types

IpcObject

Describes the IPC object used by electron-window-rtc

interface IpcObject {
  on: (
    channel: string,
    callback: (event: IpcRendererEvent, ...args: any[]) => void
  ) => void;
  removeListener: (
    channel: string,
    callback: (event: IpcRendererEvent, ...args: any[]) => void
  ) => void;
  send: (channel: string, ...args: any[]) => void;
  invoke: (channel: string, ...args: any[]) => Promise<any>;
}

WindowRTCEvent

Describes the generic event data sent and received by WindowRTCPeerConnection.

interface WindowRTCEvent {
  /**
   * This window name the event was emitted from.
   */
  local: string;
  /**
   * Peer window name.
   */
  remote: string;
  payload: any;
}

// Example.
windowConnection.on('track', (event: WindowRTCEvent) => {
  const local: string = event.local;
  const receiveremoter: string = event.remote;
  const trackEvent: RTCTrackEvent = event.payload;
});

Using canvas

When using canvas to get an image to send to other windows, application should set the frameRequestRate parameter of canvas.captureStream to a high framerate to avoid latency on the receiver side.

Setting frameRequestRate

alt good_performance

Fig. 1: const stream = canvas.captureStream(240); in Sender window doesn't induce latency. Look at the result of performance.now() sent by the Sender.

Without setting frameRequestRate

alt bad_performance

Fig. 2: Without setting frameRequestRate: a latency of ~30ms is induced.

Using WebAudio API

See example's SenderWindow and ReceiverWindow for the setup of the final stream.

alt with_audio

Fig. 3: Sending audio for visualization with or without playing it in the Sender window.

Known Issues

  • Electron example doesn't handle very well reloading windows and introduces latency. We may explore recreating stream on reload.
  • Reloading Sender window takes a lot of time for Receiver window to reconnect, whereas the requestOffer method allows reconnecting quickly on Receiver window's reload.
  • Closing and opening again windows has not been tested: it may involve some logic in the main process to be integrated in WindowRTCMain.
  • Latency differs when using the example in development mode or production mode.

License

MIT