摘要:本文使用java基础技术实现了一个可播放mid、wav格式音乐的简易音乐播放器,带UI
//此程序实现mid.wav格式音频文件的播放
//暂时只实现了单曲播放功能<播放面板里的play
//选项>其它功能会后继添加
//Version 1.0
// @author Zha_yongchun
// Email:1729465178@qq.com
package com.music;
import java.awt.event.*;
import java.io.File;
import java.io.IOException;
import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.DataLine;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.SourceDataLine;
import javax.sound.sampled.UnsupportedAudioFileException;
import javax.swing.*;
import java.awt.*;
public class playAudio extends JFrame implements ActionListener {
static String filePath =null;//播放文件路径
JButton btPause, btExit, btPlay, btLoop, btStop;
JPanel panel;
JMenuBar mb;
JMenu menu;
JMenuItem menuMi1,menuMi2;
JTextArea textarea;
public static void main(String[] args) {
playAudio pa = new playAudio();
}
// 构造方法
public playAudio() {
// 定义按钮
btPause = new JButton("Pause");
btPause.setFont(new Font("Chaparral Pro Light",Font.BOLD,15));
btExit = new JButton("EXIT");
btExit.setFont(new Font("Chaparral Pro Light",Font.BOLD,15));
btPlay = new JButton("PLAY");
btPlay.setFont(new Font("Chaparral Pro Light",Font.BOLD,15));
btLoop = new JButton("LOOP");
btLoop.setFont(new Font("Chaparral Pro Light",Font.BOLD,15));
btStop = new JButton("STOP");
btStop.setFont(new Font("Chaparral Pro Light",Font.BOLD,15));
//定义文本域
textarea=new JTextArea("Import music fileDialog...");
textarea.setEditable(false);
textarea.setFont(new Font("Chaparral Pro Light",Font.HANGING_BASELINE,20));
//定义菜单栏
mb=new JMenuBar();
menu=new JMenu("File");
menu.setMnemonic('F');
menu.setFont(new Font("Chaparral Pro Light",Font.HANGING_BASELINE,15));
menuMi1=new JMenuItem("Open");
menuMi1.setMnemonic('O');
menuMi1.setFont(new Font("Chaparral Pro Light",Font.HANGING_BASELINE,15));
menuMi2=new JMenuItem("Exit");
menuMi2.setMnemonic('E');
menuMi2.setFont(new Font("Chaparral Pro Light",Font.HANGING_BASELINE,15));
//定义面板
panel = new JPanel();
// 添加面板组件
panel.add(btPlay);
panel.add(btLoop);
panel.add(btPause);
panel.add(btStop);
panel.add(btExit);
//添加菜单组件
mb.add(menu);
menu.add(menuMi1);
menu.add(menuMi2);
// 添加事件监听
btPause.addActionListener(this);
btPause.setActionCommand("pause");
btExit.addActionListener(this);
btExit.setActionCommand("exit");
btPlay.addActionListener(this);
btPlay.setActionCommand("play");
btLoop.addActionListener(this);
btLoop.setActionCommand("loop");
btStop.addActionListener(this);
btStop.setActionCommand("stop");
menuMi1.addActionListener(this);
menuMi1.setActionCommand("open");
menuMi2.addActionListener(this);
menuMi2.setActionCommand("exit");
// 流式布局
//this.setLayout(new GridLayout(2, 1,5,0));
this.setJMenuBar(mb);
this.add(textarea);
this.add(panel,BorderLayout.SOUTH);
// 显示窗口
this.setIconImage(new ImageIcon("image/music.JPG").getImage());
this.setTitle("MusicPlayer");// 设置用户界面
this.setSize(400, 150);// 设置窗口大小,数字代表像素
this.setLocation(300, 260);// 设置窗体位置
this.setResizable(false);// 设置窗体大小是否可调整
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);// 关闭进程
this.setVisible(true);// true 显示,false不显示
}
// 事件监听
public void actionPerformed(ActionEvent e) {
String text="";//文件路径载体
Audio player = new Audio(filePath);//初始化播放器
// 打开
if (e.getActionCommand().equals("open")) {
// 打开选择文件选择歌曲
FileDialog fd = new FileDialog(this,"Chooes music", FileDialog.LOAD);
fd.setVisible(true); // 显示选择框
filePath = fd.getDirectory() +fd.getFile(); // 文件名称=获取此文件对话框的目录+文件名
if(filePath!=null)
System.out.println(text="filePath is: "+filePath);
else
System.out.println(text="Couldn't open file");
}
// 退出
else if (e.getActionCommand().equals("exit")) {
player.interrupt();
System.out.println(text="Exit program!");
System.exit(0);
}
// 播放
else if (e.getActionCommand().equals("play")) {
if(filePath!=null){
player.start();
System.out.println(text="Play music: "+filePath);
}else
System.out.println(text="There is not any file!");
}
// 循环
else if (e.getActionCommand().equals("loop")) {
if(filePath!=null){
while(!player.isAlive()){
try{
player.start();
System.out.println(text="Loop playing"+filePath);
}catch(Exception e1){
System.err.println(text="Loop Error");
}
}
}else
System.out.println(text="There is not any file!");
}
// 停止
else if (e.getActionCommand().equals("stop")) {
player.interrupt();
System.out.println(text="Stop playing!");
}
//暂停
else if(e.getActionCommand().equals("pause")){
player.interrupt();
System.out.println(text="Pause playing!");
}
this.textarea.setText(text);
}
}
//Audio类实现声音流播放 1.定义音频文件的变量,
//变量需要: 一个用于存储音频文件对象名字的String对象 filename;
//2.构造函数,初始化filename
//3.线程运行函数重写
class Audio extends Thread {
// 1.定义音频文件的变量,变量需要:一个用于存储音频文件对象名字的String对象 filename
private String filename;
// 2.构造函数,初始化filename
public Audio(String filename) {
this.filename = filename;
}
// 3.线程运行函数重写
public void run() {
// 1.定义一个文件对象引用,指向名为filename那个文件
File sourceFile = new File(filename);
// 定义一个AudioInputStream用于接收输入的音频数据
AudioInputStream audioInputStream = null;
// 使用AudioSystem来获取音频的音频输入流
try {
audioInputStream = AudioSystem.getAudioInputStream(sourceFile);
} catch (UnsupportedAudioFileException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
// 4,用AudioFormat来获取AudioInputStream的格式
AudioFormat format = audioInputStream.getFormat();
// 5.源数据行SoureDataLine是可以写入数据的数据行
SourceDataLine auline = null;
// 获取受数据行支持的音频格式DataLine.info
DataLine.Info info = new DataLine.Info(SourceDataLine.class, format);
// 获得与指定info类型相匹配的行
try {
auline = (SourceDataLine) AudioSystem.getLine(info);
// 打开具有指定格式的行,这样可使行获得所有所需系统资源并变得可操作
auline.open();
} catch (LineUnavailableException e) {
e.printStackTrace();
}
// 允许某一个数据行执行数据i/o
auline.start();
// 写出数据
int nBytesRead = 0;
byte[] abData = new byte[1024];
// 从音频流读取指定的最大数量的数据字节,并将其放入给定的字节数组中。
try {
while (nBytesRead != -1) {
nBytesRead = audioInputStream.read(abData, 0, abData.length);
// 通过此源数据行将数据写入混频器
if (nBytesRead >= 0)
auline.write(abData, 0, nBytesRead);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
auline.drain();
auline.close();
}
}
}