首页/新闻资讯/正文详情

使用 Screen-Capturing.js 与 desktopCapture 扩展实现 WebRTC 屏幕捕获:完整集成指南

发布时间:2026/9/23 12:24:12 来源:云帆数科 栏目:资讯中心
使用 Screen-Capturing.js 与 desktopCapture 扩展实现 WebRTC 屏幕捕获:完整集成指南
示例工程【免费下载链接】WebRTC-ExperimentWebRTC, WebRTC and WebRTC. Everything here is all about WebRTC!!项目地址https://gitcode.com/gh_mirrors/we/WebRTC-Experiment点击查看免费下载导读Screen-Capturing.js 是 WebRTC-Experiment 仓库中用于在网页端捕获屏幕/应用窗口 MediaStream 的前端脚本库它依赖配套的 Chrome desktopCapture 扩展Chrome-Extensions/Screen-Capturing.js/Screen-Capturing.js。本指南将带你走通下载并改造扩展 → 修改 manifest.json 白名单 → 在页面中引入脚本 → 调用各 API 捕获屏幕与系统音频的完整链路并结合仓库源码剖析底层 postMessage 消息协议与 chrome.desktopCapture 调用原理。读完本文你可以在自己的 HTTPs 域上独立完成 Chrome 屏幕共享的集成与排错。重要前提该扩展自 2019 年起已停止维护原作者明确声明use at your own risk。新项目请优先使用浏览器原生的getDisplayMediaAPI本文中的扩展方案仅适用于需要兼容旧版 Chrome34或需要sourceId细粒度控制的遗留场景。先看现代替代方案getDisplayMedia在深入扩展方案之前务必先掌握现代浏览器提供的原生屏幕捕获 API。README 开篇即给出推荐的统一封装它按能力降级依次尝试navigator.getDisplayMedia、navigator.mediaDevices.getDisplayMedia最后才回退到扩展方案getScreenStream(function(screenStream) { video.srcObject screenStream; }); function getScreenStream(callback) { if (navigator.getDisplayMedia) { navigator.getDisplayMedia({ video: true }).then(screenStream { callback(screenStream); }); } else if (navigator.mediaDevices.getDisplayMedia) { navigator.mediaDevices.getDisplayMedia({ video: true }).then(screenStream { callback(screenStream); }); } else { getScreenId(function(error, sourceId, screen_constraints) { navigator.mediaDevices.getUserMedia(screen_constraints).then(function(screenStream) { callback(screenStream); }); }); } }getDisplayMedia由浏览器直接弹窗让用户选择整个屏幕 / 应用窗口 / 标签页无需安装任何扩展、无需部署白名单这是目前唯一推荐的方案。只有当用户浏览器不支持该 API 时才需要走下文的扩展路径。工作原理与消息协议源码剖析Screen-Capturing.js 本身不直接调用chrome.desktopCapture它通过postMessage 消息协议与扩展的 content-script 通信扩展的 background-script 再调用底层 API 返回sourceId。整条链路由三个脚本协作完成脚本角色仓库路径Screen-Capturing.js网页侧 API 封装发送/接收 postMessageChrome-Extensions/Screen-Capturing.js/Screen-Capturing.jscontent-script.js网页与 background 之间的消息中转站Chrome-Extensions/desktopCapture/content-script.jsbackground-script.js调用chrome.desktopCapture.chooseDesktopMedia返回 sourceIdChrome-Extensions/desktopCapture/background-script.js网页侧postMessage 的发送与接收Screen-Capturing.js 在加载时注册message事件监听并且只处理同源消息window.addEventListener(message, function(event) { if (event.origin ! window.location.origin) { return; } onMessageCallback(event.data); });onMessageCallback处理三类响应见 Screen-Capturing.js收到字符串PermissionDeniedError用户点了取消直接以该字符串回调便于调用方判断收到rtcmulticonnection-extension-loaded扩展通知自己已在页面中注入脚本据此将内部状态chromeMediaSource置为desktop收到携带sourceId的对象扩展共享了临时 sourceId同时携带canRequestAudioTrack布尔值表示本次选择的源是否允许捕获系统音频。中转站content-scriptcontent-script.js 维护一个rtcmulticonnectionMessages白名单对象包含are-you-there、get-sourceId、audio-plus-tab三个字符串只放行白名单内的消息避免与其他无关 postMessage 冲突网页发来are-you-there时content-script 直接回复rtcmulticonnection-extension-loaded让网页快速探测扩展存在性网页发来get-sourceId或audio-plus-tab或携带get-custom-sourceId数组的消息时通过chrome.runtime.connect()建立的 Port 转发给 background-scriptbackground 返回的消息再通过window.postMessage(message, *)广播回网页。底层background-script 与 chooseDesktopMediabackground-script.js 在chrome.runtime.onConnect中监听 Port 消息根据消息类型配置screenOptions并调用chrome.desktopCapture.chooseDesktopMedia(screenOptions, port.sender.tab, onAccessApproved)get-sourceId使用默认选项[screen, window]让用户选择整屏或某个应用窗口audio-plus-tab将选项扩展为[screen, window, audio, tab]即额外允许捕获标签页和系统音频{ get-custom-sourceId: [...] }使用调用方自定义的选项数组。用户确认后onAccessApproved(sourceId, opts)被回调若sourceId为空点了取消回传PermissionDeniedError否则回传{ sourceId: sourceId, canRequestAudioTrack: !!opts.canRequestAudioTrack }。这个 sourceId 最终被写入 getUserMedia 的chromeMediaSourceId约束中从而拿到屏幕 MediaStream。第一步下载并改造 desktopCapture 扩展使用 Screen-Capturing.js 前必须先准备扩展。仓库中的扩展源码位于 Chrome-Extensions/desktopCapture你需要自行下载、改造并发布下载 desktopCapture 目录全部文件修改 manifest.json 中 content-scripts 的matches白名单把默认的https://www.webrtc-experiment.com/*替换为你自己的域名通过chrome://extensions/以加载已解压的扩展程序方式本地测试或打包成 ZIP 上传 Google Web Store 发布。manifest.json 关键配置原仓库 manifest.json 的完整配置如下version 3.7、manifest_version 2{ name : Screen Capturing, author: Muaz Khan, version : 3.7, manifest_version : 2, minimum_chrome_version: 34, description : Capture full-screen or specific applications screen on any HTTPs domain!, background: { scripts: [background-script.js], persistent: false }, content_scripts: [ { js: [ content-script.js ], all_frames: true, run_at: document_end, matches: [https://www.webrtc-experiment.com/*] }], icons : { 48 : icon.png }, permissions: [ desktopCapture ], web_accessible_resources: [ icon.png ] }你需要改动的核心只有matches例如换成你的域名matches: [https://www.your-domain.com/*]配置要点说明minimum_chrome_version: 34chrome.desktopCaptureAPI 自 Chrome 34 起可用这是扩展的最低兼容版本permissions中的desktopCapture声明使用桌面捕获 API 的权限all_frames: true页面中所有 iframe 都会注入 content-script保证getScreenId这类 iframe 嵌套方案也能工作background.persistent: false使用事件驱动非持久后台页web_accessible_resources中的icon.png网页侧通过chrome-extension://id/icon.png探测扩展安装状态时需要使用它见下文getChromeExtensionStatus原理。第二步在页面中引入 Screen-Capturing.js扩展就绪后在你的 HTTPs 页面中引入脚本仓库同时提供 CDN 用法与本地 index.html 演示页script srchttps://www.webrtc-experiment.com/Screen-Capturing.js/script script srchttps://webrtc.github.io/adapter/adapter-latest.js/script若希望离线使用可直接拷贝仓库中的 Screen-Capturing.js 到你的站点也可以使用 npm 包npm install webrtc-screen-capturing # node_modules/webrtc-screen-capturing/Screen-Capturing.js脚本同时支持 Chrome 与 FirefoxFirefox 无需扩展getScreenConstraints会直接返回{ mozMediaSource: window, mediaSource: window }约束见 Screen-Capturing.js。API 全览与用法示例getScreenConstraints获取可直接传给navigator.mediaDevices.getUserMedia的屏幕捕获约束对象内部自动完成扩展可用性检查、sourceId 获取与约束组装getScreenConstraints(function(error, screen_constraints) { if (error) { return alert(error); } if(screen_constraints.canRequestAudioTrack) { // 本次选择的源支持捕获系统扬声器音频 // getUserMedia({audio:screen_constraints}) } navigator.mediaDevices.getUserMedia({ video: screen_constraints }).then(function(stream) { var video document.querySelector(video); video.src URL.createObjectURL(stream); video.play(); }).catch(function(error) { alert(JSON.stringify(error, null, \t)); }); });从源码Screen-Capturing.js可以看到其内部组装的约束结构var screen_constraints { mandatory: { chromeMediaSource: chromeMediaSource, // screen 或 desktop maxWidth: screen.width 1920 ? screen.width : 1920, maxHeight: screen.height 1080 ? screen.height : 1080 }, optional: [] };其中chromeMediaSource默认是screen一旦探测到扩展存在其值变为desktop并且脚本会请求扩展返回 sourceId 后写入screen_constraints.mandatory.chromeMediaSourceId。maxWidth/maxHeight以屏幕实际分辨率与 1920×1080 中较大者为准。getScreenConstraintsWithAudio与getScreenConstraints相同但额外包含系统音频扬声器。实现上只是以captureSourceIdWithAudiotrue调用getScreenConstraints进而走getSourceIdWithAudio路径getScreenConstraintsWithAudio(function(error, screen_constraints) { if (error) { return alert(error); } navigator.mediaDevices.getUserMedia({ video: screen_constraints, audio: screen_constraints // 必须同时传 audio 这一行 }).then(function(stream) { var video document.querySelector(video); video.src URL.createObjectURL(stream); video.play(); }).catch(function(error) { alert(JSON.stringify(error, null, \t)); }); });演示页 index.html 中还给出了更稳妥的写法先检查screen_constraints.canRequestAudioTrack true再决定是否把 audio 约束传出去navigator.mediaDevices.getUserMedia({ video: screen_constraints, audio: screen_constraints.canRequestAudioTrack ? screen_constraints : false }).then(...)getSourceId直接向扩展索取sourceId即chromeMediaSourceId适合进阶用户自行组装约束getSourceId(function(sourceId, canRequestAudioTrack) { if(sourceId ! PermissionDeniedError) { // 拿到 sourceId组装自己的 getUserMedia 约束 } if(canRequestAudioTrack true) { // 系统音频扬声器可用 } });注意其实现细节若sourceId已缓存会立即用缓存值回调if(sourceId) return callback(sourceId);避免重复弹出选择框否则设置screenCallback并通过window.postMessage(get-sourceId, *)向扩展请求。getCustomSourceId按需指定捕获来源类型第一个参数必须是数组。支持的格式window捕获指定应用窗口screen捕获整个屏幕tab捕获标签页audio捕获系统音频var our_own_choices [tab, audio]; getCustomSourceId(our_own_choices, function(sourceId, canRequestAudioTrack) { if(sourceId ! PermissionDeniedError) { // 你的代码 } if(canRequestAudioTrack true) { // 系统音频扬声器可用 } });底层通过window.postMessage({ get-custom-sourceId: arr }, *)把数组传给扩展background-script 收到后将其直接作为chooseDesktopMedia的选项。getSourceIdWithAudiogetSourceId的含系统音频版本与getScreenConstraintsWithAudio对应getSourceIdWithAudio(function(sourceId, canRequestAudioTrack) { if(sourceId ! PermissionDeniedError) { // 你的代码 } if(canRequestAudioTrack true) { // 系统音频扬声器可用 } });getChromeExtensionStatus推荐使用的扩展状态检测方法比isChromeExtensionAvailable更可靠。它在页面中创建一个指向chrome-extension://id/icon.png的img元素onload说明扩展已安装随后再通过 postMessage 握手判断是否启用onerror说明未安装。可省略参数此时使用默认扩展 IDajhifddimkapgcifgcodmmfdlknahffk若使用自己发布的扩展请传入自己的扩展 ID。// 传你自己的扩展 ID不传则使用默认 ID getChromeExtensionStatus(your-extension-id, function(status) { if(status installed-enabled) { // 已安装且已启用 } if(status installed-disabled) { // 已安装但被禁用 } if(status not-installed) { // 未安装 } if(status not-chrome) { // 非 Chrome 浏览器Firefox 等 } });注意在非 Chrome 浏览器源码中用typeof window.InstallTrigger判断 Firefox中会直接回调not-chrome。isChromeExtensionAvailable较简化的存在性探测向扩展发送are-you-there2 秒后仍未收到响应则判定不可用isChromeExtensionAvailable(function(isAvailable) { if(!isAvailable) alert(Chrome extension is either not installed or disabled.); });官方文档建议优先使用getChromeExtensionStatus因为它能区分未安装与已禁用两种状态。常见问题无法重复捕获屏幕屏幕捕获一次后再次调用 API 却不再弹窗解决办法是先把sourceId置为null再调用任意 APIsourceId null; // 关键一行 getScreenConstraints(function(error, screen_constraints) { if (error) { return alert(error); } navigator.mediaDevices.getUserMedia({ video: screen_constraints }).then(function(stream) { var video document.querySelector(video); video.src URL.createObjectURL(stream); video.play(); }).catch(function(error) { alert(JSON.stringify(error, null, \t)); }); });原因在源码中可见getSourceId、getCustomSourceId、getSourceIdWithAudio都会检查全局变量sourceId是否已有缓存值存在则直接复用而不再请求扩展清空它即可让下一次调用重新触发chooseDesktopMedia选择框。同理如果你的业务需要每次都让用户重新选择可以在回调前主动清理sourceId。进阶替代方案getScreenId.js免发布扩展如果不想自己发布扩展仓库还提供了 getScreenId.js 方案。它使用iframe 黑客技巧页面中的 iframe 从https://www.webrtc-experiment.com/域加载该域已在官方扩展白名单内iframe 与扩展通过 postMessage 交换 sourceId再转发回你的页面从而让同一个官方扩展在任意 HTTPs 域可用。其完整调用方式与 APIgetScreenId、getChromeExtensionStatus、自定义参数捕获音频/标签页等见 getScreenId.js/README.md。script srchttps://www.WebRTC-Experiment.com/getScreenId.js/script script srchttps://webrtc.github.io/adapter/adapter-latest.js/script video controls autoplay/video script getScreenId(function (error, sourceId, screen_constraints) { navigator.mediaDevices.getUserMedia(screen_constraints).then(function (stream) { document.querySelector(video).src URL.createObjectURL(stream); }).catch(function (error) { console.error(error); }); }); /script该方案同样有局限在 iframe 内使用时 postMessage 机制可能失效官方建议此时改用 WebSocket 或外部服务器中转 sourceId并且同样需要 HTTPs 环境。本地运行演示仓库为演示页提供了极简静态服务器server.js基于 Node.js 原生 http 模块默认监听 9001 端口仅做静态文件服务并屏蔽对 server.js 自身的访问node server.js # Server listening at http://localhost:9001技术栈与适用场景小结方案适用场景关键限制getDisplayMedia现代 Chrome/Edge/Firefox需用户手动选择源不支持旧版 Chrome 34-70 等Screen-Capturing.js 自发布扩展需要固定扩展、细粒度 sourceId 控制的 HTTPs 站点需改 manifest 白名单并发布扩展已停止维护getScreenId.js 官方扩展不想发布扩展、任意 HTTPs 域快速验证依赖官方扩展与 iframe 中转iframe 内不可用最后再次提醒新项目请直接使用getDisplayMediaScreen-Capturing.js 与 desktopCapture 扩展仅作为历史兼容方案保留。本文所有 API 行为均可对照仓库源码验证网页侧封装见 Screen-Capturing.js消息中转见 content-script.js底层桌面捕获见 background-script.js完整交互演示见 index.html。赞分享示例工程【免费下载链接】WebRTC-ExperimentWebRTC, WebRTC and WebRTC. Everything here is all about WebRTC!!项目地址https://gitcode.com/gh_mirrors/we/WebRTC-Experiment点击查看免费下载相关推荐如何快速实现屏幕翻译Screen Translator 完整使用指南如何快速实现屏幕翻译Screen Translator 完整使用指南 Screen Translator 是一款强大的开源屏幕翻译工具集成了屏幕捕捉、OCR桌面应用OCRElectron屏幕捕获实现屏幕截图与录屏功能Electron屏幕捕获实现屏幕截图与录屏功能 在桌面应用开发中屏幕捕获是一个常见且重要的功能需求。无论是用于远程协助、教学演示、游戏录制还是应用监控屏幕桌面应用跨平台前端屏幕翻译终极指南Screen Translator完整使用教程屏幕翻译终极指南Screen Translator完整使用教程 Screen Translator是一款功能强大的开源屏幕翻译工具它通过智能屏幕捕捉、精准O桌面应用OCR上一篇**探索分布式应用的新纪元Iroh**下一篇黑鸟BlackbirdSwift中的SQLite轻骑兵创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关推荐

扫描文件到电脑全攻略:打印机、手机、软件实操指南
扫描文件到电脑全攻略:打印机、手机、软件实操指南

很多人一听到“扫描文件到电脑”,第一反应还是去找复印店,或者觉得这事特别麻烦。其实扫描这件事,远比你想象中简单,而且现在能用的路子非常多:打印机一体机、独立扫描仪、手机APP,甚至一个微信小程序都能搞… · 2026/9/23 12:24:05

TWEAKR信号通路在疾病治疗中的研究进展
TWEAKR信号通路在疾病治疗中的研究进展

1. 肿瘤坏死因子超家族受体TWEAKR概述TWEAKR(TNF-related weak inducer of apoptosis receptor)是肿瘤坏死因子受体超家族(TNFRSF)的第12个成员,也被称为FN14。这个受体最初是在2001年通过生物信息学方法被发现的&… · 2026/9/23 12:24:05

嵌入式Linux驱动移植实战:R836芯片驱动包解构与调试全攻略
嵌入式Linux驱动移植实战:R836芯片驱动包解构与调试全攻略

简介:R836_v2.9E驱动包是针对R836硬件设备的V2版驱动更新,版本号2.9E,适合嵌入式开发者、驱动维护人员及硬件调试工程师使用。该驱动适配多个硬件平台,可有效解决设备识别、I2C总线通信及信号调谐控制等关键问题,为先前… · 2026/9/23 12:23:59

C++五子棋AI源码解析:极大极小值算法与AlphaBeta剪枝实战
C++五子棋AI源码解析:极大极小值算法与AlphaBeta剪枝实战

简介:C实现的五子棋游戏源码,核心采用极大极小值算法与AlphaBeta剪枝传统搜索算法,前后端完整可运行。资源面向计算机相关专业学生,适合作为毕业设计、课程设计或期末大作业,也适合希望学习经典博弈搜索算法并练习项目… · 2026/9/23 17:29:55

写论文软件哪个好?我帮你把“毕业论文”拆成了四个可替换的零件
写论文软件哪个好?我帮你把“毕业论文”拆成了四个可替换的零件

毕夏AI官网 www.bixiaai.com 毕夏AI写作官网 www.bixiaai.com 毕夏官网 www.bixiaai.com 毕夏智能写作官网 www.bixiaai.com 你好,我是你们的老朋友,一个教育测评博主。 后台被问得最多的问题,永远是这个:“写论文软件哪个… · 2026/9/23 17:29:42

AI写论文哪个软件最好?毕夏AI用“不替你写”的逻辑,回答了一个被问烂的问题
AI写论文哪个软件最好?毕夏AI用“不替你写”的逻辑,回答了一个被问烂的问题

毕夏AI官网 www.bixiaai.com 毕夏AI写作官网 www.bixiaai.com 毕夏官网 www.bixiaai.com 毕夏智能写作官网 www.bixiaai.com 你好,我是你们的论文写作科普博主。 “AI写论文哪个软件最好”——这个问题我后台被问了不下两百遍。 但我今天不打算给你一个“排… · 2026/9/23 17:29:42

5分钟吃透丰满乳亲伦小说高频面试题避坑指南
5分钟吃透丰满乳亲伦小说高频面试题避坑指南

5分钟吃透丰满乳亲伦小说高频面试题避坑指南 官方文档太长抓不住重点,这是很多初学者和转行开发者最大的痛点。面对【丰满乳亲伦小说】这类看似复杂的技术概念,大家往往陷入资料海洋,找不到真正的落地场景。更尴尬的是,在准备【高频面试题】时,你会发现… · 2026/9/23 17:29:29

基于PyTorch的交通标志识别系统实战:从GTSRB训练到Jetson部署
基于PyTorch的交通标志识别系统实战:从GTSRB训练到Jetson部署

简介:本资源是一个面向计算机视觉初学者与智能交通系统开发者的Python深度学习实战项目,聚焦交通标志识别这一典型图像分类任务,适用于课程设计、毕业设计及辅助驾驶算法原型开发。压缩包共28个文件,含6个核心Python源码&#xff… · 2026/9/23 17:29:29

Qt4远程控制源码解析:从连接建立到屏幕传输的完整实现
Qt4远程控制源码解析:从连接建立到屏幕传输的完整实现

简介:这份源码包面向希望深入理解远程桌面与远程控制实现原理的开发者,尤其适合具备一定网络编程与C基础、想通过真实项目源码提升技能的中高级学习者。包内共40个文件,以14个cpp源文件与14个h头文件为核心,辅以6个dll动态库、2个… · 2026/9/23 17:29:16

3招搞定手机怎么下载微信面试难题实战项目解析
3招搞定手机怎么下载微信面试难题实战项目解析

3招搞定手机怎么下载微信面试难题实战项目解析 面试被问“手机怎么下载微信”背后的原理,90%的人答不上来。别笑,这看似弱智的问题,实则是考察你对移动应用分发机制、安全校验及网络协议理解的试金石。我带过不少校招新人,他们背了八股文,却连一个A… · 2026/9/23 0:00:03

你有新短消息请注意查收:3个新手避坑指南搞定消息系统选型
你有新短消息请注意查收:3个新手避坑指南搞定消息系统选型

你有新短消息请注意查收:3个新手避坑指南搞定消息系统选型 面试被问“高并发下如何保证消息不丢失”,你张口就是“用Redis”,结果面试官追问“如果Redis宕机了怎么办”,你瞬间卡壳。这种场景太常见了,很多新手在背八股文时,只记住了技术名词… · 2026/9/23 0:00:29

Win7无线热点配置工具源码解析:解决API失效的3个实战技巧
Win7无线热点配置工具源码解析:解决API失效的3个实战技巧

Win7无线热点配置工具源码解析:解决API失效的3个实战技巧 Win7无线热点配置工具在Win10/11上跑不动?不是你的问题,是版本升级后 API 全变了。很多老项目里的 netsh wlan… · 2026/9/23 0:00:36

了解更多?预约专属演示

我们的顾问将为您一对一讲解产品与方案

企业微信二维码