JavaSwing_使用树莓派播放视频_三种方法(FX,CLV,CLVJ)_一蓑烟雨任平生


前言

项目需求:老板要大屏显示视频,还可以用手机上的微信小程序控制暂停播放


播放视频谁不会?

MP4用爱奇艺播放器啊,迅雷影音啊,腾讯视频啊

树莓派播放?

树莓派专用系统Raspbian底层是Linux,也就是一片漆黑的命令窗口,也不支持那些exe安装的软件

一、使用技术

1.控制设备

使用mqtt,根据订阅的主题不一样进行分发指令

2.怎么窗口播放

这里使用的Swing,比较古老的窗口化,Java的Gui

3.视频卡死

减少线程个数,thread

4.远程显示

VPN可视化界面

5.远程命令链接

PUTTY,有人说用XShell,一样随个人喜好

6.文件传输

FileZilla,这个使用sftp就可以传输,有人说远程桌面,那需要安装xrdp,看个人喜好

二、视频播放

一、omxplayer播放

1.安装树莓派播放器

sudo apt-get install omxplayer

2.播放视频

sodo omxplayer -o hdmi /path/to/filename.mp4 --loop

缺陷:不能控制开始暂停,所以PASS

二.vlc播放

1.环境配置

(1)下载VLC VlC官网http://www.videolan.org/ 各个版本的下载地址http://download.videolan.org/pub/videolan/vlc/last/ 里面有32位和64位的区分,按照自己的系统下载对应的vlc版本,下载解压后提取;
(2)下载VLCJ (http://capricasoftware.co.uk/#/projects/vlcj)把下载文件解压后将其目录下的jna-3.5.2.jar、platform-3.5.2.jar、vlcj-3.8.0.jar(不同版本后缀数字可能会不同)三个文件复制到对应的java工程目录(新建 lib 文件夹)下;

如果是maven工程直接引入maven即可

(3)将vlc安装目录下的libvlc.dll、libvlccore.dll 两个文件以及plugins问佳佳复制到对应的java工程目录下;根目录

2.代码编写

播放器主类代码

package deng.test;

import java.awt.EventQueue;
import java.io.File;

import javax.swing.JFileChooser;
import javax.swing.SwingWorker;

import com.sun.jna.Native;
import com.sun.jna.NativeLibrary;

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

public class PlayerMain {

    static Window frame;
    private static int times=1;
    private static boolean flag=true;
    // private static final String NATIVE_LIBRARY_SEARCH_PATH = "D:\\Program
    // Files\\VideoLAN\\VLC\\sdk\\lib";

    public static void main(String[] args) {

        // 环境配置,将vlc sdk导入到eclipse

        // if(RuntimeUtil.isWindows()){ }
        // NativeLibrary.addSearchPath(RuntimeUtil.getLibVlcLibraryName(),
        // "D:\\vlc\\vlc-2.2.6\\sdk\\lib"); //导入的路径是vlc的安装路径
        NativeLibrary.addSearchPath(RuntimeUtil.getLibVlcLibraryName(), "vlcj//lib"); // 导入的路径是vlc的安装路径
        Native.loadLibrary(RuntimeUtil.getLibVlcLibraryName(), LibVlc.class);
        // System.out.println(LibVlc.INSTANCE.libvlc_get_version());

        // 创建主程序界面运行窗体
        EventQueue.invokeLater(new Runnable() {

            @Override
            public void run() {
                    try {
                        frame = new Window();
                        frame.setVisible(true);
                        frame.getMediaPlayer().playMedia("video//style.avi"); // 直接播放视屏,参数是视屏文件的绝对路径
                        // frame.getMediaPlayer().prepareMedia("video//test.mp4");
                        // //控制即将播放的视频
                        new SwingWorker<String, Integer>() {

                            @Override
                            protected String doInBackground() throws Exception {
                                // TODO Auto-generated method stub
                                while (flag) { // 获取视频播放进度并且按百分比显示
                                    long total = frame.getMediaPlayer().getLength();
                                    if(total==-1){//如果视频播放完,循环播放视频
                                        play();
                                        times++;
                                        System.out.println(times+"******************");
                                    }
                                    long curr = frame.getMediaPlayer().getTime();
                                    float percent = (float) curr / total;
                                    publish((int) (percent * 100));
                                    Thread.sleep(100);
                                }
                                return null;
                            }

                            protected void process(java.util.List<Integer> chunks) {
                                for (int v : chunks) {
                                    frame.getProgressBar().setValue(v);
                                }
                            }
                        }.execute();
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }

        });
    }
    
    //关闭播放器释放资源
    public static void dispose(){
        flag=false;
        frame.getMediaPlayer().stop();
        frame.dispose();
    }

    // 打开文件
    public static void openVideo() {
        JFileChooser chooser = new JFileChooser();
        int v = chooser.showOpenDialog(null);
        if (v == JFileChooser.APPROVE_OPTION) {
            File file = chooser.getSelectedFile();
            frame.getMediaPlayer().playMedia(file.getAbsolutePath());
        }
    }

    // 退出播放
    public static void exit() {
        frame.getMediaPlayer().release();
        System.exit(0);
    }

    // 实现播放按钮的方法
    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 setVol(int v) {
        frame.getMediaPlayer().setVolume(v);
    }

}

播放器窗体类:

package deng.test;

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.border.EmptyBorder;  
import javax.swing.event.ChangeEvent;  
import javax.swing.event.ChangeListener;  
  
import uk.co.caprica.vlcj.component.EmbeddedMediaPlayerComponent;  
import uk.co.caprica.vlcj.player.embedded.EmbeddedMediaPlayer;  
  
@SuppressWarnings("serial")
public class Window extends JFrame{  
      
    private JPanel contentPane; //顶层容器,整个播放页面的容器  
    private JMenuBar menuBar;   //菜单栏  
    private JMenu mnFile,mnSetting,mnHelp;  //文件菜单  
    private JMenuItem mnOpenVideo,mnExit;   //文件菜单子目录,打开视屏、退出  
    private JPanel panel;   //控制区域容器  
    private JProgressBar progress;  //进度条  
    private JPanel progressPanel;   //进度条容器  
    private JPanel controlPanel;    //控制按钮容器  
    private JButton btnStop,btnPlay,btnPause;   //控制按钮,停止、播放、暂停  
    private JSlider slider;     //声音控制块  
      
      
    EmbeddedMediaPlayerComponent playerComponent;   //媒体播放器组件  
      
    public static void main(String[] args) {  
          
    }  
  
    //MainWindow构造方法,创建视屏播放的主界面  
    public Window(){  
        setTitle("   小婷婷专属播放器   Copyright@dengchaoqun");  
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);  
        setBounds(200,80,900,600);  
        contentPane=new JPanel();  
        contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));  
        contentPane.setLayout(new BorderLayout(0,0));  
        setContentPane(contentPane);
          
        /*视频播放窗口中的菜单栏*/  
        menuBar=new JMenuBar();  
        setJMenuBar(menuBar);  
          
        mnFile=new JMenu("文件");     //设置菜单名  
        menuBar.add(mnFile);  
        mnSetting=new JMenu("设置");  
        menuBar.add(mnSetting);  
        mnHelp=new JMenu("帮助");  
        menuBar.add(mnHelp);  
          
        mnOpenVideo =new JMenuItem("打开文件"); //设置文件菜单子目录打开文件  
        mnFile.add(mnOpenVideo);  
          
        mnExit =new JMenuItem("退出");    //设置文件菜单子目录退出  
        mnFile.add(mnExit);  
          
        //打开文件  
        mnOpenVideo.addActionListener(new ActionListener() {  
              
            @Override  
            public void actionPerformed(ActionEvent e) {  
                // TODO Auto-generated method stub  
                PlayerMain.openVideo();  
            }  
        });  
          
        //退出  
        mnExit.addActionListener(new ActionListener() {  
              
            @Override  
            public void actionPerformed(ActionEvent e) {  
                // TODO Auto-generated method stub  
                PlayerMain.exit();  
            }  
        });  
          
          
        /*视屏窗口中播放界面部分*/  
        JPanel videoPane=new JPanel();  
        contentPane.add(videoPane, BorderLayout.CENTER);  
        videoPane.setLayout(new BorderLayout(0,0));
          
        playerComponent=new EmbeddedMediaPlayerComponent();  
        videoPane.add(playerComponent);  
          
        /*视屏窗口中控制部分*/  
          
        panel=new JPanel();     //实例化控制区域容器  
        videoPane.add(panel,BorderLayout.SOUTH);  
          
        progressPanel=new JPanel(); //实例化进度条容器  
        panel.add(progressPanel, BorderLayout.NORTH);  
  
        //添加进度条  
        progress=new JProgressBar();      
        progressPanel.add(progress);  
        //panel.add(progress,BorderLayout.NORTH);  
        progress.addMouseListener(new MouseAdapter() {  
            @Override  
            public void mouseClicked(MouseEvent e){     //点击进度条调整视屏播放进度  
                int x=e.getX();  
                PlayerMain.jumpTo((float)x/progress.getWidth());  
            }  
        });  
        progress.setStringPainted(true);  
          
          
        controlPanel=new JPanel();      //实例化控制按钮容器  
        panel.add(controlPanel,BorderLayout.SOUTH);  
          
        //添加停止按钮  
        btnStop=new JButton("停止");  
        btnStop.addMouseListener(new MouseAdapter() {  
            @Override  
            public void mouseClicked(MouseEvent e) {  
                // TODO Auto-generated method stub  
                PlayerMain.stop();  
            }  
        });  
        controlPanel.add(btnStop);  
          
        //添加播放按钮  
        btnPlay=new JButton("播放");  
        btnPlay.addMouseListener(new MouseAdapter() {  
            @Override  
            public void mouseClicked(MouseEvent e) {  
                // TODO Auto-generated method stub  
                PlayerMain.play();  
            }  
        });  
        controlPanel.add(btnPlay);  
          
        //添加暂停按钮  
        btnPause=new JButton("暂停");  
        btnPause.addMouseListener(new MouseAdapter() {  
            @Override  
            public void mouseClicked(MouseEvent e) {  
                // TODO Auto-generated method stub
                //PlayerMain.dispose();
                PlayerMain.pause();  
            }  
        });  
        controlPanel.add(btnPause);  
          
        //添加声音控制块  
        slider=new JSlider();  
        slider.setValue(80);  
        slider.setMaximum(100);  
        slider.addChangeListener(new ChangeListener() {  
              
            @Override  
            public void stateChanged(ChangeEvent e) {  
                // TODO Auto-generated method stub  
                PlayerMain.setVol(slider.getValue());  
            }  
        });  
        controlPanel.add(slider);  
    }  
      
    //获取播放媒体实例(某个视频)  
    public EmbeddedMediaPlayer getMediaPlayer() {  
        return playerComponent.getMediaPlayer();  
    }  
      
    //获取进度条实例  
    public JProgressBar getProgressBar() {  
        return progress;  
    }  
      
}

缺陷:windows开发的不支持Linux,所以Pass

三.JavaFX播放

1.不要看官网,直接开撸

看了FX半天的官网,什么JDK环境必须11+,什么插件安装,什么dll安装,总结四个字:一派胡言

2.直接上代码:

import javafx.application.Application;
import javafx.scene.Scene;
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.stage.Stage;
import javafx.util.Duration;

import java.io.File;

/**
 * @Author: 一蓑烟雨
 * @Description: 音频、视频播放Demo
 * @Date: 2021/6/3 21:46
 * @Version: 1.0
 */
public class MediaDemo extends Application{

    public static void main(String[] args) {
        launch(args);
    }

    @Override
    public void start(Stage primaryStage){
        // 音频或视频的路径
        // 举例中的路径为工程根目录下的test.mp4
        // 如果不能正常播放,则音频或视频文件可能损坏;或者有版权,需对应的播放器正常播放;或者录屏后重新尝试,避过版权问题
        //String url = new File(System.getProperty("user.dir") + "/test.mp4").getAbsoluteFile().toURI().toString();
        File url = new File("D://131.mp4");
        //String s = url.getAbsoluteFile().toURI().toString();
        String s = "http://222.133.14.246:19091//hnyfkj-file-server/plugins/im/mp4/20210603/131.mp4";
        //String url = "D://131.mp4";
        Media media = new Media(s);
        MediaPlayer mediaPlayer = new MediaPlayer(media);
        // 设置音量:0.0 - 1.0
        mediaPlayer.setVolume(0.5);
        // 设置开始时间
        mediaPlayer.setStartTime(Duration.seconds(1));
        MediaView mView = new MediaView(mediaPlayer);
        System.out.println(media.getSource());

        VBox vBox = new VBox(3);
        vBox.getChildren().add(mView);
        vBox.setPrefWidth(580);
        vBox.setPrefHeight(360);
        mView.setFitWidth(vBox.getPrefWidth());
        mView.setFitHeight(vBox.getPrefHeight() - 40);

        int fontSize = 16;

        ToggleGroup toggleGroup = new ToggleGroup();

        ToggleButton playButton = new ToggleButton("播放");
        playButton.setFont(new Font(fontSize));
        playButton.setOnMouseClicked(event -> mediaPlayer.play());
        playButton.setToggleGroup(toggleGroup);

        ToggleButton suspendButton = new ToggleButton("暂停");
        suspendButton.setFont(new Font(fontSize));
        suspendButton.setOnMouseClicked(event -> mediaPlayer.pause());
        suspendButton.setToggleGroup(toggleGroup);

        ToggleButton continueButton = new ToggleButton("继续");
        continueButton.setFont(new Font(fontSize));
        continueButton.setOnMouseClicked(event -> mediaPlayer.play());
        continueButton.setToggleGroup(toggleGroup);

        ToggleButton closeButton = new ToggleButton("结束");
        closeButton.setFont(new Font(fontSize));
        closeButton.setOnMouseClicked(event -> mediaPlayer.stop());
        closeButton.setToggleGroup(toggleGroup);

        HBox hBox = new HBox(3);
        hBox.getChildren().addAll(playButton, suspendButton, continueButton, closeButton);
        vBox.getChildren().add(hBox);

        Scene scene = new Scene(vBox,580,360);
        primaryStage.setTitle("MediaDemo");
        primaryStage.setScene(scene);
        primaryStage.show();
    }
}

缺陷:在树莓派系统播放总是Mtqq报错,所以Pass(具体原因还在排查)

三.vlcj播放

vlcj比vlc多了一个字母J,有啥区别?具体区别我也不清楚,不过这个比那个适应力更强,不需要记载本地dll,所以跨平台性比较高,然后可以在任何平台依附平台播放器的安装位置来播放

1.环境搭建

跟clv环境是一样的只不过不需要复制plugs和dll到项目中,因为vlcj是跨平台的,所以Linux不能加载dll,不需要加在dll了

2.代码

播放器代码的实现

package videoPlayer.Main;

import java.awt.EventQueue;
import java.io.File;
import javax.swing.JFileChooser;
import javax.swing.SwingWorker;
import com.sun.jna.NativeLibrary;
import uk.co.caprica.vlcj.discovery.NativeDiscovery;
import uk.co.caprica.vlcj.runtime.RuntimeUtil;
import videoPlayer.views.MainWindow;

public class MainVideoPlayler {
    //声明全局变量MainWindow
    static MainWindow frame;
    public static void main(String[] args) {
        //实例化NativeDiscovery类
        new NativeDiscovery().discover();
        //通过判断选择系统,Windows,Mac OS,Liunx。以下都是各个系统的VLC默认安装路径
        if (RuntimeUtil.isWindows()) {
            NativeLibrary.addSearchPath(
                RuntimeUtil.getLibVlcLibraryName(), "C:\\Program Files\\VideoLAN\\VLC");
        }else if (RuntimeUtil.isMac()) {
            NativeLibrary.addSearchPath(
                RuntimeUtil.getLibVlcLibraryName(), "/Applications/VLC.app/Contents/MacOS/lib");
        }else if (RuntimeUtil.isNix()) {
            NativeLibrary.addSearchPath(
                RuntimeUtil.getLibVlcLibraryName(), "/home/linux/vlc/install/lib");
        }
        EventQueue.invokeLater(new Runnable() {
        public void run() {
            try {
                frame = new MainWindow();
                frame.setVisible(true);
                //通过--subsdec-encoding= 可以指定字幕文件编码格式
                String options[] = {"--subsdec-encoding=GB18030"};

				//循环播放
				frame.getMediaPlayer().setRepeat(true);
                //让窗体获得视频资源
                frame.getMediaPlayer().prepareMedia(
                    "D:\\xxxx.mp4",options);
                //prepareMedia();是准备播放视频。而playMedia();是直接播放视频
                //frame.getMediaPlayer().playMedia(
               // "D:\\我的文件\\06、Java语言\\7、界面设计\\10、Java视频播放器的制作\\1、工程的准备.mp4",options);
                new SwingWorker<String, Integer>() {
                    //调节视频音量
                    protected String doInBackground() throws Exception {
                    while (true) {
                        //获得当前视频总时间长度
                        long total = frame.getMediaPlayer().getLength();
                        //获得当期播放时间
                        long curr = frame.getMediaPlayer().getTime();
                        //获取播放视频的百分比
                        float percent = ((float)curr/total);
                        publish((int)(percent*100));
                        Thread.sleep(100);
                     }
                    }
                    protected void process(java.util.List<Integer> chunks) {
                    for (int v:chunks) {
                        frame.getProgressBar().setValue(v);
                        }
                    };
                }.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 chooser = new JFileChooser();
        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();
            frame.getMediaPlayer().playMedia(file.getAbsolutePath());
        }
        File file = chooser.getSelectedFile();
        frame.getMediaPlayer().setSubTitleFile(file);
    }
    //实现软件退出
    public static void exit() {
        frame.getMediaPlayer().release();
        System.exit(0);
    }
    //调节音量
    public static void volume(int v) {
        frame.getMediaPlayer().setVolume(v);
    }
}

缺陷:在树莓派系统播放播放一小时会卡关机,但是有思路,我准备先把视频加载缓存到本地,然后进行播放是不是会好点(树莓派本身运行内存就小,所以播放视频还是有难度的,一半用来做嵌入式开发会好一些,播放视频用windows会好点)

总结

方法不同,效果也不同,优缺点也不同,看个人喜好

在这里插入图片描述

  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值