利用 Web 浏览器构建 Java Media Player

如果您需要在 Java 桌面应用程序中嵌入媒体播放器,有几种方法可供选择:

  • 您可以使用 JavaFX Media API 来实现所有必需的媒体播放器功能。
  • 虽然稍显过时但仍然可用的 Java Media Framework 也可以作为一种解决方案。
  • 您可以集成像 VLCJ 这样的第三方 Java 库,它封装了本机媒体播放器的功能。

每种方法都有其优缺点:

JavaFX Media API 方法是跨平台的,适用于 Windows、Linux 和 macOS。它在 JavaFX 中运作良好。但是,如果您使用 Swing 或 SWT,则需要诸如 JFXPanelFXCanvas 这样的桥接器。

封装本机媒体播放器的功能需要为每个平台单独进行配置,因为播放器可能不支持所有必需的平台。例如,VLCJ 就不支持 Linux。此外,您可能还需要在目标平台上安装缺失的视频和音频编解码器,以播放各种媒体格式。

利用 Web 浏览器的功能

如今,我们大部分的媒体内容都是通过 Web 浏览器来获取的。它们适用于多个平台,并且支持播放各种音频和视频格式。同时,还具备播放媒体内容所需的所有必要功能。既然 Web 浏览器已经如此强大和全面,我们为何不考虑在 Java 桌面应用程序中利用这一优势来播放媒体内容呢?

在本文中,我将介绍另一种可在 Java Swing、JavaFX 或 SWT 应用程序中构建跨平台 Java 媒体播放器的方法。具体操作如下:

  1. 使用 JxBrowser[1] 将 Web 浏览器控件集成到简单的 Java Swing 应用程序中。
  2. 利用 HTML5 的功能加载用于播放所需视频的 HTML 网页。
  3. 通过直接从 Java 代码中调用的 JavaScript 命令来控制视频的播放。

JxBrowser 是一款商业 Java 库,它允许您在跨平台的 Java Swing、JavaFX 和 SWT 应用程序中充分利用 Chromium 的强大功能。非常适合那些基于 Java 技术开发并销售软件解决方案的公司使用。

过去,Flash Player 是我们在网页上展示各种媒体内容的常用工具,备受欢迎。然而,随着技术的不断发展,2020 年 12 月,Flash Player 正式退出了历史舞台,现在,HTML5 的 Video 和 Audio API 已经全面取代了它的地位。

目前,我们主要有两种方式来利用这些 API 播放媒体内容:

  1. 直接使用 HTML5 的 Video 和 Audio API 进行操作。
  2. 使用第三方 JavaScript 库,如 Plyr、Video.js 等。

在本文中,我将使用 Plyr 库 — 这个最受欢迎的 HTML5 媒体播放器之一。它简单易用,与应用程序集成起来非常方便。

实现

让我们创建一个演示程序,展示如何使用 Plyr JS 库和 JxBrowser 构建跨平台的 Java 媒体播放器。

首先,我们需要创建一个 HTML 页面(media.html),其中包含 JS 库,嵌入视频播放器,并配置目标 MP4 视频文件的位置:

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Java Media Player</title><link rel="stylesheet" href="<https://cdn.plyr.io/3.6.8/plyr.css>"/>
</head>
<body style="margin:0"><video id="player"controlscrossoriginplaysinlinedata-poster="<https://cdn.plyr.io/static/demo/View_From_A_Blue_Moon_Trailer-HD.jpg>"><source src="<https://cdn.plyr.io/static/demo/View_From_A_Blue_Moon_Trailer-720p.mp4>"type="video/mp4"/>
</video><script src="<https://cdn.plyr.io/3.6.8/plyr.js>" crossorigin="anonymous"></script>
</body>
</html>

接下来,我们需要创建一个简单的 Java Swing 应用程序,该程序将显示一个带有 Web 浏览器和播放控件的 JFrame 窗口:

JFrame frame = new JFrame("Java Media Player");
frame.add(new MediaPlayer(), BorderLayout.CENTER);
frame.setVisible(true);

MediaPlayer 组件包含了 Web 浏览器和播放控件。它具有以下初始化逻辑:

engine = Engine.newInstance(EngineOptions.newBuilder(HARDWARE_ACCELERATED)// 在这个演示中,我们加载了 MP4 视频文件,// 因此我们必须启用默认情况下禁用的相应专有功能。.enableProprietaryFeature(ProprietaryFeature.H_264).enableProprietaryFeature(ProprietaryFeature.AAC)// 启用通过 JavaScript 在网页上无需用户交互即可编程播放视频的功能。.enableAutoplay().build());
Browser browser = engine.newBrowser();// 将 JsPlayer 的实例注入到 JavaScript 中,
// 以便从 JavaScript 中调用其方法来通知播放器事件。
browser.set(InjectJsCallback.class, params -> {Frame frame = params.frame();JsObject window = frame.executeJavaScript("window");if (window != null) {player = new JsPlayer(frame);window.putProperty("java", player);}return Response.proceed();
});// 获取包含 JS 视频播放器的 media.html 文件的绝对路径,
// 加载该文件并等待其完全加载完成,
// 这样我们就可以构建播放器 UI 控件了。
URL resource = MediaPlayer.class.getResource("/media.html");
if (resource != null) {browser.navigation().loadUrlAndWait(resource.toString());
}// 创建一个可视化 Swing 控件,
// 用于显示包含视频的网页内容。
BrowserView view = BrowserView.newInstance(browser);
view.setPreferredSize(new Dimension(1280, 720));// 将控件嵌入到 Java Swing 框架中。
setLayout(new BorderLayout());
add(view, BorderLayout.CENTER);
add(playbackControls(), BorderLayout.SOUTH);

让我来解释一下我在初始化逻辑中都做了什么。在上面的代码中,我配置了 Engine 实例,该实例相当于 Google Chrome 应用程序,并为其设置了几个选项:

  • 启用 H264 和 AAC 专有功能,以便能够播放 MP4 视频;
  • 启用通过 JavaScript 在网页上无需用户交互即可编程播放视频的功能。

接下来,我创建了一个 Browser 实例,它相当于 Chrome 浏览器的一个标签页,并加载了 media.html 文件。为了显示 HTML 文件的内容,我创建了一个 Swing BrowserView 控件,并将其嵌入到 Java 框架中。

在演示应用程序中,我决定使用以下媒体播放器功能:

  • 播放和暂停;
  • 静音和取消静音;
  • 调节音量;
  • 获取视频时长(以秒为单位);
  • 当当前播放时间发生变化时接收通知;
  • 设置当前播放时间。

对于上述每一种播放功能,我都创建了一个对应的 Java Swing GUI 控件,以便最终的播放面板具有以下外观:

现在,我需要将这些控件与 JS 媒体播放器的相应功能进行绑定。例如,当我点击播放按钮时,我需要调用 player.play() 这个 JS 函数。为此,我使用了相应的 JxBrowser API:

frame.executeJavaScript("player.play()");

为了从 JavaScript 接收播放状态改变的通知,我需要定义一个公开的 Java 类,并在其中使用 @JsAccessible 注解标记公开方法,如下所示:

public final class JsPlayer {@JsAccessiblepublic void onTimeUpdated(double currentTime) {listeners.forEach(listener -> listener.accept(currentTime));}
}

接着,让我们同样使用以下 JxBrowser API 创建该类的一个实例,并将其注入到 JavaScript 中:

browser.set(InjectJsCallback.class, params -> {Frame frame = params.frame();JsObject window = frame.executeJavaScript("window");if (window != null) {player = new JsPlayer(frame);window.putProperty("java", player);}return Response.proceed();
});

使用 @JsAccessible 注解的方法在 JavaScript 中是“可见”的,当相应的事件被触发时,可以调用它们。

在该 media.html 文件中,我需要添加 JavaScript 代码,以便在发生不同的播放事件时通知 Java 端:

<script>player.on('时间更新', event => {java.onTimeUpdated(player.currentTime);});player.on('音量变化', event => {java.onVolumeChanged(player.volume, player.muted);});player.on('播放', event => { java.onPlaybackStarted(); });player.on('暂停', event => { java.onPlaybackPaused(); });
</script>

该程序的完整源代码以及 media.html 文件可在 GitHub[2] 上获取。

结果

如果您编译并运行该程序,您将会看到以下输出:

Java 媒体播放器演示应用程序

JxBrowser 是跨平台的,因此这种方法适用于所有平台,无需您付出额外的努力。

结论

HTML5 的视频功能足以构建自定义媒体播放器,以在各种平台上播放大多数流行的视频和音频格式。

希望本文所述方法能对您有所帮助,也期待收到您的宝贵评论和建议。

参考资料

[1] JxBrowser: https://teamdev.cn/jxbrowser/?utm_campaign=java-media-player&utm_medium=article&utm_source=csdn

[2] GitHub: https://github.com/TeamDev-IP/JxBrowser-Examples/tree/master/tutorials/media-player/src/main?utm_source=csdn&utm_medium=article&utm_campaign=java-media-player

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/412958.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

如何选择适合企业的财税自动化解决方案

财税自动化解决方案是现代企业提升财务管理效率、降低运营成本的关键工具。然而&#xff0c;市场上的财税自动化产品琳琅满目&#xff0c;功能各异&#xff0c;企业在选择时常常感到困惑。本文金智维将从中小型的需求出发&#xff0c;帮助企业了解如何选择适合自身的财税自动化…

QT实战项目之音乐播放器

项目效果演示 myMusicShow 项目概述 在本QT音乐播放器实战项目中,开发环境使用的是QT Creator5.14版本。该项目实现了音乐播放器的基本功能,例如开始播放、停止播放、下一首播放、上一首播放、调节音量、调节倍速、设置音乐播放模式等。同时还具备搜索功能,通过搜索歌曲名字…

另一种关于类的小例

前言 我们还是以一段关于构造函数的代码作为开端&#xff0c;我们以之前银行家的小项目为背景 class Account {constructor(owner, currency, pin) {this.owner owner;this.currency currency;this.pin pin;} }const ITshare new Account(ITshare, EUR, 21211); console.…

零基础入门天池镜像提交--windows场景VirtualBox虚拟机安装linux系统并ssh远程登录,直至镜像的制作及提交

背景&#xff1a;由于本人只有一台windows,天池上的比赛需要提交镜像&#xff0c;自己试了好多方法给windows安装linux&#xff0c;但是始终没安装成功。最终采用在利用VirtualBox安装linux虚拟机&#xff0c;使用MobaXterm进行ssh登陆linux&#xff0c;镜像的制作、push、提交…

Java+Swing实现学生选课管理系统

JavaSwing实现学生选课管理系统 一、系统介绍二、系统展示1.课程查询2.课程添加3.退课 三、系统实现四、其他1.其它系统2.获取源码 一、系统介绍 本系统实现了学生登录和管理员登录&#xff0c;学生实现选课&#xff0c;查看已选课程&#xff0c;修改密码&#xff0c;查看学生…

Java | Leetcode Java题解之第386题字典序排数

题目&#xff1a; 题解&#xff1a; class Solution {public List<Integer> lexicalOrder(int n) {List<Integer> ret new ArrayList<Integer>();int number 1;for (int i 0; i < n; i) {ret.add(number);if (number * 10 < n) {number * 10;} els…

顺序表

目录 1. 数据结构 2. 顺序表 1&#xff09;线性表 2&#xff09;顺序表分类 3、动态顺序表的实现 1. 数据结构 数据&#xff1a;常见的数值1、2、3、4.....、教务系统里保存的用户信息&#xff08;姓名、性别、年龄、学历等 等&#xff09;、网页里肉眼可以看到的信息&…

vTESTstudio系列12--vTESTstudio中的动态函数库介绍2

在上期的文章&#xff08;vTESTstudio系列11--vTESTstudio中的动态函数库介绍1&#xff09;中&#xff0c;我们详细介绍了osek_tp.dll的接口&#xff0c;本章开始给大家介绍如何通过osek_tp.dll的接口去发送诊断指令&#xff0c;Let‘s Go!!! 目录 1. CanTp发送数据的函数&am…

图表操作——图表保存为图片+多个图表批量保存为压缩包——js技能提升

使用场景&#xff1a; echarts图表&#xff1a;生成的柱状图/折线图/饼图等可以实现图表的导出&#xff0c;导出格式为一个图片。也可以支持多个图表同时导出为图片&#xff0c;以压缩包的形式下载下来。 下面介绍单个导出批量导出的具体用法&#xff1a; 1.单个导出功能——…

可信捐赠系统的设计与开发论文

摘 要 如今社会上各行各业&#xff0c;都喜欢用自己行业的专属软件工作&#xff0c;互联网发展到这个时候&#xff0c;人们已经发现离不开了互联网。新技术的产生&#xff0c;往往能解决一些老技术的弊端问题。因为传统可信捐赠系统信息管理难度大&#xff0c;容错率低&#x…

选对文档版本管理软件:10款工具详解

本篇文章中提到的工具包括&#xff1a;1.PingCode&#xff1b;2.Worktile&#xff1b;3.联想Filez&#xff1b;4.蓝凌云&#xff1b;5.阿里云盘&#xff1b;6.360亿方云&#xff1b;7.无忧企业文档&#xff1b;8.DocStar ECM&#xff1b;9.Dropbox Business&#xff1b;10.Shar…

数据库之心:MySQL 探索(一)mysql的安装和基本介绍

欢迎来到我们的MySQL博客&#xff01;在这里&#xff0c;我们将深入探讨MySQL数据库系统的各个方面&#xff0c;包括基础知识、优化技巧、实践案例以及最新的行业趋势。 目录 前言 什么是数据库&#xff1f; 数据库产品 MySQL安装 解压 配置 添加环境变量 初始化MySQL …

Linux云计算 |【第二阶段】SHELL-DAY4

主要内容&#xff1a; grep、egrep的使用&#xff0c;基本/扩展正则、sed的使用&#xff08;非交互、逐行处理、常用命令与选项&#xff09; 补充&#xff1a;grep [-E]选项&#xff0c;表示允许使用扩展的正则表达式&#xff08;同等于egrep&#xff09; 一、grep 与 egrep 的…

基于深度学习的单目标跟踪系统

基于深度学习的单目标跟踪&#xff0c;效果吊打传统算法&#xff0c;3060显卡上达到实时&#xff0c;代码python和c两个版本都有。 基于深度学习的单目标跟踪系统是一种先进的计算机视觉技术&#xff0c;它可以实现实时的、高精度的目标跟踪。与传统的基于特征匹配或模板匹配的…

LED的使用寿命评估

一&#xff0e;前言 LED光源随着时间的推移&#xff0c;输出光功率会逐渐衰减。在某一时间点&#xff0c;当LED发出的光衰减到一定水平&#xff0c;就无法满足应用要求。因此&#xff0c;常遇见客户会索取产品中LED光源的使用寿命数据。那么怎样确认LED的使用寿命呢&#xff1…

MySQL5.6迁移到DM8

注意&#xff1a; MySQL 5.7 与 MySQL 8.0 的语法有所区别&#xff0c;本文档是将MySQL5.6迁移到DM8。 迁移前准备 源库 数据库信息 统计源端业务库要迁移的数据量、字符编码、归档保留等信息。 内容 说明 备注 数据库架构 单机 节点数 1 数据库版本 MySQL 5.6…

UE5 摄像机图像采集到材质 映射到 UI 和 物体表面

一.创建SceneCapture2D的组件 二.创建用于 映射的 贴图 三.将RenderTarget贴图放到SceneCapture2D的摄像机上Scene Capture的TextureTarget 四.这个时候的映射贴图&#xff0c;产生的材质可以直接。放到Plane上。 五&#xff0c;但是如果要用于UI,还需要更改SceneCapture2D的摄…

C语言基础(二十七)

1、位字段&#xff08;Bit-fields&#xff09;也是一种数据结构&#xff0c;允许在结构体&#xff08;struct&#xff09;或联合体&#xff08;union&#xff09;中定义其成员占用特定的位数。对于需要精确控制内存布局或处理硬件寄存器映射等场景非常有用。位字段使得开发者能…

WebRTC协议下的视频汇聚融合技术:EasyCVR视频技术构建高效视频交互体验

视频汇聚融合技术是指将来自不同源、不同格式、不同网络环境的视频流进行集中处理、整合和展示的技术。随着视频监控、远程会议、在线教育、直播娱乐等领域的快速发展&#xff0c;视频数据的规模急剧增长&#xff0c;对视频处理能力和效率提出了更高要求。视频汇聚融合技术通过…

GAMES202——作业3 Screen Space Ray Tracing

任务 为场景实现屏幕空间的全局光照效果 1.直接光照&#xff1a; 实现ssrFragmentShader中的EvalDiffuse(wi, wo, uv) 和EvalDirectionalLight(uv) 函数&#xff0c;并在 main 函数中实现直接光照的效果。 2.屏幕空间光线求交&#xff1a;实现RayMarch(ori, dir, out hitPos) …