从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
相关产品推荐
相关产品推荐

