🛠️

【Electron】画面共有やスクリーンショットに「映らない」ウィンドウを作る技術的アプローチ

に公開

WebRTCの getDisplayMedia を用いたブラウザベースの画面共有や、各種デスクトップツールのスクリーンショット API が普及した現在、セキュリティやプライバシーの観点から 「特定のウィンドウだけを画面共有の対象から除外したい(映り込ませたくない)」 というユースケースが増えています。

例えば、パスワード管理ツールの機密情報表示、社内セキュリティツール、あるいは作業中に個人のプライバシーを守るためのオーバーレイ(懸念窓)などがこれに該当します。

本記事では、クロスプラットフォーム開発で主流の Electron を使用し、OS レベルの API を叩いて「画面共有やキャプチャに絶対に映らないウィンドウ」を実装する方法と、その技術的裏側について解説します。


1. 最もシンプルな実装:setContentProtection

Electronには、ウィンドウのコンテンツをキャプチャから保護するための標準 API win.setContentProtection(enable) が用意されています。

これを使用すると、OS(Windows / macOS)のグラフィックレイヤーに対して、該当ウィンドウをキャプチャ対象から除外(または黒塗り)するよう命令を出すことができます。

import { app, BrowserWindow } from 'electron';

function createProtectedWindow() {
  const win = new BrowserWindow({
    width: 400,
    height: 300,
    alwaysOnTop: true, // 常に最前面に表示
    frame: false,      // 枠なしのミニマルなUI
    transparent: true  // 背景を透明に
  });

  win.loadURL('[https://example.com/overlay](https://example.com/overlay)');

  // 【最重要】画面キャプチャを無効化する
  win.setContentProtection(true);
}

app.whenReady().then(createProtectedWindow);

OS内部での動作原理

  • Windows (WDA: SetWindowDisplayAffinity)
    Electronの内部では、Windowsの SetWindowDisplayAffinity という独自 API が呼ばれ、フラグに WDA_EXCLUDEFROMCAPTURE(または WDA_MONITOR)がセットされます。これにより、DWM(Desktop Window Manager)が画面をレンダリングする際、キャプチャ用のバッファからこのウィンドウの描画情報が自動的にスキップされます。
  • macOS (NSWindow SharingType)
    macOS側では、NSWindowsharingTypeNSWindowSharingNone に設定されます。これにより、AirPlayでのミラーリングや、システム標準のスクリーンショット、Zoom等の画面共有時にウィンドウが完全に不可視(または透明)になります。

2. さらに高度なステルス性を実現するオーバーレイ

単に黒塗りにするだけでなく、「完全に存在自体をキャプチャに映さない(透明化して下の画面を透過させる)」かつ「自分にはしっかり見える」という高度なUI/UXを実現する場合、Electronのウィンドウ属性をさらにチューニングする必要があります。

const win = new BrowserWindow({
  width: 500,
  height: 250,
  type: 'toolbar',       // タスクバーやドックにアイコンを出さない
  hasShadow: false,
  webPreferences: {
    offscreen: false     // オフスクリーンレンダリングは使用しない
  }
});

// マウスイベントを完全に透過させたい場合(下の画面をクリック可能にする)
win.setIgnoreMouseEvents(true, { forward: true });
win.setContentProtection(true);

これにより、オンライン会議ツール(Zoom、Google Meet、Teamsなど)で「画面全体を共有」した状態であっても、このウィンドウだけは相手側の画面や録画データに一切残らなくなります。


3. 実戦応用:リアルタイムAIアシスタントへの組み込み

この「画面共有に映らないウィンドウ」という技術は、私が開発しているオンライン面接・コーディング 試験対策ツール「Linkjob AI」 のコアアーキテクチャとしても採用されています。

開発時の課題と解決策
リアルタイムで音声やコード選考(LeetCode型、HireVue等)の解析ヒントをユーザーに提示する際、以下の課題がありました。

面接官側の画面共有への映り込み: 受講者が画面を共有した際、AIのヒント画面が面接官に見えてしまうと、選考の公平性やUIの邪魔になる。

パフォーマンスへの影響: OSレベルのAPIとChromiumのレンダリングパイプラインが競合すると、フレームレートが落ちる。

setContentProtection をベースに、低遅延のデータストリーミング(WebSocket/PCM変換)と組み合わせることで、「面接システム側には一切干渉せず、受講者の画面上でのみ自然に並走するプライベートなAIアシスタント」を安全に実現することができました。


まとめ

Electronを用いたデスクトップアプリ開発において、setContentProtection は非常に強力ですが、OSのアップデート(特にWindows 11のグラフィックス仕様変更など)によって挙動が変わることがあるため、常にネイティブ層の動向を追う必要があります。

セキュリティツールや、プライバシーを保護したいオーバーレイアプリを開発している方の参考になれば幸いです。

もし「実際に画面共有に映らないUIがどのように動作するのか」に興味がある方は、プロダクトとして落とし込んだ Linkjob AI日本語公式サイト のランディングページも覗いてみてください。

Discussion