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

从Electron迁移到Tauri:如何枚举兼容getUserMedia的可用屏幕?

枚举屏幕并兼容getUserMedia的Tauri实现方案

一、Tauri内置能力

Tauri本身没有直接对应Electron desktopCapturer.getSources的API,但可以通过两种方式实现需求:

1. 用Tauri窗口API获取基础屏幕信息

你可以调用Tauri的window.screens API获取屏幕的基础属性(尺寸、位置、是否为主屏等),但返回的ID不直接兼容Chrome的chromeMediaSourceId格式。

前端示例代码:

import { getCurrentWindow } from '@tauri-apps/api/window';

async function getBasicScreens() {
  const window = getCurrentWindow();
  const screens = await window.screens();
  return screens.map((screen, index) => ({
    id: screen.id,
    name: screen.name || `屏幕 ${index + 1}`,
    size: { width: screen.size.width, height: screen.size.height }
  }));
}

2. 直接使用Web标准API获取屏幕流

Tauri基于WebKit(macOS/iOS)、WebView2(Windows)或GTK WebKit(Linux),这些引擎支持标准的getDisplayMedia API,可直接获取屏幕流。但如果需要提前枚举所有屏幕并拿到兼容ID,需要结合Rust插件实现。

二、Rust插件实现兼容的屏幕枚举

Rust有跨平台屏幕枚举库(如screen-rs、winit),可获取屏幕信息并生成符合Chrome格式的chromeMediaSourceId。

1. 编写Rust插件核心逻辑

首先在Tauri项目的Cargo.toml中添加依赖:

[dependencies]
tauri = { version = "1.5", features = ["api-all"] }
screen-rs = "0.1"
serde = { version = "1.0", features = ["derive"] }

然后在src-tauri/src/lib.rs中实现命令:

use screen_rs::Screen;
use tauri::command;
use serde::Serialize;

#[command]
async fn get_compatible_screens() -> Result<Vec<ScreenInfo>, String> {
    let screens = Screen::all().map_err(|e| e.to_string())?;
    let mut screen_list = Vec::new();

    for screen in screens {
        // 生成Chrome兼容的screen ID,格式为"screen:<系统屏幕ID>"
        let chrome_source_id = format!("screen:{}", screen.id());
        screen_list.push(ScreenInfo {
            id: chrome_source_id,
            name: screen.name().unwrap_or_else(|| "未知屏幕".into()),
            width: screen.width(),
            height: screen.height(),
        });
    }

    Ok(screen_list)
}

#[derive(Serialize)]
struct ScreenInfo {
    id: String,
    name: String,
    width: u32,
    height: u32,
}

fn main() {
    tauri::Builder::default()
        .invoke_handler(tauri::generate_handler![get_compatible_screens])
        .run(tauri::generate_context!())
        .expect("运行Tauri应用失败");
}

2. 前端调用并捕获屏幕

在前端调用Rust命令拿到屏幕列表,再用兼容ID调用getUserMedia:

import { invoke } from '@tauri-apps/api/tauri';

async function captureSelectedScreen() {
  const screens = await invoke('get_compatible_screens');
  // 示例选择第一个屏幕
  const targetScreen = screens[0];
  
  try {
    const stream = await navigator.mediaDevices.getUserMedia({
      audio: false,
      video: {
        mandatory: {
          chromeMediaSource: 'desktop',
          chromeMediaSourceId: targetScreen.id
        }
      }
    });
    // 将流渲染到video元素
    const videoEl = document.getElementById('screen-preview');
    videoEl.srcObject = stream;
  } catch (err) {
    console.error("捕获屏幕失败:", err);
  }
}

三、权限配置

需要在tauri.conf.json中开启屏幕捕获相关权限:

{
  "tauri": {
    "allowlist": {
      "window": {
        "all": true
      }
    },
    "permissions": {
      "screenCapture": {
        "allow": true
      }
    }
  }
}

内容的提问来源于stack exchange,提问作者Robert Hegner

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 17:07:06