远程屏幕共享广泛运用于各种应用和服务中,从网络会议到远程访问应用都离不开它的支持。后台员工可以使用它向一线同事咨询问题,技术支持专家也可以通过它查看客户看到的精确画面。

尽管市面上有像 TeamViewer 这样的第三方应用可供选择,但如果您希望直接在 Java 应用程序中集成远程访问功能,那么,您可能需要考虑另一种解决方案。

在本文中,我将向您展示如何利用 JxBrowser 的功能,实现运行在不同电脑上的两个 Java 应用程序之间的屏幕共享。

JxBrowser 作为一款强大的跨平台 Java 库,它不仅能够将基于 Chromium 的 Web 浏览器控件无缝集成到您的 Java Swing、JavaFX、SWT 应用程序中,同时还提供了对 Chromium 数百种强大功能的支持,这为我们实现屏幕共享提供了很大便利。

为了在 Java 中实现屏幕共享,我将利用 Chromium 内置的屏幕共享功能,并结合 JxBrowser 提供的编程接口进行操作。

你用 Kotlin 写代码吗?请查阅文章如何在 Kotlin 中实现屏幕共享

概述 

该项目包含两部分: 一是基于 Node.js 的服务器;二是两个独立的 Java 应用程序。

服务器是一个简化的 WebRTC 服务器实现。项目的这一部分包含了用于连接到服务器并启动屏幕共享会话的 JavaScript 代码。

Java 客户端是两个桌面应用程序。第一个应用程序是一个带有按钮的窗口。点击按钮将启动共享会话。第二个应用程序则会自动接收视频流并显示它。同时还有一个按钮用于停止屏幕共享。

WebRTC 服务器图示

WebRTC 服务器 

WebRTC 服务器被配置为支持两个客户端之间的交互:一个流媒体发送端(streamer)和一个接收端(receiver)。该服务器提供两个静态页面,分别是 streamer.html 和 receiver.html。

const app = express();

app.use(express.static('public'));

app.get('/streamer', (req, res) => {
   res.sendFile(rootPath + 'public/streamer.html');
});

app.get('/receiver', (req, res) => {
   res.sendFile(rootPath + 'public/receiver.html');
});

每个 HTML 文件都包含了 JavaScript 代码,这段代码负责连接至服务器并通过 WebRTC 建立屏幕共享。当流媒体发送端开始捕获屏幕时,我们会将其屏幕视图作为视频流接收。为了显示这个视频流,我们会在接收端使用内置的 HTML5 视频播放器。

Web 服务器图示

为了检查一切是否正常,让我们打开两个浏览器窗口亲自查看一下。

流媒体发送端和接收端预览

Java 客户端 

接下来,让我们实现 Java 客户端,并将它们与 JavaScript 应用程序集成。我们需要初始化一个空的 Gradle 项目,并使用 JxBrowser Gradle 插件添加 JxBrowser 的依赖项。

plugins {
    
    id("com.teamdev.jxbrowser") version "1.2.1"
}

jxbrowser {
    version = "8.2.1"
}

dependencies {
    // 检测当前平台并添加相应的 Chromium 二进制文件。 
    implementation(jxbrowser.currentPlatform)

    // 添加对 Swing 集成的依赖项。
    implementation(jxbrowser.swing)
}

流媒体发送端应用 

让我们从一个将要共享其屏幕的应用程序开始。

我们需要代表流媒体发送端连接到服务器。首先,需要创建 Engine 和 Browser 的实例:

Engine engine = Engine.newInstance(HARDWARE_ACCELERATED);
Browser browser = engine.newBrowser();

然后加载所需的 URL:

browser.navigation().loadUrlAndWait("http://localhost:3000/streamer");

一旦 URL 加载完毕,我们便可以访问 streamer.html 中的 JavaScript 代码,以及可以在 Java 中通过按钮点击直接开始屏幕共享:

JButton startSharingButton = new JButton("共享您的屏幕");

startSharingButton.addActionListener(e -> {
   browser.mainFrame().ifPresent(mainFrame ->    
       mainFrame.executeJavaScript("startScreenSharing()"));
});

默认情况下,当网页想要捕获屏幕上的视频时,Chromium 会弹出一个对话框供用户选择捕获源。不过,借助 JxBrowser API,我们可以直接在代码中指定捕获源,从而省去手动选择的步骤:

browser.set(StartCaptureSessionCallback.class, (params, tell) -> {
    CaptureSources sources = params.sources();
    // 共享整个屏幕。
    CaptureSource screen = sources.screens().get(0);
    tell.selectSource(screen, AudioCaptureMode.CAPTURE);
});

让我们保存 CaptureSession 的实例,以便稍后可以通过编程方式停止它。

private CaptureSession captureSession;

browser.on(CaptureSessionStarted.class, event -> 
    captureSession = event.capture()
);

为此,我们需要一个不同的按钮:

JButton stopSharingButton = new JButton("停止共享");
stopSharingButton.addActionListener(e -> {
   captureSession.stop();
});

接收端应用 

在接收端应用中,我们将显示共享的屏幕。

和流媒体发送端应用一样,我们需要连接到 WebRTC 服务器,但这次是作为接收端。因此,我们需要创建 Engine 和 Browser 实例,并导航到接收端的 URL:

Engine engine = Engine.newInstance(HARDWARE_ACCELERATED);
Browser browser = engine.newBrowser();
browser.navigation().loadUrlAndWait("http://localhost:3000/receiver");

为了在 Java 应用程序中显示流媒体发送端的屏幕,让我们创建一个 Swing 的 BrowserView 组件,并将其嵌入到 JFrame 中:

private static void initUI(Browser browser) {
   BrowserView view = BrowserView.newInstance(browser);

   JFrame frame = new JFrame("接收端");
   frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
   frame.setSize(700, 500);
   frame.add(view, BorderLayout.CENTER);
   frame.setLocationRelativeTo(null);
   frame.setVisible(true);
}

BrowserView 组件将显示加载的网页内容,包括 HTML5 视频播放器,这样我们就可以看到流媒体发送端的屏幕了。

就是这样!

接收端预览

您可以在不同的终端中运行以下命令来启动 WebRTC 服务器和两个 Java 应用程序:

cd server && node server.js
cd clients && ./gradlew runStreamer
cd clients && ./gradlew runReceiver
探索 JxBrowser 的更多功能!
立即体验

源代码 

该项目的源代码可在 GitHub 上获取。

结论 

在本文中,我向您展示了如何利用 JxBrowser 在一个 Java 应用程序中实现屏幕共享,并在另一个 Java 应用程序中显示它。

我创建了一个简单的 JavaScript 屏幕共享应用。然后使用 JxBrowser 将其集成到了两个 Swing 应用程序中。

借助 JxBrowser 提供的 capturing API(捕获 API),我很快就为标准的 Java 应用程序增加了屏幕共享功能。