【效果图】

【功能】

1、当窗口获取焦点后,按空格暂停/播放

2、原速播放键、暂停/播放键、倍速播放键(最高3倍速,每次递增0.5)

3、进度条可点击选择播放位置

4、时间显示、播放速度显示

【项目与工具】

maven、java8、vlc-3.8.0、log4j-1.2.17

【代码】
Window.java

import java.awt.*;
import java.awt.event.*;
import java.util.Comparator;import javax.swing.*;
import javax.swing.border.EmptyBorder;import uk.co.caprica.vlcj.component.EmbeddedMediaPlayerComponent;
import uk.co.caprica.vlcj.player.embedded.EmbeddedMediaPlayer;
import utils.FileUtils;public class Window extends JFrame {// private final Logger logger = LoggerFactory.getLogger(Window.class);private static final int PROGRESS_HEIGHT = 10;private static final int PROGRESS_MIN_VALUE = 0;private static final int PROGRESS_MAX_VALUE = 100;// 总时间private static String TOTAL_TIME;// 播放速度private float speed;// 播放器组件private EmbeddedMediaPlayerComponent mediaPlayerComponent;// 进度条private JProgressBar progress;// 暂停按钮private Button pauseButton;// 显示播放速度的按钮private Label displaySpeed;// 显示时间private Label displayTime;// 进度定时器private Timer progressTimer;// 继续播放定时器private Timer continueTimer;// 所有视频路径private java.util.List<String> videos;// 当前播放视频的位置private int videoIndex;public Window(String videoFolder) {initVideoFilesPath(videoFolder);// 设置默认速度为原速speed = 1.0f;// 设置窗口标题setTitle("VideoPlayer");// 设置窗口焦点监听事件:窗口打开时、窗口获得焦点时设置默认焦点为暂停按钮this.addWindowFocusListener(getWindowFocusListener());// 窗口关闭事件:释放资源并退出程序addWindowListener(closeWindowReleaseMedia());// 设置默认窗口关闭事件// setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);// 设置窗口位置setBounds(100, 100, 800, 600);// 最大化显示窗口// setExtendedState(JFrame.MAXIMIZED_BOTH);// 主面板JPanel contentPane = new JPanel();contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));contentPane.setLayout(new BorderLayout(0, 0));setContentPane(contentPane);// ======播放面板======JPanel player = new JPanel();contentPane.add(player, BorderLayout.CENTER);contentPane.add(player);player.setLayout(new BorderLayout(0, 0));// 创建播放器组件并添加到容器中去mediaPlayerComponent = new EmbeddedMediaPlayerComponent();player.add(mediaPlayerComponent);// 视频表面焦点监听:表面获得焦点时设置默认焦点为暂停按钮getVideoSurface().addFocusListener(videoSurfaceFocusAction());// getMediaPlayer().setRepeat(true); // 重复播放// ======底部面板======JPanel bottomPanel = new JPanel();BoxLayout boxLayout = new BoxLayout(bottomPanel, BoxLayout.Y_AXIS);bottomPanel.setLayout(boxLayout);contentPane.add(bottomPanel, BorderLayout.SOUTH);// ------进度条组件面板------JPanel progressPanel = new JPanel();progress = new JProgressBar();progress.setMinimum(PROGRESS_MIN_VALUE);progress.setMaximum(PROGRESS_MAX_VALUE);progress.setPreferredSize(getNewDimension());// 设置进度条中间显示进度百分比progress.setStringPainted(false);// 进度条进度的颜色progress.setForeground(new Color(46, 145, 228));// 进度条背景的颜色progress.setBackground(new Color(220, 220, 220));// 点击进度条调整视频播放指针progress.addMouseListener(setVideoPlayPoint());// 定时器progressTimer = getProgressTimer();progressTimer.start();progressPanel.add(progress);progressPanel.setAlignmentX(Component.CENTER_ALIGNMENT);bottomPanel.add(progressPanel);// contentPane.add(progressPanel, BorderLayout.SOUTH);// ------按钮组件面板------JPanel buttonPanel = new JPanel();// contentPane.add(buttonPanel, BorderLayout.SOUTH);buttonPanel.setAlignmentX(Component.CENTER_ALIGNMENT);bottomPanel.add(buttonPanel);displayTime = new Label();displayTime.setText(getTimeString());buttonPanel.add(displayTime);// 重置按钮:设置播放速度为原速Button resetButton = new Button("reset");resetButton.setFocusable(false);resetButton.addMouseListener(mouseClickedResetSpeed());buttonPanel.add(resetButton);// 暂停/播放按钮pauseButton = new Button("pause");pauseButton.addKeyListener(spaceKeyPressMediaPause());pauseButton.addMouseListener(mouseClickedMediaPause());buttonPanel.add(pauseButton);// 倍速播放按钮:每次递增0.5,最大为3倍速Button fastForwardButton = new Button(">>>");fastForwardButton.setFocusable(false);fastForwardButton.addMouseListener(mouseClickedFastForward());buttonPanel.add(fastForwardButton);// 播放速度显示按钮displaySpeed = new Label();displaySpeed.setText("x" + speed);displaySpeed.setFocusable(false);displaySpeed.setEnabled(false);buttonPanel.add(displaySpeed);// 监听窗口大小,设置进度条宽度为窗口宽度(但是对于最大化和还原窗口无效,原因未知<-_->)this.addComponentListener(windowResizedResetProgressWidth());// 监听窗口最大化和还原,设置进度条宽度为窗口宽度this.addWindowStateListener(windowStateChangedResetProgressWidth());continueTimer = getContinueTimer();continueTimer.start();}private void initVideoFilesPath(String videoFolder) {videos = FileUtils.readFilePath(videoFolder);videos.sort(Comparator.naturalOrder());videoIndex = 0;// System.out.println(videos);}public void play() {getMediaPlayer().playMedia(videos.get(videoIndex));setWindowTitle();// System.out.println("play video..." + getMediaPlayer().getMediaMeta().getTitle());}private void setWindowTitle() {String title = getMediaPlayer().getMediaMeta().getTitle();setTitle("VideoPlayer-" + title);}private String getTimeString(long curr, long total) {return formatSecond2Time(curr) + " / " + formatSecond2Time(total);}private String getTimeString() {setTotalTime();return formatSecond2Time(getMediaPlayer().getTime()) + " / " + TOTAL_TIME;}private void setTotalTime() {if (TOTAL_TIME == null) {long totalSecond = getMediaPlayer().getLength();TOTAL_TIME = formatSecond2Time(totalSecond);}}private String formatSecond2Time(long milliseconds) {int second = (int) (milliseconds / 1000);int h = second / 3600;int m = (second % 3600) / 60;int s = (second % 3600) % 60;return String.format("%02d", h) + ":" + String.format("%02d", m) + ":"+ String.format("%02d", s);}private Timer getContinueTimer() {return new Timer(1000, new AbstractAction() {@Overridepublic void actionPerformed(ActionEvent e) {long total = getMediaPlayer().getLength();long curr = getMediaPlayer().getTime();if (curr == total) {videoIndex++;if (videoIndex >= videos.size()) {continueTimer.stop();System.out.println("all videos finished...");return;}getMediaPlayer().playMedia(videos.get(videoIndex));setWindowTitle();setProgress(getMediaPlayer().getTime(), getMediaPlayer().getLength());progressTimer.restart();}}});}private Timer getProgressTimer() {return new Timer(1000, new AbstractAction() {@Overridepublic void actionPerformed(ActionEvent e) {if (getProgress().getValue() >= PROGRESS_MAX_VALUE) {// 结束定时器progressTimer.stop();return;}// 设置进度值long total = getMediaPlayer().getLength();long curr = getMediaPlayer().getTime();setProgress(curr, total);}});}private void setProgress(long curr, long total) {float percent = (float) curr / total;int value = (int) (percent * 100);getProgress().setValue(value);displayTime.setText(getTimeString(curr, total));}private WindowAdapter windowStateChangedResetProgressWidth() {return new WindowAdapter() {@Overridepublic void windowStateChanged(WindowEvent state) {// state=1或7为最小化,此处不处理if (state.getNewState() == 0) {// System.out.println("窗口恢复到初始状态");setProgressWidthAutoAdaptWindow();} else if (state.getNewState() == 6) {// System.out.println("窗口最大化");setProgressWidthAutoAdaptWindow();}}};}private void setProgressWidthAutoAdaptWindow() {getProgress().setPreferredSize(getNewDimension());}private ComponentAdapter windowResizedResetProgressWidth() {return new ComponentAdapter() {@Overridepublic void componentResized(ComponentEvent e) {setProgressWidthAutoAdaptWindow();}};}private Dimension getNewDimension() {return new Dimension(getWidth(), PROGRESS_HEIGHT);}private MouseAdapter setVideoPlayPoint() {return new MouseAdapter() {@Overridepublic void mouseClicked(MouseEvent e) {int x = e.getX();long total = getMediaPlayer().getLength();long time = (long) ((float) x / progress.getWidth() * total);setProgress(time, total);getMediaPlayer().setTime(time);}};}private FocusAdapter videoSurfaceFocusAction() {return new FocusAdapter() {@Overridepublic void focusGained(FocusEvent e) {setPauseButtonAsDefaultFocus();}};}private WindowAdapter closeWindowReleaseMedia() {return new WindowAdapter() {@Overridepublic void windowClosing(WindowEvent e) {getMediaPlayer().stop();getMediaPlayer().release();System.exit(0);}};}private MouseListener mouseClickedResetSpeed() {return new MouseAdapter() {@Overridepublic void mouseClicked(MouseEvent e) {if (speed == 1.0f) {return;}speed = 1.0f;getMediaPlayer().setRate(speed);displaySpeed.setText("x" + speed);}};}private MouseListener mouseClickedFastForward() {return new MouseAdapter() {@Overridepublic void mouseClicked(MouseEvent e) {if (speed >= 3.0f) {speed = 1.0f;} else {speed += 0.5f;}getMediaPlayer().setRate(speed);displaySpeed.setText("x" + speed);}};}private MouseAdapter mouseClickedMediaPause() {return new MouseAdapter() {@Overridepublic void mouseClicked(MouseEvent e) {getMediaPlayer().pause();if (progressTimer.isRunning()) {progressTimer.stop();} else {progressTimer.restart();}}};}private WindowFocusListener getWindowFocusListener() {return new WindowAdapter() {@Overridepublic void windowOpened(WindowEvent e) {setPauseButtonAsDefaultFocus();}@Overridepublic void windowGainedFocus(WindowEvent e) {setPauseButtonAsDefaultFocus();}@Overridepublic void windowLostFocus(WindowEvent e) {}};}private void setPauseButtonAsDefaultFocus() {pauseButton.requestFocus();}private KeyListener spaceKeyPressMediaPause() {return new KeyAdapter() {@Overridepublic void keyPressed(KeyEvent e) {if (e.getKeyCode() == KeyEvent.VK_SPACE) {getMediaPlayer().pause();}}};}private JProgressBar getProgress() {return progress;}private EmbeddedMediaPlayer getMediaPlayer() {return mediaPlayerComponent.getMediaPlayer();}private Canvas getVideoSurface() {return mediaPlayerComponent.getVideoSurface();}}

Main.java

import org.apache.log4j.BasicConfigurator;import com.sun.jna.NativeLibrary;import uk.co.caprica.vlcj.runtime.RuntimeUtil;public class Main {public static void main(String[] args) {// 解决日志报错问题BasicConfigurator.configure();// 关闭日志// Logger.getRootLogger().shutdown();// 加载dllNativeLibrary.addSearchPath(RuntimeUtil.getLibVlcLibraryName(), "vlc");// 方式一:直接传文件夹String videoFolder = "E:\\tmp\\test\\videoTest";Window frame = new Window(videoFolder);frame.setVisible(true);frame.play();// 方式二:传文件// String filePath = "E:\\tmp\\test\\videoTest\\01_编程语言运行机制.avi";// EmbeddedMediaPlayer mediaPlayer = frame.getMediaPlayer();// mediaPlayer.playMedia(filePath);}}

FileUtils.java

package utils;import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.Stack;public class FileUtils {public static List<String> readFilePath(String folderPath) {List<String> list = new ArrayList<>();File folder = new File(folderPath);if (!folder.isDirectory()) {return list;}File[] files = folder.listFiles();if (Objects.isNull(files) || files.length <= 0) {return list;}for (File file : files) {if (!file.isFile()) {continue;}list.add(file.getAbsolutePath());}return list;}public static List<String> readAllFilePath(String folderPath) {Stack<File> stack = new Stack<>();List<String> list = new ArrayList<>();File folder = new File(folderPath);if (!folder.isDirectory()) {return list;}stack.push(folder);while (!stack.isEmpty()) {File tmpFile = stack.pop();File[] subFiles = tmpFile.listFiles();if (subFiles == null) {continue;}for (File subFile : subFiles) {if (subFile.isDirectory()) {stack.push(subFile);} else {list.add(subFile.getAbsolutePath());}}}return list;}}

依赖

<dependencies><!-- https://mvnrepository.com/artifact/uk.co.caprica/vlcj --><dependency><groupId>uk.co.caprica</groupId><artifactId>vlcj</artifactId><version>3.8.0</version></dependency><dependency><groupId>org.slf4j</groupId><artifactId>slf4j-api</artifactId><version>1.8.0-beta0</version></dependency><dependency><groupId>org.slf4j</groupId><artifactId>slf4j-log4j12</artifactId><version>1.8.0-beta0</version></dependency><dependency><groupId>log4j</groupId><artifactId>log4j</artifactId><version>1.2.17</version></dependency></dependencies>

vlc

vlc安装目录下的:
libvlc.dll文件
libvlccore.dll文件
plugins文件夹官网地址:https://www.videolan.org/vlc/

【项目结构】

【参考链接】

1、Java利用VLC开发简易的视频播放器-单向箭头
https://www.cnblogs.com/SnailsRunning/p/10251912.html

2、Java利用VLC开发简易视屏播放器-冷月枫寂
https://www.cnblogs.com/deng-c-q/p/7510418.html

3、使用java创建一个简易的视屏播放器-南柯一梦x
https://blog.csdn.net/nankeyimengxihe/article/details/50419449

4、Java Swing 图形界面开发(目录)-xietansheng
https://blog.csdn.net/xietansheng/article/details/72814492

5、Java制作进度条-晨曦之光Wing
https://blog.csdn.net/qq_36533690/article/details/106448207

6、MediaPlayerForJava(创建一个视频播放器)-FeiHuang
https://www.jianshu.com/p/2c61e3c6aa70

7、SLF4J: No SLF4J providers were found.-香山上的麻雀
https://www.jianshu.com/p/41e0a730347f

8、vlc官方文档
http://javadox.com/uk.co.caprica/vlcj/3.0.1/uk/co/caprica/vlcj/player/MediaPlayer.html

【说明】

没事做着玩一玩,其实也可以用一用,不过vlc会报几个错(好像也不会影响使用),目前暂时还没找到解决方法<-_->。错误比如这个[00000000222fd390] direct3d11 vout display error: SetThumbNailClip failed: 0x800706f4

【GitHub】

https://github.com/cxzgwing/simple-video-player

【后记】

2020.06.09

GitHub中的项目,截止到2020.06.09,简易播放器新增以下功能(共12个commits):

1、声音控制模块:音量百分比显示、点击音量进度条设置音量、鼠标轮滑滚动设置音量

2、选择文件按钮:支持多选文件(暂未判断文件类型)

3、查看播放文件列表(半透明效果):列表中文件名支持换行显示

4、播放/暂停按钮文案动态显示

5、升级了log4j版本,1.2.17升级到2.13.3

(最新版本与本文展示的源码版本差距有一丢丢大,嘻嘻(#^.^#),播放模式也改了,之前是写好路径,运行窗口就播放,最新版本是选择文件后点击播放按钮或按空格才播放)

【升级版本项目地址】

cxzgwing/video-player: Java简易视频播放器 升级版 (github.com)

【升级版本效果图】

【Java】简易视频播放器相关推荐

  1. java视频播放器制作_java创建简易视频播放器

    java创建简易视频播放器 发布时间:2020-09-23 04:28:09 来源:脚本之家 阅读:98 作者:南柯一梦xihe 最近有个多媒体的作业,要求使用visualC++和OpenCV编写一个 ...

  2. Android的媒体播放器——简易视频播放器(详解)

    一.案例效果 二.主界面的设计与功能 2.1 案例效果 2.2 布局界面 activity_main.xml 参考代码: <?xml version="1.0" encodi ...

  3. 视频播放页php,html jquery简易视频播放器

    html jquery js 简易视频播放器 直接上代码:html> Document #durationbar{ width: 500px; height: 20px; } #duration ...

  4. C语言基于GTK+Libvlc实现的简易视频播放器(二)

    简易视频播放器-全屏播放 一.课程说明 上一次我们使用gtk+libvlc实现了一个最简单的视频播放器,可以实现点击按钮暂定和停止播放视频,以及同步显示视频播放进度,但即使作为一个视频播放器,只有这些 ...

  5. 【基于QMediaPlayer的简易视频播放器】— 3、结合QSlider实现播放进度控制和音量控制

    基于QMediaPlayer的简易视频播放器 1.创建基本布局 2.QMediaPlayer的基本使用 3.结合QSlider实现播放进度控制和音量控制 4.重载QSlider鼠标响应事件,实现单击跳 ...

  6. java如何开发视频软件_使用JAVA编写视频播放器

    Java因其跨平台优势而陷入困境. 当时,我以为"写一次,到处跑". 这听起来不错,它应该是所有语言开发的最终方法. Java必将统治世界. 事实证明当时我还太小. 所谓的鱼和熊掌 ...

  7. 视频播放器+android,简易视频播放器

    NetConnection 对象 0002 var netConnection:NetConnection=new NetConnection ; 0003 /*如果连接到没有使用服务器的 priva ...

  8. 【Harmony OS】【ArkUI】ets开发 简易视频播放器

    前言:这一次我们来使用ets的Swiper组件.List组件和Video组件制作一个简易的视频播放器.本篇是以HarmonyOS官网的codelab简易视频播放器(eTS)为基础进行编写.本篇最主要的 ...

  9. Video标签自定义简易视频播放器

    Video标签自定义简易视频播放器 提示:以下是本篇文章正文内容,下面案例可供参考 一.Dom结构 <template><el-dialog :title="winTitl ...

最新文章

  1. VS2010/MFC编程入门之十七(对话框:文件对话框)
  2. 实践Jenkins集成Cobertura自动化构建SpringBoot工程
  3. 利用OpenCV的VideoCapture类实现视频读操作
  4. getRunningTask API
  5. Nginx命令与配置详解
  6. 聊一聊ABP vNext的模块化系统
  7. 网络七大趋势 媒介将很快彻底消失
  8. NLP自然语言处理库系列教程——gensim库
  9. 10套R语言教程+练习题
  10. p1957口算题c语言,洛谷P1957口算练习题题解
  11. base_c:字符串翻转练习
  12. 基于Aspect的情感分析
  13. 论文笔记 · Symmetry and Group in Attribute-Object Compositions(CVPR 2020)
  14. 外网访问家庭局域网方案,解决运营商100.x.x.x内网IP问题
  15. 怎么有python画五角星_Python的画五角星
  16. iOS 图片滚动播放
  17. torch dataloader 数据并行_PyTorch Parallel Training(单机多卡并行、混合精度、同步BN训练指南文档)
  18. 三极管和MOS管开关速度谁快呀
  19. python 执行命令并获取命令行输出_Python实现获取命令行输出结果的方法
  20. 锐起无盘2046 XP 教程(适合新手)

热门文章

  1. 如何调成适用计算机的分辨率,怎么调电脑分辨率调最合适
  2. pycharm创建python工程_使用Pycharm(Python工具)新建项目及创建Python文件的教程
  3. 钉钉“宜搭”,产品经理的需求管理利器
  4. linux版格式,计算机的组成、Linux主流三大版本的区别、Linux的哲学思想、Linux的使用格式及命令的使用简...
  5. 异构传感器定位论文概述
  6. Latex文档单双栏设置
  7. 解决:‘config.status: error: Something went wrong bootstrapping makefile fragments......’问题
  8. SAS Base基本操作
  9. 闹钟小程序(C#源码)
  10. AutoCAD常用快捷键