You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Electron桌面录屏共享至Web应用的实现问题求助

可行实现方案解析

核心思路

让Electron端作为WebRTC的唯一媒体源端,仅在Electron侧通过desktopCapturer获取桌面流并发起WebRTC连接;Web端仅作为纯接收端,不调用任何媒体捕获API(如getUserMedia),自然不会触发摄像头/麦克风权限请求。

具体实现步骤

1. Electron端:获取桌面流并作为WebRTC发送方

  • 使用Electron的desktopCapturerAPI获取桌面共享流,这一步会触发系统的录屏权限请求(仅Electron端)。
  • 初始化WebRTC的RTCPeerConnection,将桌面流添加到连接中,生成Offer并通过信令通道发送给Web端。
  • 监听ICE候选事件,将候选信息同步给Web端。

示例代码片段:

// Electron 渲染进程
const { desktopCapturer } = require('electron');

async function getDesktopStream() {
  const sources = await desktopCapturer.getSources({ types: ['screen'] });
  const stream = await navigator.mediaDevices.getUserMedia({
    audio: false,
    video: {
      mandatory: {
        chromeMediaSource: 'desktop',
        chromeMediaSourceId: sources[0].id,
        minWidth: 1280,
        maxWidth: 1920,
        minHeight: 720,
        maxHeight: 1080
      }
    }
  });
  return stream;
}

// 初始化WebRTC发送端
async function initSender() {
  const pc = new RTCPeerConnection({ iceServers: [{ urls: 'stun:stun.l.google.com:19302' }] });
  const desktopStream = await getDesktopStream();
  
  // 添加媒体轨道到连接
  desktopStream.getTracks().forEach(track => pc.addTrack(track, desktopStream));
  
  // 生成Offer并设置本地描述
  const offer = await pc.createOffer();
  await pc.setLocalDescription(offer);
  
  // 将Offer发送给Web端(通过WebSocket信令通道)
  sendSignalingData({ type: 'offer', data: offer });
  
  // 监听ICE候选并发送给Web端
  pc.onicecandidate = (e) => {
    if (e.candidate) {
      sendSignalingData({ type: 'ice', data: e.candidate });
    }
  };
}

2. Web端:仅作为WebRTC接收方

  • 初始化WebRTC的RTCPeerConnection,但不调用getUserMedia,只监听远程媒体轨道事件,将接收到的流渲染到页面的<video>元素中。
  • 接收Electron端发送的Offer,设置为远程描述,生成Answer并返回给Electron端。
  • 接收Electron端发送的ICE候选,添加到连接中完成协商。

示例代码片段:

// Web端页面
const pc = new RTCPeerConnection({ iceServers: [{ urls: 'stun:stun.l.google.com:19302' }] });
const remoteVideo = document.getElementById('remote-video');

// 监听远程媒体轨道,渲染桌面流
pc.ontrack = (e) => {
  remoteVideo.srcObject = e.streams[0];
};

// 通过WebSocket接收信令数据
signalingSocket.onmessage = async (event) => {
  const data = JSON.parse(event.data);
  switch(data.type) {
    case 'offer':
      await pc.setRemoteDescription(new RTCSessionDescription(data.data));
      const answer = await pc.createAnswer();
      await pc.setLocalDescription(answer);
      // 发送Answer给Electron端
      signalingSocket.send(JSON.stringify({ type: 'answer', data: answer }));
      break;
    case 'ice':
      await pc.addIceCandidate(new RTCIceCandidate(data.data));
      break;
  }
};

3. 信令通道搭建

需要一个简单的信令服务(如基于Node.js的WebSocket服务),用于传递WebRTC的Offer、Answer和ICE候选,确保Electron端和Web端能完成连接协商。

关键注意事项

  • 必须保证Web端绝不调用navigator.mediaDevices.getUserMedia,这是避免触发权限请求的核心。
  • Electron端的desktopCapturer需在渲染进程中调用,若在主进程获取源ID,需通过IPC传递到渲染进程再捕获流,注意Electron版本的API兼容性。
  • 若需要同步桌面音频,可在getUserMedia配置中开启音频,并选择对应的桌面音频源。

内容的提问来源于stack exchange,提问作者Web Experts

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.25 00:26:07