提供3000多款全球软件/控件产品
针对软件研发的各个阶段提供专业培训与技术咨询
根据客户需求提供定制化的软件开发服务
全球知名设计软件,显著提升设计质量
打造以经营为中心,实现生产过程透明化管理
帮助企业合理产能分配,提高资源利用率
快速打造数字化生产线,实现全流程追溯
生产过程精准追溯,满足企业合规要求
以六西格玛为理论基础,实现产品质量全数字化管理
通过大屏电子看板,实现车间透明化管理
对设备进行全生命周期管理,提高设备综合利用率
实现设备数据的实时采集与监控
利用数字化技术提升油气勘探的效率和成功率
钻井计划优化、实时监控和风险评估
提供业务洞察与决策支持实现数据驱动决策
翻译|使用教程|编辑:吉伟伟|2024-11-14 14:56:20.460|阅读 3 次
概述:在本文中,我们将展示如何利用 JxBrowser 的功能在两个 Compose Desktop 应用程序之间实现屏幕共享。
# 慧都年终大促·界面/图表报表/文档/IDE等千款热门软控件火热促销中 >>
JxBrowser是一个跨平台的 JVM 库,它允许您将基于 Chromium 的 Browser 控件集成到 Compose、Swing、JavaFX、SWT 应用程序中,并使用 Chromium 的数百种功能。为了在 Kotlin 中实现屏幕共享,我们利用了 Chromium 的 WebRTC 支持以及 JxBrowser 对其的编程访问能力。
在本文中,我们将展示如何利用 JxBrowser 的功能在两个 Compose Desktop 应用程序之间实现屏幕共享。
概述
WebRTC 是一个开放标准,允许通过常规 JavaScript API 进行实时通信。该技术在所有现代 Browser 以及所有主要平台的原生客户端上均可使用。我们将使用它将捕获的屏幕视频流从一个应用程序发送到另一个应用程序。
该项目由四个模块组成:
信令服务器促进对等端之间初始的连接信息交换。这包括有关网络、会话描述符和媒体功能的信息。
Compose 客户端是两个桌面应用程序:一个通过单击即可共享屏幕,另一个接收并显示视频流。
服务器
WebRTC 的主要挑战之一是如何管理信令,它充当对等端的汇合点,而不传输实际数据。我们使用 PeerJS 库来抽象信令逻辑,使我们能够专注于应用程序的功能。该库提供了服务器和客户端实现。
我们需要做的只是创建一个 PeerServer 实例并运行创建的 Node.js 应用程序。
首先,我们添加所需的 NPM 依赖项:
npm install peer
然后,创建一个 PeerServer 实例:
PeerServer({ port: 3000 });
并运行创建的应用程序:
node server.js
Compose 客户端
对于 Compose 应用程序,我们需要使用 JxBrowser 和 Compose 插件来初始化一个空的 Gradle 项目:
plugins { id("org.jetbrains.kotlin.jvm") version "2.0.0" id("com.teamdev.jxbrowser") version "1.1.0" id("org.jetbrains.compose") version "1.6.11" } jxbrowser { version = "8.1.0" includePreviewBuilds() } dependencies { implementation(jxbrowser.currentPlatform) implementation(jxbrowser.compose) implementation(compose.desktop.currentOs) }
每个 Compose 客户端由三层组成:
接收端应用程序
让我们先从显示共享屏幕的接收端应用程序开始。
我们需要实现一个接收 WebRTC 组件。它应该连接到信令服务器并订阅传入的呼叫。其 API 将由一个单独的 connect() 函数组成。该函数应暴露在全局范围内,以便从 Kotlin 端进行访问。
window.connect = (signalingServer) => { const peer = new Peer(RECEIVER_PEER_ID, signalingServer); peer.on('call', (call) => { call.answer(); call.on('stream', (stream) => { showVideo(stream); }); call.on('close', () => { hideVideo(); }); }); }
我们接听每个呼叫,并在 <video> 元素中显示接收到的流,否则该元素将被隐藏。在文章的末尾,我们会提供一个指向 GitHub 上完整源代码的链接。
接下来,我们将使用 JxBrowser 加载此组件,并使暴露的 JS 函数可以从 Kotlin 中调用:
class WebrtcReceiver(browser: Browser) { private const val webrtcComponent = "/receiving-peer.html" private val frame = browser.mainFrame!! init { browser.loadWebPage(webrtcComponent) } fun connect(server: SignalingServer) = executeJavaScript("connect($server)") // 在加载的 Frame 上执行给定的 JS 代码。 private fun executeJavaScript(javaScript: String) = // ... // 从应用程序的资源中加载页面。 private fun Browser.loadWebPage(webPage: String) = // ... }
WebrtcReceiver 从应用程序的资源中加载实现的组件到 Browser 中,并公开一个单一的公共 connect(...) 方法,该方法直接调用其 JS 对应项。
最后,让我们创建一个 Compose 应用程序来将这些组件组合在一起:
singleWindowApplication(title = "Screen Viewer") { val engine = remember { createEngine() } val browser = remember { engine.newBrowser() } val webrtc = remember { WebrtcReceiver(browser) } BrowserView(browser) LaunchedEffect(Unit) { webrtc.connect(SIGNALING_SERVER) } }
首先,我们创建 Engine、Browser 和 WebrtcReceiver 实例。然后,我们添加 BrowserView 组合项来显示 HTML5 视频播放器。在启动的效果中,我们连接到信令服务器,假设这是一个快速且不会失败的操作。
发送端应用程序
在发送端应用程序中,我们通过向接收端发起呼叫来共享主屏幕。
我们需要实现发送 WebRTC 组件。它应该能够连接到信令服务器,开始和停止屏幕共享会话。因此,它的 API 将由三个函数组成。这些函数应该暴露给全局作用域,以便从 Kotlin 端进行访问。
let peer; let mediaConnection; let mediaStream; window.connect = (signalingServer) => { peer = new Peer(SENDER_PEER_ID, signalingServer); } window.startScreenSharing = () => { navigator.mediaDevices.getDisplayMedia({ video: {cursor: 'always'} }).then(stream => { mediaConnection = peer.call(RECEIVER_PEER_ID, stream); mediaStream = stream; }); } window.stopScreenSharing = () => { mediaConnection.close(); mediaStream.getTracks().forEach(track => track.stop()); }
在建立与信令服务器的连接后,组件可以开始和停止屏幕共享会话。开始新的会话意味着选择一个媒体流来呼叫接收端。当共享停止时,应该关闭该流和点对点媒体连接。只要组件被加载,与信令服务器的连接就会保持活动状态。
与接收端应用程序类似,让我们为这个组件创建一个 Kotlin 包装器。我们将通过添加新功能来扩展 WebrtcReceiver 以创建 WebrtcSender。
首先,我们需要告诉 JxBrowser 使用哪个视频源。默认情况下,当网页想要从屏幕捕获视频时,Chromium 会显示一个对话框,我们可以在其中选择源。使用 JxBrowser API,我们可以直接在代码中指定捕获源:
init { // 当 Browser 即将开始捕获会话时,选择一个源。 browser.register(StartCaptureSessionCallback { params: Params, tell: Action -> val primaryScreen = params.sources().screens()[0] tell.selectSource(primaryScreen, AudioCaptureMode.CAPTURE) }) }
其次,我们希望让用户界面知道当前是否有活动的共享会话。这是为了决定是显示 Start 还是 Stop 按钮。让我们创建一个可观察的属性,并将其绑定到 JxBrowser 的 CaptureSessionStarted 和 CaptureSessionsStopped 事件:
var isSharing by mutableStateOf(false) private set init { // ... // 在会话开始和停止时更新 `isSharing` 状态变量。 browser.subscribe<CaptureSessionStarted> { event: CaptureSessionStarted -> isSharing = true event.capture().subscribe<CaptureSessionStopped> { isSharing = false } } }
最后要做的就是添加两个公共方法,用于调用其 JavaScript 对应项:
fun startScreenSharing() = executeJavaScript("startScreenSharing()") fun stopScreenSharing() = executeJavaScript("stopScreenSharing()")
就是这样!
在本地运行时,应用程序看起来是这样的:
在不同的 PC 上运行
作为一项额外的好处,您可以轻松地使此示例在不同的 PC 上运行,而无需暴露本地运行的信令服务器。PeerJS 提供了一个免费的云托管 PeerServer 版本。如果未指定特定的服务器来使用,该库将自动连接到公共云服务器。请注意,在编写本文时,它是可运行的,但其正常运行时间并不保证。
要尝试此功能,您需要在发送和接收 WebRTC 组件中删除显式传递给 Peer 构造函数的服务器参数。
// 使用该服务器。 const peer = new Peer(RECEIVER_PEER_ID, signalingServer); // 使用云托管实例。 const peer = new Peer(RECEIVER_PEER_ID);
另外,请注意,您将与其他人共享这个公共服务器,由于对等 ID 是手动设置的,所以可能会发生冲突。
结论
在本文中,我们展示了如何使用 JxBrowser 和 WebRTC 在一个 Compose 应用程序中共享屏幕,并在另一个应用程序中显示视频流。通过利用 JxBrowser 对 Chromium 的集成以及用于 WebRTC 的 PeerJS 库,我们可以快速构建一个功能完备的屏幕共享应用程序。
本站文章除注明转载外,均为本站原创或翻译。欢迎任何形式的转载,但请务必注明出处、不得修改原文相关链接,如果存在内容上的异议请邮件反馈至chenjj@evget.com
文章转载自:慧都网本文将探讨如何使用 Spire.XLS for .NET 在 C# 程序中导入 Excel 数据到数据库以及导出数据库到 Excel 文件,实现数据在 Excel 和数据库之间无缝流转。
在本文中,我们将向您展示如何逐步执行此操作,告诉您什么是 SCORM,为什么需要使用它,并列出我们测试过的最佳 SCORM 转换工具之一——iSpring Suite。
本文主要介绍如何使用Kendo UI for Angular组件的ListView来构建带有图表的仪表板,欢迎下载新版控件体验!
在本文中,您将学习如何使用Spire.PDF for .NET在 C# 中向 PDF 文档添加页码。
一个跨平台的库,用于将Chromium浏览器集成到Java应用程序中
DotNetBrowserDotNetBrowser能添加Chromium引擎到你的.NET 应用中,支持.NET6!
JResourceBrowser一款类似于Javax.Swing.JFileChooser的Swing控件,但它还能使用户通过一系列目录选项获得各类协议。
WOW WebBrowser可将Internet Explorer ActiveX(IEX)组件转换成一种可编程的ActiveX组件
服务电话
重庆/ 023-68661681
华东/ 13452821722
华南/ 18100878085
华北/ 17347785263
客户支持
技术支持咨询服务
服务热线:400-700-1020
邮箱:sales@evget.com
关注我们
地址 : 重庆市九龙坡区火炬大道69号6幢
慧都科技 版权所有 Copyright 2003- 2024 渝ICP备12000582号-13 渝公网安备 50010702500608号