前言
之前的版本,有位朋友说无法实现暂停播放,还有一些其他无伤大雅的bug,所以我就查了一波资料,研究了一下后,进行的一波优化。
这个版本的播放器,实现了:上一首、下一首、暂停/播放、目录浏览等功能。
注意
需要注意的是几个jar包的变化,旧的jar包会导致一些异常,例如:Resetting to invalid mark等,所以做了有一些改变,当然jl1.0.1不要应该也行:
代码
手写是MyPlayer类里面的变化,为了方便我直接写成了MyPlayer2;
其中不再使用jl中player的play方法,而是改用JavaSound中的方法类实现。
代码结构:
MyPlayer2实现
package com.lyrics.musicplayer.service;
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;
public class MyPlayer2 extends Thread{
Object lock = new Object();
AudioInputStream stream;
SourceDataLine sourceDataLine;
public static boolean paused = false;
private String music;
public MyPlayer2(String music) {
this.music = music;
}
public void setPaused(boolean paused) {
MyPlayer2.paused = paused;
}
public void run() {
try {
play(music);
} catch (IOException | UnsupportedAudioFileException | LineUnavailableException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void play(String music) throws IOException, UnsupportedAudioFileException, LineUnavailableException {
stream = AudioSystem.getAudioInputStream(new File(music));
AudioFormat format = stream.getFormat();
if (format.getEncoding() != AudioFormat.Encoding.PCM_SIGNED) {
format = new AudioFormat(AudioFormat.Encoding.PCM_SIGNED, format.getSampleRate(), 16, format.getChannels(),
format.getChannels() * 2, format.getSampleRate(), false);
stream = AudioSystem.getAudioInputStream(format, stream);
}
DataLine.Info info = new DataLine.Info(SourceDataLine.class, stream.getFormat());
sourceDataLine = (SourceDataLine) AudioSystem.getLine(info);
sourceDataLine.open(stream.getFormat(), sourceDataLine.getBufferSize());
sourceDataLine.start();
int numRead = 0;
byte[] buf = new byte[sourceDataLine.getBufferSize()];
while ((numRead = stream.read(buf, 0, buf.length)) >= 0) {
while(paused) {
if(sourceDataLine.isRunning()) {
sourceDataLine.stop();
}
else {
sourceDataLine.start();
}
}
int offset = 0;
while (offset < numRead) {
offset += sourceDataLine.write(buf, offset, numRead - offset);
}
System.out.println(sourceDataLine.getFramePosition() + " " + sourceDataLine.getMicrosecondPosition());
}
sourceDataLine.drain();
sourceDataLine.stop();
sourceDataLine.close();
stream.close();
}
public void close() {
if(sourceDataLine != null) {
sourceDataLine.close();
}
if(stream != null) {
try {
stream.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public void on() {
setPaused(false);
}
public void pause() {
setPaused(true);
}
}
Design实现
package com.lyrics.musicplayer.ui;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.DirectoryDialog;
import java.util.Vector;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Text;
import com.lyrics.musicplayer.service.MyPlayer2;
import com.lyrics.musicplayer.util.FileList;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.widgets.List;
import org.eclipse.swt.events.MouseAdapter;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.widgets.Label;
public class Design {
protected Shell shell;
private Text textBrowser;
String selecteddir=null;
String programdir=null;
String music;
int index = 0;
MyPlayer2 myplayer;
/**
* Open the window.
*/
public void open() {
Display display = Display.getDefault();
createContents();
shell.open();
shell.layout();
while (!shell.isDisposed()) {
if (!display.readAndDispatch()) {
display.sleep();
}
}
myplayer.close();
}
/**
* Create contents of the window.
* @wbp.parser.entryPoint
*/
protected void createContents() {
shell = new Shell();
shell.setSize(358, 335);
shell.setText("Music Player");
Button btnPlayer = new Button(shell, SWT.NONE);
btnPlayer.setText("播放");
btnPlayer.setBounds(138, 45, 80, 27);
List listDisplay = new List(shell, SWT.BORDER | SWT.H_SCROLL | SWT.V_SCROLL);
listDisplay.setBounds(10, 138, 322, 149);
Button btnPrevMusic = new Button(shell, SWT.NONE);
btnPrevMusic.setBounds(22, 45, 80, 27);
btnPrevMusic.setText("上一首");
Button btnNextMusic = new Button(shell, SWT.NONE);
btnNextMusic.setText("下一首");
btnNextMusic.setBounds(252, 45, 80, 27);
textBrowser = new Text(shell, SWT.BORDER);
textBrowser.setBounds(10, 93, 229, 23);
Button btnBrowser = new Button(shell, SWT.NONE);
btnBrowser.setBounds(252, 91, 80, 27);
btnBrowser.setText("浏览");
Label label = new Label(shell, SWT.NONE);
label.setBounds(22, 10, 61, 17);
label.setText("正在播放:");
Label lblName = new Label(shell, SWT.NONE);
lblName.setBounds(86, 10, 246, 17);
// 播放暂停键
btnPlayer.addMouseListener(new MouseAdapter() {
@Override
public void mouseDown(MouseEvent e) {
if(!MyPlayer2.paused) {
btnPlayer.setText("播放");
myplayer.pause();
return;
}
if(MyPlayer2.paused){
//thread.run();
btnPlayer.setText("暂停");
myplayer.on();
}
}
});
// 双击列表播放
listDisplay.addMouseListener(new MouseAdapter() {
@Override
public void mouseDoubleClick(MouseEvent e) {
index = listDisplay.getSelectionIndex();
lblName.setText(listDisplay.getItem(index));
btnPlayer.setText("暂停");
music=selecteddir + "/" +listDisplay.getItem(index);
myplayer = new MyPlayer2( music);
myplayer.on();
myplayer.start();
}
}
);
// 文件夹选择
btnBrowser.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
//新建文件夹(目录)对话框
DirectoryDialog folderdlg=new DirectoryDialog(shell);
//设置文件对话框的标题
folderdlg.setText("文件选择");
//设置初始路径
folderdlg.setFilterPath("SystemDrive");
//设置对话框提示文本信息
folderdlg.setMessage("请选择相应的文件夹");
//打开文件对话框,返回选中文件夹目录
selecteddir=folderdlg.open();
if(selecteddir==null){
return ;
}
else{
textBrowser.setText(selecteddir);
programdir=System.getProperty("user.dir");
try {
FileList fileList= new FileList();
Vector<String> list=new Vector<String> ();
fileList.getAllFileName(selecteddir, list);
for(int i=0;i<list.size();i++)
{
listDisplay.add(list.elementAt(i));
System.out.println(list.elementAt(i));
}
} catch (Exception e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
}
});
// 上一首
btnPrevMusic.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
index = index-1;
listDisplay.setSelection(index);
btnPlayer.setText("暂停");
lblName.setText(listDisplay.getItem(index));
myplayer.close();
music= selecteddir + "/" + listDisplay.getItem(index);
myplayer = new MyPlayer2( music);
myplayer.on();
myplayer.start();
}
});
// 下一首
btnNextMusic.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
index = index+1;
listDisplay.setSelection(index);
btnPlayer.setText("暂停");
lblName.setText(listDisplay.getItem(index));
myplayer.close();
music = selecteddir + "/" + listDisplay.getItem(index);
myplayer = new MyPlayer2( music);
myplayer.on();
myplayer.start();
}
});
}
}
FileList实现
package com.lyrics.musicplayer.util;
import java.io.File;
import java.util.Vector;
public class FileList {
public void getAllFileName(String path,Vector<String> list) {
File file = new File(path);
File[] tempList = file.listFiles();
for (int i = 0; i < tempList.length; i++) {
if (tempList[i].isFile()) {
list.add(tempList[i].getName());
}
if (tempList[i].isDirectory()) {
getAllFileName(tempList[i].getAbsolutePath(),list);
}
}
return;
}
}
启动:MusicPlayer实现
package com.lyrics.musicplayer;
import com.lyrics.musicplayer.ui.Design;
/**
* @Author: lyrics
* @ClassName: MusicPlayer
* @Date: 2020/05/17
* @Copyright: lyrics
*/
public class MusicPlayer {
public static void main(String[] args) {
try {
Design window = new Design();
window.open();
} catch (Exception e) {
e.printStackTrace();
}
}
}
运行结果
写在最后
针对之前有位朋友提到的问题我都一一实现或者解决了,但是这个代码毕竟只是随意之作,肯定有很多不足的地方,如果接下来我不是很忙的话,我会继续更新优化,当然也有可能是有生之年系列。