使用Java實現MP3音樂播放器

使用Java實現MP3音樂播放器
JavaSound是一個小巧的低層API,支持數字音頻和MIDI數據的記錄/回放。在JDK 1.3.0 以前,JavaSound是一個標準的Java擴展API,但從Java 21.3.0版開始,JavaSound就被包含到JDK之中。因爲Java有着跨平臺(操做系統、硬件平臺)的特色,基於JavaSound的音頻處理程序(包括本文的程序)可以在任何實現了Java 1.3+的系統上運行,無需加裝任何支持軟件。
使用JavaSound API,能夠實現各類基於聲音的應用,例如聲音錄製、音樂播放、網絡電話、音樂編輯等。JavaSound API又以各類解碼和合成器SPI(服務提供者接口, Service Provider Interface)爲基礎,實現各類音樂格式的解碼與轉碼。
在處理輸入音頻時,對於來自各類音頻輸入端口的信號,例如麥克風、CD播放器、磁帶播放器等,能夠在它們到達TargetDataLine以前,利用混頻器控制輸入混頻,最後在程序中經過TargetDataLine得到數字化的音頻輸入流。
相似地,在處理輸出音頻時,混頻器用來對一系列來自SourceDataLine的數據進行混頻處理,經處理後的信號可輸出到各類輸出端口,例如揚聲器、耳機等。SourceDataLine是一個可寫入音頻信號數字流的設備,例如,咱們能夠從一個WAV文件讀取內容寫入到SourceDataLine,而後再經過揚聲器輸出。
其流程圖如圖17-7所示。
音頻輸入輸入流程圖
17-7  音頻輸入輸入流程圖
爲了支持 mp3 的播放,咱們必須添加 mp3 SPI 支持庫。首先須要下載 mp3 的支持庫:
     官方網站: http://www.javazoom.net/
     下載頁面: http://www.javazoom.net/mp3spi/sources.html
     下載地址: http://www.javazoom.net/mp3spi/sources/mp3spi 1.9.4 .zip
     下載文件: mp3spi 1.9.4 .zip
mp3spi 1.9.4 .zip 中的三個 Jar 文件 jl1.0.jar mp3spi1.9.4.jar tritonus_share.jar 添加到當前項目中便可。
下面咱們來實現一個 MP3 音樂播放器,實現的功能是:單擊【文件】 à 【打開】彈出文件選擇對話框,將選擇目錄的全部 mp3 wav 文件加入到播放列表中,雙擊播放列表中的音樂文件實現音樂的播放和切換。
要實現該程序,首先須要提供了一個主程序窗口,該窗口提供了各類界面組件和操做事件的控制,幷包含一個音樂播放的子線程,子線程由主線程控制。所以有兩個類:
     音樂播放器主程序 MusicPlayer.java
     播放線程 PlayThread.java
1)音樂播放器主程序MusicPlayer.java
package com.test.audio;
import java.io.File;
import java.awt.BorderLayout;
import java.awt.FileDialog;
import java.awt.Frame;
import java.awt.GridLayout;
import java.awt.Label;
import java.awt.List;
import java.awt.Menu;
import java.awt.MenuBar;
import java.awt.MenuItem;
import java.awt.MenuShortcut;
import java.awt.Panel;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.DataLine;
import javax.sound.sampled.SourceDataLine;
public class MusicPlayer extends Frame {
    boolean isStop = true;// 控制播放線程
    boolean hasStop = true;// 播放線程狀態
 
    String filepath;// 播放文件目錄
    String filename;// 播放文件名稱
    AudioInputStream audioInputStream;// 文件流
    AudioFormat audioFormat;// 文件格式
    SourceDataLine sourceDataLine;// 輸出設備
 
    List list;// 文件列表
    Label labelfilepath;// 播放目錄顯示標籤
    Label labelfilename;// 播放文件顯示標籤
 
    public MusicPlayer() {
        // 設置窗體屬性
        setLayout(new BorderLayout());
        setTitle("MP3 音樂播放器 ");
        setSize(350, 370);
 
        // 創建菜單欄
        MenuBar menubar = new MenuBar();
        Menu menufile = new Menu(" 文件 ");
        MenuItem menuopen = new MenuItem(" 打開 ", new MenuShortcut(KeyEvent.VK_O));
        menufile.add(menuopen);
        menufile.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                open();
            }
        });
        menubar.add(menufile);
        setMenuBar(menubar);
 
        // 文件列表
        list = new List(10);
        list.addMouseListener(new MouseAdapter() {
            public void mouseClicked(MouseEvent e) {
                // 雙擊時處理
                if (e.getClickCount() == 2) {
                    // 播放選中的文件
                    filename = list.getSelectedItem();
                    play();
                }
            }
        });
        add(list, "Center");
 
        // 信息顯示
        Panel panel = new Panel(new GridLayout(2, 1));
        labelfilepath = new Label(" 播放目錄: ");
        labelfilename = new Label(" 播放文件: ");
        panel.add(labelfilepath);
        panel.add(labelfilename);
        add(panel, "North");
 
        // 註冊窗體關閉事件
        addWindowListener(new WindowAdapter() {
            public void windowClosing(WindowEvent e) {
                System.exit(0);
            }
        });
        setVisible(true);
    }
 
    // 打開
    private void open() {
        FileDialog dialog = new FileDialog(this, "Open", 0);
        dialog.setVisible(true);
        filepath = dialog.getDirectory();
        if (filepath != null) {
            labelfilepath.setText(" 播放目錄: " + filepath);
 
            // 顯示文件列表
            list.removeAll();
            File filedir = new File(filepath);
            File[] filelist = filedir.listFiles();
            for (File file : filelist) {
                String filename = file.getName().toLowerCase();
                if (filename.endsWith(".mp3") || filename.endsWith(".wav")) {
                    list.add(filename);
                }
            }
        }
    }
 
    // 播放
    private void play() {
        try {
            isStop = true;// 中止播放線程
            // 等待播放線程中止
            System.out.print(" 開始播放: " + filename);
            while (!hasStop) {
                System.out.print(".");
                try {
                    Thread.sleep(10);
                } catch (Exception e) {
                }
            }
            System.out.println("");
            File file = new File(filepath + filename);
            labelfilename.setText(" 播放文件: " + filename);
 
            // 取得文件輸入流
            audioInputStream = AudioSystem.getAudioInputStream(file);
            audioFormat = audioInputStream.getFormat();
            // 轉換 mp3 文件編碼
            if (audioFormat.getEncoding() != AudioFormat.Encoding.PCM_SIGNED) {
                audioFormat = new AudioFormat(AudioFormat.Encoding.PCM_SIGNED,
                        audioFormat.getSampleRate(), 16, audioFormat
                                .getChannels(), audioFormat.getChannels() * 2,
                        audioFormat.getSampleRate(), false);
                audioInputStream = AudioSystem.getAudioInputStream(audioFormat,
                        audioInputStream);
            }
 
            // 打開輸出設備
            DataLine.Info dataLineInfo = new DataLine.Info(
                    SourceDataLine.class, audioFormat,
                    AudioSystem.NOT_SPECIFIED);
            sourceDataLine = (SourceDataLine) AudioSystem.getLine(dataLineInfo);
            sourceDataLine.open(audioFormat);
            sourceDataLine.start();
 
            // 建立獨立線程進行播放
            isStop = false;
            Thread playThread = new Thread(new PlayThread());
            playThread.start();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
 
    public static void main(String args[]) {
        new MusicPlayer();
    }
}
在該主程序中添加一個入口主函數 main() 來啓動該主程序便可。
2)播放線程PlayThread.java
該程序的代碼以下:
class PlayThread extends Thread {
    byte tempBuffer[] = new byte[320];
 
    public void run() {
        try {
            int cnt;
            hasStop = false;
            // 讀取數據到緩存數據
            while ((cnt = audioInputStream.read(tempBuffer, 0,
                    tempBuffer.length)) != -1) {
                if (isStop)
                    break;
                if (cnt > 0) {
                    // 寫入緩存數據
                    sourceDataLine.write(tempBuffer, 0, cnt);
                }
            }
            // Block 等待臨時數據被輸出爲空
            sourceDataLine.drain();
            sourceDataLine.close();
            hasStop = true;
        } catch (Exception e) {
            e.printStackTrace();
            System.exit(0);
        }
    }
}
3)運行MP3音樂播放器
完成以上代碼後,便可運行主程序 MusicPlayer ,就會顯示如圖 17-9 示的窗口:
 音樂播放器主窗口
17-9  音樂播放器主窗口
單擊【文件】 à 【打開】,就會彈出如圖 17-10 所示的打開窗口:
選擇文件
17-10  選擇文件
選中某一個音樂文件後,單擊【打開】按鈕,就會將該目錄下的全部mp3wav音樂文件添加到播放器的播放列表中,如圖17-11所示。
播放列表
 
17-11  播放列表
雙擊該播放列表中的音樂文件,就會開始播放音樂了。在音樂播放的過程當中,你還能夠隨時雙擊某一個文件來中止當前的音樂播放,並開始播放新的音樂文件。
 
相關文章
相關標籤/搜索