English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية
1. Принцип реализации музыкального плеера
Мультимедийные функции Javase очень слабы, поэтому есть специальный плагин для обработки мультимедиа, называемый JMF, модели, предоставляемые JMF, можно大致 разделить на семь категорий
* Источник данных (Data source)
* Устройство захвата (Capture Device, включая видео и аудио устройства захвата)
* Воспроизводящее устройство (Player)
* Обработчик (Processor)
* Пул данных (DataSink)
* Формат данных (Format)
* Управляющий (Manager)
А я создал этот музыкальный плеер MyMusicPlayer (имя класса, которое я создал) именно для того, чтобы использовать Player класс из JMF для реализации его воспроизведения и других функций.
Прежде всего, что нам нужно сделать, это установить JMF. Установка JMF, возможно, является довольно сложной задачей для многих новеньких, так как JMF поддерживает только 32-битные версии JDK, а такие IDE, как Eclipse, должны соответствовать JDK, то есть среда IDE должна поддерживать 32-битные версии JDK. После установки JMF иногда не удается воспроизвести MP3, и необходимо установить mp3plugin JMF.
Второй раздел:效果图 интерфейса
Третий раздел: структура функций
Четвертый раздел: код для различных функций
public class MyMusicPlayer implements ActionListener, ControllerListener,Runnable{ JFrame j=new JFrame("Музыкальный плеер"); JLabel TablePlaer=new JLabel("Список воспроизведения"); JButton BAdd=new JButton("Добавить песню"); JButton BDelect=new JButton("Удалить песню"); JButton BDelectTable=new JButton("Очистить список"); JButton BMoveNext=new JButton("Следующий трек"); JButton BMovePrevious=new JButton("Предыдущий трек"); JButton BPlayer=new JButton("Пауза"); JButton BStop=new JButton("Стоп"); JButton BSet=new JButton("Показать текст песни"); JButton BEnd=new JButton("Стоп"); String[] s={"Плеер в порядке","Повтор одного трека","Случайное воспроизведение"}; //Массив вариантов списка JComboBox select=new JComboBox(s); //Создание выпадающего списка JPanel p1=new JPanel(); //Область списка воспроизведения JPanel p=new JPanel(); JPanel p2=new JPanel(); //Область кнопок JPanel p3=new JPanel(); JLabel l=new JLabel(); JPanel p5=new JPanel(); //Место для списка воспроизведения JPanel p6=new JPanel(); //Место для названия播放的歌曲 static JPanel pp=new JPanel(); static JLabel lb; public static JTextArea jt=new JTextArea(); static int index; // Индекс списка воспроизведения int count; int flag; // Маркер для определения случайного или последовательного воспроизведения int countSecond; // Получается общее время музыки static int newtime = 0; int ischanging = 0; // При клике мыши по курсору значение прогресса также изменяется int ispressing = 0; // Определяет, был ли клик мыши по курсору File MusicName = null; static java.util.List<File> MusicNames = null; // Используется generics для создания объекта File File currentDirectory = null; List list; // Список файлов FileDialog open; // Определяется объект диалогового окна файла Random rand = new Random(); String filename; // Прогресс-бар JButton timeInformation = new JButton(); JSlider timeSlider = new JSlider(SwingConstants.HORIZONTAL, 0, 100, 0); // Используется для направления ползунка в горизонтальном направлении. // (0, 100, 0) Создается горизонтальный ползунок с указанными минимальным, максимальным и начальным значениями. // 播放 Player player = null; MusicFileChooser fileChooser = new MusicFileChooser(); static JTextPane tp=new JTextPane(); //显示歌词区域 static JTextArea are=new JTextArea(); //显示图片区域 public MyMusicPlayer(){ j.setSize(1200, 700); j.setLayout(null); j.getContentPane().setBackground(Color.BLACK); j.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); p.setBounds(2, 563, 1180, 95)} p.setLayout(new BorderLayout()); p1.setBounds(2, 3, 298, 30); p1.setBackground(new Color(255, 255, 255)); p2.setLayout(new GridLayout(2, 3, 20, 20)); p2.setBackground(Color.LIGHT_GRAY); p3.setLayout(new GridLayout(2, 0, 200, 10)); p3.setBackground(new Color(255, 255, 255)); p5.setBounds(2, 35, 298, 526); p5.setLayout(null); p5.setBackground(new Color(255, 255, 255)); p6.setBounds(301, 3, 880, 30); p6.setLayout(null); p6.setBackground(new Color(255, 255, 255)); l.setBounds(250, 4, 600, 30); // Настройка отображения играющей песни p6.add(l); /* Реализация вставки изображения /* */ ImageIcon ic = new ImageIcon("image\\2.3.jpg"); ic = new ImageIcon(ic.getImage().getScaledInstance(880, 477, 2)); // Получение изображения и настройка размера изображения lb = new JLabel(ic); lb.setOpaque(false); pp.setOpaque(false); // Установлено как прозрачное pp.setBounds(241, 80, 990, 500); are.setBounds(241, 56, 990, 520); are.setOpaque(false); tp.setBackground(new Color(255, 255, 255)); tp.setBounds(301, 35, 880, 49); pp.add(are); pp.add(lb); // Список файлов list = new List(10); list.setBounds(100, 55, 187, 495); //列表区域 list.addActionListener(this); j.add(list); j.add(jt); j.add(tp); BAdd.setBounds(5,20, 90,30); BAdd.setBackground(new Color(255,255,255)); BDelect.setBounds(5, 80, 90, 30); BDelect.setBackground(new Color(255,255,255)); BDelectTable.setBounds(5, 140, 90, 30); BDelectTable.setBackground(new Color(255,255,255)); TablePlaer.setBounds(30, 100, 200, 50); TablePlaer.setFont(new Font("宋体",1, 20)); p1.add(TablePlaer); BMovePrevious.setBackground(new Color(255,255,255)); BPlayer.setBackground(new Color(255,255,255)); BMoveNext.setBackground(new Color(255,255,255)); BStop.setBackground(new Color(255,255,255)); select.setBackground(new Color(255,255,255)); BSet.setBackground(new Color(255,255,255)); p2.add(BMovePrevious); p2.add(BPlayer); p2.add(BMoveNext); p2.add(BStop); p2.add(select); p2.add(BSet); p2.setBackground(new Color(255,255,255)); p.add(p2,BorderLayout.WEST); p.add(p3,BorderLayout.CENTER); p5.add(p); p5.add(BAdd); p5.add(BDelect); p5.add(BDelectTable); BAdd.addActionListener(this); BDelect.addActionListener(this); BDelectTable.addActionListener(this); BMoveNext.addActionListener(this); BPlayer.addActionListener(this); BMovePrevious.addActionListener(this); BStop.addActionListener(this); select.addActionListener(this); BSet.addActionListener(this); timeInformation.setEnabled(false); /* * Реализация прогресс-бара /* */ timeSlider.setMajorTickSpacing(1); // Вызов этого метода для установки интервала между основными метками.传入ое число означает расстояние между основными метками, измеряемое по значению. timeSlider.setPaintTicks(true); // Для того чтобы рисовать основные метки, setPaintTicks должен быть установлен в true timeSlider.addChangeListener(new ChangeListener() { // Создание нового ChangeListener для добавления к ползунку. public void stateChanged(ChangeEvent arg0) { if (player != null && ispressing == 1) { newtime = (int)((JSlider)arg0.getSource()).getValue(); timeInformation.setText("Текущее время:"+newtime/60+":"+newtime%60+" || "+" Общее время: "+countSecond/60+":"+countSecond%60); ischanging = 1; } } }); timeSlider.addMouseListener(new MouseAdapter(){ public void mousePressed(MouseEvent arg0) { ispressing = 1; //当鼠标对游标进行点击时 } public void mouseReleased(MouseEvent arg0) { ispressing = 0; //当鼠标不对游标进行点击时 } }); timeInformation.setText("当前时间:00:00 || 总时间:00:00"); timeInformation.setBackground(new Color(255,255,255)); p3.add(timeInformation,BorderLayout.NORTH); p3.add(timeSlider,BorderLayout.SOUTH); j.add(pp); j.add(p5); j.add(p); j.add(p1); j.add(p6); j.setVisible(true); // j.setResizable(false); } /* /* 主函数 */ /* */ public static void main(String[] args) throws IOException, InterruptedException { //InterruptedException:当线程在活动之前或活动期间处于正在等待、休眠或占用状态且该线程被中断时,抛出该异常 MyMusicPlayer play=new MyMusicPlayer(); Thread timeRun = new Thread(play); timeRun.start(); } @Override public void actionPerformed(ActionEvent e) { String cmd = e.getActionCommand(); //通过获取字符串来判断是播放还是暂停, String box = (String)select.getSelectedItem(); //Определение порядка воспроизведения if(e.getSource()==BAdd) { if (player == null) { if (fileChooser.showOpenDialog(j) == MusicFileChooser.APPROVE_OPTION) { this.MusicName = fileChooser.getSelectedFile(); File cd = fileChooser.getCurrentDirectory(); // Получение текущей папки if (cd != this.currentDirectory|| this.currentDirectory == null) { FileFilter[] fileFilters = fileChooser.getChoosableFileFilters(); // FileFilter - это абстрактный класс, который JFileChooser использует для фильтрации набора файлов, отображаемых пользователю File files[] = cd.listFiles(); // cd.listFiles() возвращает массив абстрактных путей, представляющих файлы в этом каталоге. this.MusicNames = new ArrayList<File>(); for (File file : files) { // В каждом цикле переменная file получает объект файла из массива, и затем в теле цикла с этим объектом выполняются операции, такие как: //for(int i=0;i<files.length;i++){ file = files[i];……} filename = file.getName().toLowerCase(); // Получение всех названий музыки for (FileFilter filter : fileFilters) { if (!file.isDirectory() && filter.accept(file)) { this.MusicNames.add(file); list.add(filename); filename=e.getActionCommand(); } } } } index = MusicNames.indexOf(MusicName); // Определение индекса песни count = MusicNames.size(); PlayFile(); } } else { player.start(); } } if(cmd.equals("Пауза")){ BPlayer.setText("Воспроизведение"); player.stop(); } if(cmd.equals("Воспроизведение")){ BPlayer.setText("Пауза"); player.start(); } if(e.getSource()==BStop){ // остановка if (player != null) { player.stop(); timeInformation.setText("Текущее время:00:00 || Общее время:00:00"); timeSlider.setValue(0); player.setMediaTime(new Time(0)); // Установить время в ноль } } if(e.getSource()==BMoveNext){ // Следующая песня if (player != null) { if("Постепенное воспроизведение".equals(box)){ nextMusic(); } if("Случайное воспроизведение".equals(box)){ int index = (int) rand.nextInt(this.MusicNames.size()) + 1; if (this.MusicNames != null && !this.MusicNames.isEmpty()) { if ( ++index == this.MusicNames.size()) { index=(int) rand.nextInt(this.MusicNames.size())+1; } player.stop(); // Если нажата кнопка "Предыдущая песня", остановить текущую песню и воспроизвести предыдущую try { player = Manager.createRealizedPlayer(MusicNames.get(index).toURI().toURL()); player.prefetch(); player.setMediaTime(new Time(0.0));// 从某个时间段开始播放 player.addControllerListener(this); l.setText("Воспроизводится: " + this.MusicNames.get(index).toString()); list.select(index); player.start(); flag=1; } catch (NoPlayerException | CannotRealizeException | IOException e1) { e1.printStackTrace(); } } } } } if(e.getSource()==BMovePrevious){ // Предыдущая песня if (player != null) { if("Постепенное воспроизведение".equals(box)){ PreviousMusic(); } if("Случайное воспроизведение".equals(box)){ int index = (int) rand.nextInt(this.MusicNames.size()) + 1; if (this.MusicNames != null && !this.MusicNames.isEmpty()) { if ( index--==(int) rand.nextInt(this.MusicNames.size())+1) { index = this.MusicNames.size() - 1; } player.stop(); // Если нажата кнопка "Предыдущая песня", остановить текущую песню и воспроизвести предыдущую try { player = Manager.createRealizedPlayer(MusicNames.get(index).toURI().toURL()); player.prefetch(); player.setMediaTime(new Time(0.0));// 从某个时间段开始播放 player.addControllerListener(this); l.setText("Воспроизводится: " + this.MusicNames.get(index).toString()); list.select(index); player.start(); flag=1; } catch (NoPlayerException | CannotRealizeException | IOException e1) { e1.printStackTrace(); } } } } } if(e.getSource()==BDelect){ // Удаление песни index = list.getSelectedIndex(); list.remove(index); MusicNames.remove(this.index); } if(e.getSource()==BDelectTable){ // Очистка списка list.removeAll(); MusicNames.removeAll(MusicNames); player.stop(); player = null; } // Реализация воспроизведения при двойном клике на список list.addMouseListener(new MouseAdapter() { public void mouseClicked(MouseEvent e) { // Обработка при двойном клике if (e.getClickCount() == 2) { if(player!=null){ player.stop(); } // Воспроизведение выбранного файла index = list.getSelectedIndex(); PlayFile(); } } }); } // Потому что реализована интерфейс "ControllerListener", этот метод предназначен для обработки событий, переданных медиаплеером; public void controllerUpdate(ControllerEvent e) { String box = (String)select.getSelectedItem(); //Определение порядка воспроизведения if (e instanceof EndOfMediaEvent) { player.setMediaTime(new Time(0)); if ("Повторение одной песни".equals(box)) { player.start(); } if("Постепенное воспроизведение".equals(box)){ nextMusic(); } if("Случайное воспроизведение".equals(box)){ if (this.MusicNames != null && !this.MusicNames.isEmpty()) { int index = (int) rand.nextInt(this.MusicNames.size()) + 1; try { player = Manager.createRealizedPlayer(MusicNames.get(index).toURI().toURL()); player.prefetch(); player.setMediaTime(new Time(0.0));// 从某个时间段开始播放 player.addControllerListener(this); l.setText("Воспроизводится: " + this.MusicNames.get(index).toString()); list.select(index); player.start(); flag=1; } catch (NoPlayerException | CannotRealizeException | IOException e1) { e1.printStackTrace(); } } } } } */ * Получение названия MP3 песни * * @Путь к MP3 файлу * @Название песни */ public String getMusicName(String str) { int i; for (i = str.length() - 1; i > 0; i--) { if (str.charAt(i) == '\\') break; } str = str.substring(i + 1, str.length() - 4); return str; } */ * Функция воспроизведения следующей песни */ public void nextMusic() { } */ * Функция воспроизведения предыдущей песни */ public void PreviousMusic() { } */ * Основная функция воспроизведения MP3 файла */ public void PlayFile() { try { player = Manager.createRealizedPlayer(MusicNames.get(index).toURI().toURL()); player.prefetch(); player.setMediaTime(new Time(0.0));// 从某个时间段开始播放 player.addControllerListener(this); l.setFont(new Font("宋体",0,20)); l.setText("正在播放:"+this.MusicNames.get(index).toString()); //显示正在播放的歌曲 list.select(index); player.start(); Mythread11 tt=new Mythread11(); tt.start(); } catch (Exception e1) { //当选到一首音乐不能播放时,对其进行处理 dealError(); return; } this.setFrame(); } public void setFrame() { countSecond = (int)player.getDuration().getSeconds(); timeSlider.setMaximum(countSecond); timeSlider.setValue(0); newtime = 0; } private void dealError() { // TODO Автоматически сгенерированный метод MusicNames.remove(index); if( --count == index ) index = 0; if( count == 0) player = null; else PlayFile(); } */ * MP3文件筛选内部类 */ class MusicFileChooser extends JFileChooser { } */ * MP3文件筛选辅助内部类 * */ class MyFileFilter extends FileFilter { //FileFilter 是一个抽象类,JFileChooser 使用它过滤显示给用户的文件集合 String[] suffarr; String decription; public MyFileFilter() { super(); } public MyFileFilter(String[] suffarr, String description) { super(); this.suffarr = suffarr; this.description = description; } public boolean accept(File f) { for (String s : suffarr) { if (f.getName().toUpperCase().endsWith(s)) { return true; } } return f.isDirectory(); } public String getDescription() { return this.description; } } */ * Чтение и отображение полосы времени */ public void run() { while(true) { sleep(); if(player != null) { if(ispressing == 0) { if(ischanging == 1) { newtime = timeSlider.getValue(); player.setMediaTime(new Time(((long) newtime) * 1000000000)); ischanging = 0; } else { newtime = (int) player.getMediaTime().getSeconds(); timeSlider.setValue(newtime); timeInformation.setText("Текущее время: " + newtime / 60 + ":" + newtime % 60 + " || "+ "Общее время: "+ countSecond / 60 + ":" + countSecond % 60); } } } } } // Реализация потока для текста песни class Mythread11 extends Thread { public void run() { // TODO Автоматически сгенерированный метод try{ LRC lrc = ReadLRC.readLRC("Traveling Light.lrc"); Lyrics ls = ParseLRC.parseLRC(lrc); playTest(ls); catch(Exception e){ } } } static void playTest(Lyrics ls) throws InterruptedException {}}} tp.setFont(new Font("宋体", 1, 20)); tp.setForeground(Color.BLUE); StyledDocument doc = tp.getStyledDocument(); SimpleAttributeSet center = new SimpleAttributeSet(); StyleConstants.setAlignment(center, StyleConstants.ALIGN_CENTER); // Показ lyrics doc.setParagraphAttributes(0, doc.getLength(), center, false); tp.setText("Исполнитель: " + ls.getAr()); tp.setText("Альбом: " + ls.getAl()); tp.setText("Песня: " + ls.getTi()); tp.setText("Создание текста песни: " + ls.getBy()); for (Lyric l : ls.getLyrics()) { tp.setText(l.getTxt()); Thread.sleep(l.getTimeSize()); } } }
V. Общий результат тестирования
Вот так
Для получения дополнительной информации о плеере нажмите на «Функции java плеера» для изучения.
Вот и все, что есть в этой статье. Надеюсь, это поможет вам в изучении, и希望大家 поддержат руководства по криканию.