【多媒体】Java实现MP4和MP3音视频播放器【JavaFX】【更多功能的播放器】【音视频播放】

news2024/9/30 23:23:27

在Java中播放视频可以使用多种方案,最常见的是通过Swing组件JFrame和JLabel来嵌入JMF(Java Media Framework)或Xuggler。不过,JMF已经不再被推荐使用,而Xuggler是基于DirectX的,不适用于跨平台。而且上述方案都需要使用第三方库。

在JDK 8.0版本中,一个最简单的视频播放器跨平台解决方案是使用JavaFX,它提供了MediaPlayer类来播放视频。
JavaFX是一个用于创建富客户端应用程序的GUI框架,它提供了丰富的图形、多媒体和动画功能。在JavaFX中,我们可以使用简洁的代码来实现视频播放功能。
JavaFX 最初是由 Oracle 推出的一个用于开发富客户端的GUI框架,它旨在取代较旧的 Swing 框架。JavaFX 于 2007 年推出,2011 年 10 月发布了2.0 版本。JavaFX 2.0 的一个优点是适用于跨平台,而且可以完全用 Java 语言编写代码。

2014年发布的JDK 8.0就包含了JavaFx 2.0 版本。然而,随着时间的发展和技术的变迁,JavaFx 2.0并未达到预期目标,而且在与其他的技术标准竟争中处于下风。从 JDK 11 开始,Oracle 决定不再将 JavaFX 包含在 JDK 中,如有需要JavaFX必须单独下载和使用。
尽管如此,JavaFX 仍然是一个强大的开发工具,开发者可用它来设计、编写、测试、调试和部署富客户端程序,支持跨平台使用。

使用Java语言实现一个音视频播放器,支持播放各种常见视频格式,如MP4、Flv等;同时支持MP3和wav格式的音频。
这个视频可使用菜单来用文件选择器来选择视频文件进行播放。该播放器具备基本的播放控制功能,如播放、暂停、继续、关闭、全屏等,并且能够实现视频的全屏播放和音量控制。

以下是本例程的源代码:

/***
 * @author QiuGen
 * @description 用JavaFX实现音视频播放器MusicPlayer.java
 * 实现功能:这个视频使用菜单来用文件选择器来选择视频文件进行播放。
 * 该播放器具备基本的播放控制功能,如播放、暂停、继续、关闭、全屏
 * 等,并且能够实现视频的全屏播放和音量控制。
 * @date 2024/7/9
 * ***/
import java.io.File;
import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.Orientation;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Menu;
import javafx.scene.control.MenuBar;
import javafx.scene.control.MenuItem;
import javafx.scene.control.Separator;
import javafx.scene.control.Slider;
import javafx.scene.control.ToggleButton;
import javafx.scene.control.ToggleGroup;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.scene.media.Media;
import javafx.scene.media.MediaPlayer;
import javafx.scene.media.MediaView;
import javafx.scene.text.Font;
import javafx.scene.text.Text;
import javafx.stage.FileChooser;
import javafx.stage.Stage;

public class MusicPlayer extends Application {
	static double WIDTH = 800;
	static double HEIGHT = 680;
	private VBox rootBox = new VBox(3);
	private Stage primaryStage;
	private Media media;
	private MediaPlayer mediaPlayer;
	private MediaView mediaView;
	// 音频或视频的路径
	//private  String path;
	private static final String PATH = "D:/Temp/太极拳.mp4";
	//private static final String PATH = "D:/Temp/大约在冬季.mp3";
	//private static final String PATH = "D:/Temp/我是一片云.wav";
	//private static final String PATH = "D:/Temp/彩云飞.mp4";
	
	@Override
	public void start(Stage primaryStage) throws Exception {
		/***/
		// 创建媒体播放器
        media = new Media(new File(PATH).toURI().toString());
        mediaPlayer = new MediaPlayer(media);
        mediaView = new MediaView(mediaPlayer);

        setRootBox();
 
        Scene scene = new Scene(rootBox,WIDTH,HEIGHT);
        primaryStage.setTitle("音视频播放器");
        primaryStage.setScene(scene);
        primaryStage.show();
    }
	
	private void setRootBox() {
        rootBox.getChildren().add(getTopHBox());
        rootBox.setAlignment(Pos.CENTER);

        rootBox.getChildren().add(mediaView);
        rootBox.setPrefWidth(WIDTH);
        rootBox.setPrefHeight(HEIGHT);
        mediaView.setFitWidth(rootBox.getPrefWidth());
        mediaView.setFitHeight(rootBox.getPrefHeight() - 80);
 
        rootBox.getChildren().add(new Separator());
        rootBox.getChildren().add(getTogBtnHBox());
	}
	
    private MenuBar getMenu()
    {
        MenuBar menuBar = new MenuBar();
        
        Menu menuFile = new Menu("文件");                
        Menu menuEdit = new Menu("编辑");
        Menu menuHelp = new Menu("帮助");        
        menuBar.getMenus().addAll(menuFile, menuEdit, menuHelp);
        
        
        // 创建一个菜单项
        MenuItem openFile = new MenuItem("打开文件");
 
        // 为菜单项添加事件处理器
        openFile.setOnAction(new EventHandler<ActionEvent>() {
            @Override
            public void handle(ActionEvent event) {
                // 创建一个文件选择器
                FileChooser fileChooser = new FileChooser();
                fileChooser.setTitle("打开文件");
                // 显示文件选择器,并获取选中的文件(如果有)
                fileChooser.showOpenMultipleDialog(primaryStage);
            }
        });
        
        // 为菜单项添加事件处理器
        openFile.setOnAction(new EventHandler<ActionEvent>() {
            @Override
            public void handle(ActionEvent event) {
                // 创建一个文件选择器
                FileChooser fileChooser = new FileChooser();
                fileChooser.setTitle("打开文件");
                fileChooser.getExtensionFilters().addAll(
                        new FileChooser.ExtensionFilter("All Video Files", "*.mp4", "*.flv", "*.mp3", "*.wav"),
                        new FileChooser.ExtensionFilter("Mp4 Video Files", "*.mp4"),
                        new FileChooser.ExtensionFilter("Flv Video Files", "*.flv"),
                        new FileChooser.ExtensionFilter("Mp3 Audio Files", "*.mp3"),
                        new FileChooser.ExtensionFilter("Wav Audio Files", "*.wav")
                );
                // 显示文件选择器,并获取选中的文件(如果有)
                File file = fileChooser.showOpenDialog(primaryStage);
                if (file != null) {
                	media = new Media(file.toURI().toString());
                    mediaPlayer = new MediaPlayer(media);
                    // 创建媒体视图
                    mediaView = new MediaView(mediaPlayer);
                    mediaView.setFitWidth(WIDTH);
                    mediaView.setFitHeight(HEIGHT - 80);
                    rootBox.getChildren().clear();
                    setRootBox();
                    mediaPlayer.play();
                }
            }
        });
 
        // 将菜单项添加到菜单
        menuFile.getItems().add(openFile);
        
        return menuBar;
    }
    
    private HBox getTopHBox() {
    	HBox hbox = new HBox();
    	hbox.getChildren().addAll(getMenu(),getVolumeHBox());
    	return hbox;
    }
    /****/
    private HBox getVolumeHBox() {
    	HBox hBox = new HBox();
    	hBox.setAlignment(Pos.CENTER);
        // 创建“音量”微调滑块按钮
        Slider vSlider = new Slider(0, 1, 0.5); // 初始音量为50%
        vSlider.setPrefWidth(WIDTH*2/3);
        vSlider.valueProperty().addListener((observable, oldValue, newValue) -> {
            mediaPlayer.setVolume(newValue.doubleValue());
        });
        hBox.getChildren().add(new Separator(Orientation.VERTICAL));
        hBox.getChildren().addAll(new Text("音量:"), vSlider); 
    	
    	return hBox;
    }
    /****/
    private HBox getTogBtnHBox()
    {
        int fontSize = 16;
        ToggleGroup toggleGroup = new ToggleGroup();
 
        ToggleButton playBtn = new ToggleButton("播放");
        playBtn.setFont(new Font(fontSize));
        playBtn.setOnMouseClicked(event -> mediaPlayer.play());
        playBtn.setToggleGroup(toggleGroup);
 
        ToggleButton suspendBtn = new ToggleButton("暂停");
        suspendBtn.setFont(new Font(fontSize));
        suspendBtn.setOnMouseClicked(event -> mediaPlayer.pause());
        suspendBtn.setToggleGroup(toggleGroup);
 
        ToggleButton continueBtn = new ToggleButton("继续");
        continueBtn.setFont(new Font(fontSize));
        continueBtn.setOnMouseClicked(event -> mediaPlayer.play());
        continueBtn.setToggleGroup(toggleGroup);
 
        ToggleButton closeBtn = new ToggleButton("结束");
        closeBtn.setFont(new Font(fontSize));
        closeBtn.setOnMouseClicked(event -> mediaPlayer.stop());
        closeBtn.setToggleGroup(toggleGroup);
        
        // 创建“全屏”按钮
        ToggleButton fScreenBtn = new ToggleButton("全屏");
        fScreenBtn.setFont(new Font(fontSize));
        fScreenBtn.setOnAction(e -> {
            Stage stage = (Stage) fScreenBtn.getScene().getWindow();
            stage.setFullScreen(true);
            mediaView.setFitWidth(stage.getWidth());
            mediaView.setFitHeight(stage.getHeight()); 
        });
        fScreenBtn.setToggleGroup(toggleGroup);
 
        HBox hBox = new HBox(3);
        hBox.setAlignment(Pos.CENTER);
        hBox.getChildren().addAll(playBtn, suspendBtn, continueBtn, closeBtn,fScreenBtn);  
 
        return hBox;
    }
    
    public static void main(String[] args) {
    	Application.launch(args);
	}
}

以下是测试播放演示效果图:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

前端构建工具(webpackvite)

这里写目录标题 构建工具webpack介绍配置文件简介entryoutputloaderbabel插件开发服务器&#xff08;webpack-dev-server&#xff09;soureMap vite 构建工具 当我们习惯了在node中编写代码的方式后&#xff0c;在回到前端编写html、css、js这些东西会感觉到各种的不便。比如:…

【PB案例学习笔记】-30动态打开窗口

写在前面 这是PB案例学习笔记系列文章的第30篇&#xff0c;该系列文章适合具有一定PB基础的读者。 通过一个个由浅入深的编程实战案例学习&#xff0c;提高编程技巧&#xff0c;以保证小伙伴们能应付公司的各种开发需求。 文章中设计到的源码&#xff0c;小凡都上传到了gite…

【C++报错已解决】Multiple Definition of Symbol

&#x1f3ac; 鸽芷咕&#xff1a;个人主页 &#x1f525; 个人专栏: 《C干货基地》《粉丝福利》 ⛺️生活的理想&#xff0c;就是为了理想的生活! 文章目录 引言一、问题描述1.1 报错示例1.2 报错分析1.3 解决思路 二、解决方法&#xff1a;方法一&#xff1a;使用extern关键…

Linux驱动开发-03字符设备驱动框架搭建

一、字符设备驱动开发步骤 驱动模块的加载和卸载&#xff08;将驱动编译模块&#xff0c;insmod加载驱动运行&#xff09;字符设备注册与注销&#xff08;我们的驱动实际上是去操作底层的硬件&#xff0c;所以需要向系统注册一个设备&#xff0c;告诉Linux系统&#xff0c;我有…

最新知识付费系统3.0整站+自动采集同步插件

支持分类替换 将主站同步过来的文章分类进行替换 支持自定义文章作者&#xff08;选择多个作者则同步到的文章作者将会随机分配&#xff09; 支持添加黑名单分类 添加后 如果同步过来的文章包含黑名单分类将不会发布文章 自动检测同步&#xff0c;无需人工值守以及挂采集软件…

ProFuzzBench入门教学——使用(Ubuntu22.04)

ProFuzzBench是网络协议状态模糊测试的基准测试。它包括一套用于流行协议&#xff08;例如 TLS、SSH、SMTP、FTP、SIP&#xff09;的代表性开源网络服务器&#xff0c;以及用于自动执行实验的工具。详细参考&#xff1a;阅读笔记——《ProFuzzBench: A Benchmark for Stateful …

研华运动控制卡在LabVIEW中的应用

在现代工业和科研领域中&#xff0c;精密运动控制系统的需求日益增加。这些系统广泛应用于自动化生产线、精密机械加工、机器人控制、光学仪器调试和实验室自动化设备等诸多领域。本文以研华公司的运动控制卡为例&#xff0c;详细介绍其在LabVIEW中的应用&#xff0c;展示如何通…

习题练习以

题意&#xff1a;求i&M的popcount的和&#xff0c;i属于0……N 主要思路还是变加为乘。 举个例子N22&#xff0c;即10110 假设M的第3位是1&#xff0c;分析N中&#xff1a; 00110 00111 00100 00101 发现其实等价于 0010 0011 0000 0001 也就是左边第4位和第5…

数据库基础练习4

准备 create table dept (dept1 int ,dept_name varchar(11)) charsetutf8; create table emp (sid int ,name varchar(11),age int,worktime_start date,incoming int,dept2 int) charsetutf8;insert into dept values(101,财务),(102,销售),(103,IT技术),(104,行政);INSERT …

诸葛亮的连环计 责任链模式

“万事谋定而后动&#xff0c;一环扣一环&#xff0c;方能成大事。” 在三国时期&#xff0c;诸葛亮以其超凡的智慧闻名天下。在他众多的计策中&#xff0c;有一个鲜为人知却极具智慧的连环计&#xff0c;完美诠释了现代软件设计中的责任链模式。让我们一同探索这个巧妙的计策…

【安全设备】堡垒机

一、什么是堡垒机 安全运维审计与风险控制系统即堡垒机&#xff0c;前身为跳板机&#xff0c;跳板机是一个简单的管理设备&#xff0c;但缺乏对运维操作的控制和审计能力。堡垒机是一种特定的网络安全设备&#xff0c;用于在一个网络环境中保护数据和网络不受外部和内部用户的…

Python酷库之旅-第三方库Pandas(013)

目录 一、用法精讲 31、pandas.read_feather函数 31-1、语法 31-2、参数 31-3、功能 31-4、返回值 31-5、说明 31-6、用法 31-6-1、数据准备 31-6-2、代码示例 31-6-3、结果输出 32、pandas.DataFrame.to_feather函数 32-1、语法 32-2、参数 32-3、功能 32-4、…

Go语言入门之基础语法

Go语言入门之基础语法 1.简单语法概述 行分隔符&#xff1a; 一行代表一个语句结束&#xff0c;无需写分号。将多个语句写在一行可以用分号分隔&#xff0c;但是不推荐 注释&#xff1a; // 或者/* */ 标识符&#xff1a; 用来命名变量、类型等程序实体。 支持大小写字母、数字…

Golang | Leetcode Golang题解之第226题翻转二叉树

题目&#xff1a; 题解&#xff1a; func invertTree(root *TreeNode) *TreeNode {if root nil {return nil}left : invertTree(root.Left)right : invertTree(root.Right)root.Left rightroot.Right leftreturn root }

Python函数 之 模块和包

1.模块 1, 在Python 中, 每个以 .py 结尾的 Python 代码⽂件 都可以称为是⼀个模块。 2, 在模块中 别⼈书写好的功能(变量, 函数, 类)&#xff0c;我们可以拿来直接使⽤。 3, 我们自己写的代码文件&#xff0c; 想要作为模块让别⼈使⽤, 你的代码⽂件名(模块名) 满足标识符的规…

大话光学原理:4.散射:瑞利、拉曼、米氏和布里渊

这是一缕柔和的光&#xff0c;在空气的舞台上轻盈地跳跃。它悠然自得&#xff0c;在宁静的空间中缓缓前行。然而&#xff0c;一片细薄透明的介质挡住了它的脚步&#xff0c;它毫无预兆地撞上了这片障碍。在这短暂的接触中&#xff0c;它被分解成无数微小的粒子&#xff0c;被迫…

LabVIEW电滞回线测试系统

铁电材料的性能评估依赖于电滞回线的测量&#xff0c;这直接关系到材料的应用效果和寿命。传统的电滞回线测量方法操作复杂且设备成本高。开发了一种基于LabVIEW的电滞回线测试系统&#xff0c;解决传统方法的不足&#xff0c;降低成本&#xff0c;提高操作便捷性和数据分析的自…

前端面试题38(js原型与对象)

在JavaScript中&#xff0c;原型&#xff08;prototype&#xff09;是核心特性之一&#xff0c;它用于实现对象之间的继承和属性方法的共享。理解原型和对象的关系对于深入学习JavaScript至关重要。下面我会详细解释这两个概念以及它们是如何工作的&#xff0c;并给出一些示例代…

关于Python的类的一些理解

才发现python的类对象只能调用类方法 我想使用对类对象a使用系统调用的len方法就会报错 2.类对象a是什么&#xff1f; 答&#xff1a;是所有的带有self的成员变量 举例说明&#xff1a;红色的就是a里面的东西 class A:def __init__(self,data):self.datadataself.b1self.d{a…

详细分析@FunctionalInterface的基本知识(附Demo)

目录 前言1. 基本知识2. Demo 前言 Java的基本知识推荐阅读&#xff1a; java框架 零基础从入门到精通的学习路线 附开源项目面经等&#xff08;超全&#xff09;Spring框架从入门到学精&#xff08;全&#xff09; 1. 基本知识 FunctionalInterface 是 Java 8 引入的一个注…