Java視頻播放器的制作


----------------siwuxie095

   

   

   

   

   

   

   

使用 Java Swing 框架制作一個簡單的視頻播放器:

   

   

首先到 VideoLAN 的官網下載 VLC media player,制作的視頻播放器內核

需要調用 VLC media player

   

VideoLAN:http://www.videolan.org/

   

VLC command-line help:https://wiki.videolan.org/VLC_command-line_help/

   

   

   

接着下載相關的在線開源庫:vlcj

   

GitHub 鏈接:https://github.com/caprica/vlcj

   

   

下載鏈接:

1http://capricasoftware.co.uk/#/projects/vlcj

2http://capricasoftware.co.uk/#/projects/vlcj/tutorial/installation

3http://download.csdn.net/detail/siwuxie095/9807180

   

   

vlcj 教程:http://capricasoftware.co.uk/#/projects/vlcj/tutorial

   

   

vlcj-3.8.0-dist.tar.gz 解壓后一覽:

   

   

   

   

必備的 4 個 jar 包:

1)jna-3.5.2.jar

2)platform-3.5.2.jar

3)vlcj-3.8.0.jar

4)slf4j-api-1.7.10.jar

   

   

   

雖然這 4 jar 包已經夠了,但根據控制台的提示:

Failed to load class "org.slf4j.impl.StaticLoggerBinder"

   

   

   

   

最好還是查看具體的細節:https://www.slf4j.org/codes.html#StaticLoggerBinder

   

可以導入頁面中所提到的 5 個包中的任何一個且只能一個來解決問題

1)slf4j-nop.jar

2)slf4j-simple.jar

3)slf4j-log4j12.jar

4)slf4j-jdk14.jar

5)logback-classic.jar

   

   

SLF4J 下載鏈接:

1https://www.slf4j.org/download.html

2http://download.csdn.net/detail/siwuxie095/9807191

   

   

   

我選擇導入 slf4j-nop-1.7.25.jar,即 5 個可選包中的第一個

   

   

   

   

工程名:MyVideoPlayer

包名:com.siwuxie095.main、com.siwuxie095.view

類名:VideoPlayer.java(主類)、MainWindow.java

   

   

打開資源管理器,在工程 MyVideoPlayer 文件夾下,創建一個

文件夾:lib,在其中放入:

1)jna-3.5.2.jar

2)platform-3.5.2.jar

3)vlcj-3.8.0.jar

4)slf4j-api-1.7.10.jar

5 slf4j-nop-1.7.25.jar

   

   

工程結構目錄如下:

   

   

   

   

全選這 5 jar 文件,右鍵->Build Path->Add to Build Path

   

此時,工程結構目錄一覽:

   

   

   

   

   

VideoPlayer.java(主類):

   

package com.siwuxie095.main;

   

import java.awt.EventQueue;

import java.io.File;

   

import javax.swing.JFileChooser;

import javax.swing.SwingWorker;

   

import com.siwuxie095.view.MainWindow;

import com.sun.jna.Native;

import com.sun.jna.NativeLibrary;

   

import uk.co.caprica.vlcj.binding.LibVlc;

import uk.co.caprica.vlcj.discovery.NativeDiscovery;

import uk.co.caprica.vlcj.runtime.RuntimeUtil;

   

public class VideoPlayer {

 

/**

* VLC播放器系統庫的路徑:D:\VLC media player\VLC

* 注意需要將路徑中的反斜杠改為斜杠,或 使用雙反斜杠(即通過轉義符進行轉義)

* 系統庫一般是在含有 libvlc.dlllibvlccore.dll 的路徑

*/

private static final String NATIVE_LIBRARY_SEARCH_PATH = "D:/VLC media player/VLC";

 

//將聲明轉移到類中,並設為 static

static MainWindow frame;

   

 

public static void main(String[] args) {

 

//(1)法一:首先要找到本機庫(VLC播放器的系統庫),這是自動搜索本機庫的位置

boolean found = new NativeDiscovery().discover();

System.out.println(found);

System.out.println(LibVlc.INSTANCE.libvlc_get_version());

   

   

//判斷當前的系統是否是Windows

//還可以判斷MacLinux,以傳入不同的路徑

if (RuntimeUtil.isWindows()) {

 

//(2)法二:手動設置本機庫(VLC播放器的系統庫)的路徑

NativeLibrary.addSearchPath(RuntimeUtil.getLibVlcLibraryName(),

NATIVE_LIBRARY_SEARCH_PATH);

 

System.out.println(LibVlc.INSTANCE.libvlc_get_version());

}

   

//加載VLC播放器的系統庫

Native.loadLibrary(RuntimeUtil.getLibVlcLibraryName(), LibVlc.class);

 

 

//在主方法中創建窗體

EventQueue.invokeLater(new Runnable() {

public void run() {

try {

frame = new MainWindow();

frame.setVisible(true);

//字幕的編碼

String options="--subsdec-encoding=GB18030";

/**

* prepareMedia() 先准備而不是馬上播放

* 可傳入視頻文件的路徑(和播放參數,如:字幕編碼)

* 這里使用雙反斜杠(通過轉義符進行轉義)

* 關於播放參數,可以參考 VLC command-line

* 鏈接:https://wiki.videolan.org/VLC_command-line_help/

* 進入后搜索 subsdec 設定字幕編碼

* 還可以傳入更多播放參數

*/

frame.getMediaPlayer().prepareMedia("C:\\Users\\siwux\\Desktop\\"

+ "testvideo\\test.mp4",options);

 

frame.getMediaPlayer().toggleFullScreen();

 

//創建一個 SwingWorker 線程,用於實時調節進度

//注意:創建完畢,最后要 execute() 將它運行起來

new SwingWorker<String, Integer>() {

   

@Override

protected String doInBackground() throws Exception {

 

while (true) {

//視頻總時長,以毫秒計

long total=frame.getMediaPlayer().getLength();

//當前所看時長,以毫秒計

long curr=frame.getMediaPlayer().getTime();

//百分比,並強轉為 float

float percent=(float)curr/total;

//因為進度條不是按百分比進行計算,而是 0-100 的數值范圍

//所以要乘 100,並強轉為 intpublish() process()

//(進度條范圍可設置,如果改為 0-120,就要乘 120)

publish((int)(percent*100));

 

//每隔 0.1 (100毫秒)更新一次進度條,如果不加則刷新過快

Thread.sleep(100);

}

 

}

 

protected void process(java.util.List<Integer> chunks) {

//創建int型變量 value 接收 chunks 中的值

for (int value : chunks) {

frame.getProgressBar().setValue(value);

}

 

};

}.execute();

} catch (Exception e) {

e.printStackTrace();

}

}

});

 

}

 

 

//播放

public static void play() {

frame.getMediaPlayer().play();

}

 

//暫停

public static void pause() {

frame.getMediaPlayer().pause();

}

 

//停止

public static void stop() {

frame.getMediaPlayer().stop();

}

 

 

public static void jumpTo(float to) {

//為跳轉設定時間:百分比乘以視頻時間的總長

frame.getMediaPlayer().setTime((long)(to*frame.getMediaPlayer().getLength()));

}

 

public static void openVideo() {

//創建文件選擇器:JFileChooser

JFileChooser chooser=new JFileChooser();

//將父級窗體設置成 null

int v=chooser.showOpenDialog(null);

if (v==JFileChooser.APPROVE_OPTION) {

File file=chooser.getSelectedFile();

//獲取到文件的絕對路徑,開始播放

frame.getMediaPlayer().playMedia(file.getAbsolutePath());

}

}

 

public static void openSubtitle() {

JFileChooser chooser=new JFileChooser();

int v=chooser.showOpenDialog(null);

if (v==JFileChooser.APPROVE_OPTION) {

File file=chooser.getSelectedFile();

//設定字幕,直接傳入 file 對象

frame.getMediaPlayer().setSubTitleFile(file);

}

}

 

public static void exit() {

//在退出之前,先釋放播放器的資源

frame.getMediaPlayer().release();

System.exit(0);

}

 

public static void setVol(int vol) {

//設定音量

frame.getMediaPlayer().setVolume(vol);

}

 

}

   

   

   

MainWindow.java:

   

package com.siwuxie095.view;

   

import java.awt.BorderLayout;

import java.awt.event.ActionEvent;

import java.awt.event.ActionListener;

import java.awt.event.MouseAdapter;

import java.awt.event.MouseEvent;

   

import javax.swing.JButton;

import javax.swing.JFrame;

import javax.swing.JMenu;

import javax.swing.JMenuBar;

import javax.swing.JMenuItem;

import javax.swing.JPanel;

import javax.swing.JProgressBar;

import javax.swing.JSlider;

import javax.swing.UIManager;

import javax.swing.UnsupportedLookAndFeelException;

import javax.swing.border.EmptyBorder;

import javax.swing.event.ChangeEvent;

import javax.swing.event.ChangeListener;

   

import com.siwuxie095.main.VideoPlayer;

import com.sun.java.swing.plaf.windows.WindowsLookAndFeel;

   

import uk.co.caprica.vlcj.component.EmbeddedMediaPlayerComponent;

import uk.co.caprica.vlcj.player.embedded.EmbeddedMediaPlayer;

   

public class MainWindow extends JFrame {

   

private JPanel contentPane;

 

//創建播放器的界面需要使用 EmbeddedMediaPlayerComponent

EmbeddedMediaPlayerComponent playerComponent;

 

private JPanel bottomPane;

private JButton btnPlay;

private JButton btnPause;

private JButton btnStop;

private JPanel controlPane;

private JProgressBar progress;

private JMenuBar menuBar;

private JMenu mnFile;

private JMenuItem mntmOpenvideo;

private JMenuItem mntmOpensubtitle;

private JMenuItem mntmExit;

private JSlider slider;

   

   

/**

* Create the frame.

*/

public MainWindow() {

 

try {

UIManager.setLookAndFeel(new WindowsLookAndFeel());

} catch (UnsupportedLookAndFeelException e) {

e.printStackTrace();

}

 

setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

setBounds(100, 100, 450, 300);

 

menuBar = new JMenuBar();

setJMenuBar(menuBar);

 

mnFile = new JMenu("File");

menuBar.add(mnFile);

 

mntmOpenvideo = new JMenuItem("OpenVideo");

mntmOpenvideo.addActionListener(new ActionListener() {

public void actionPerformed(ActionEvent e) {

VideoPlayer.openVideo();

}

});

mnFile.add(mntmOpenvideo);

 

mntmOpensubtitle = new JMenuItem("OpenSubtitle");

mntmOpensubtitle.addActionListener(new ActionListener() {

public void actionPerformed(ActionEvent e) {

VideoPlayer.openSubtitle();

}

});

mnFile.add(mntmOpensubtitle);

 

mntmExit = new JMenuItem("Exit");

mntmExit.addActionListener(new ActionListener() {

public void actionPerformed(ActionEvent e) {

VideoPlayer.exit();

}

});

mnFile.add(mntmExit);

contentPane = new JPanel();

contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));

contentPane.setLayout(new BorderLayout(0, 0));

setContentPane(contentPane);

 

JPanel videoPane = new JPanel();

contentPane.add(videoPane, BorderLayout.CENTER);

videoPane.setLayout(new BorderLayout(0, 0));

 

// videoPane 創建之后實例化 playerComponent

playerComponent=new EmbeddedMediaPlayerComponent();

// playerComponent 添加到 videoPane 中,並指定布局

videoPane.add(playerComponent, BorderLayout.CENTER);

 

bottomPane = new JPanel();

videoPane.add(bottomPane, BorderLayout.SOUTH);

bottomPane.setLayout(new BorderLayout(0, 0));

 

controlPane = new JPanel();

bottomPane.add(controlPane);

 

btnStop = new JButton("Stop");

controlPane.add(btnStop);

btnStop.setFocusable(false);

 

btnPlay = new JButton("Play");

controlPane.add(btnPlay);

btnPlay.setFocusable(false);

 

btnPause = new JButton("Pause");

controlPane.add(btnPause);

btnPause.setFocusable(false);

 

slider = new JSlider();

slider.setFocusable(false);

//關於默認音量的設定要在 stateChanged 事件之前

//如果要設定最大音量和最小音量也是如此

slider.setValue(20);

//為音量調節 slider 添加 stateChanged 事件

slider.addChangeListener(new ChangeListener() {

public void stateChanged(ChangeEvent e) {

VideoPlayer.setVol(slider.getValue());

}

});

 

 

controlPane.add(slider);

 

progress = new JProgressBar();

progress.setFocusable(false);

 

//為進度條 progress 添加 mouseClicked 事件

progress.addMouseListener(new MouseAdapter() {

@Override

public void mouseClicked(MouseEvent e) {

//獲取鼠標點擊在進度條上的位置

int x=e.getX();

//計算點擊位置占進度條總長的百分比

float per=(float)x/progress.getWidth();

VideoPlayer.jumpTo(per);

}

});

//讓進度條 progress 顯示數字百分比

progress.setStringPainted(true);

bottomPane.add(progress, BorderLayout.NORTH);

 

 

// Stop 按鈕添加 mouseClicked 事件

btnStop.addMouseListener(new MouseAdapter() {

@Override

public void mouseClicked(MouseEvent e) {

VideoPlayer.stop();

}

});

 

   

// Play 按鈕添加 mouseClicked 事件

btnPlay.addMouseListener(new MouseAdapter() {

@Override

public void mouseClicked(MouseEvent e) {

VideoPlayer.play();

}

});

 

 

// Pause 按鈕添加 mouseClicked 事件

btnPause.addMouseListener(new MouseAdapter() {

@Override

public void mouseClicked(MouseEvent e) {

VideoPlayer.pause();

}

});

 

}

 

 

//返回媒體播放器的實例

public EmbeddedMediaPlayer getMediaPlayer() {

return playerComponent.getMediaPlayer();

}

 

 

//返回JProgressBar的實例

public JProgressBar getProgressBar() {

return progress;

}

   

}

   

   

   

將窗體 JFrame 的 LookAndFeel 設定為 Windows

   

   

根面板 contentPane 使用默認布局 Border Layout

   

   

在 contentPane 的中間添加一個 JPanel,將其布局改為:

Border Layout,Rename 為 videoPane

   

   

在 videoPane 的下方添加一個 JPanel,將其布局改為:

Border Layout,Rename 為 bottomPane

   

   

在 bottomPane 的中間添加一個 JPanel,將其布局改為:

Flow Layout,Rename 為 controlPane

   

   

在 controlPane 中添加三個 JButton 和一個 JSlider

   

   

將三個 JButton 的 focusable 屬性設為 false,並將其文本(text)分別改為:

Stop、Play 和 Pause,再分別 Rename 為:btnStop、btnPlay 和 btnPause

   

   

為三個 JButton 添加 mouseClicked 事件,實現對應 停止、播放 和 暫停 的功能

   

   

Slider 的 focusable 屬性設為 false

   

   

JSlider 添加 stateChanged 事件,實現 調節音量 的功能

   

   

bottomPane 的上方添加一個 JProgressBar

   

   

JProgressBar 的 focusable 屬性設為 false,stringPainted 屬性設為 true,

並 Rename 為:progress

   

   

為 JProgressBar 添加 mouseClicked 事件,實現 調節進度 的功能

   

   

JFrame 的上方添加一個 JMenuBar,注意:JMenuBar 和 contentPane 同級

   

   

制作 菜單欄,為 菜單項 添加 actionPerformed 事件,實現

打開視頻、打開字幕 和 退出 的功能

   

   

   

整體的 Components 視圖:

   

   

   

   

運行程序:

   

   

   

   

   

   

最后導出為可執行的 Java 程序:

選擇工程 MyVideoPlayer,右鍵->Export->Java->Runnable JAR file

   

然后選擇當前主類:VideoPlayer - MyVideoPlayer,導出

路徑指定為:E:\workspace\MyVideoPlayer\release,並

命名為:MyVideoPlayer.jar

   

   

   

   

   

   

   

   

【made by siwuxie095】


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM