1. 如何用java做一个音乐播放器
首先下载播放mp3的包,比如mp3spi1.9.4.jar。在工程中添加这个包。
播放器演示代码如下
packagecom.test.audio;
importjava.io.File;
importjava.awt.BorderLayout;
importjava.awt.FileDialog;
importjava.awt.Frame;
importjava.awt.GridLayout;
importjava.awt.Label;
importjava.awt.List;
importjava.awt.Menu;
importjava.awt.MenuBar;
importjava.awt.MenuItem;
importjava.awt.MenuShortcut;
importjava.awt.Panel;
importjava.awt.event.ActionEvent;
importjava.awt.event.ActionListener;
importjava.awt.event.KeyEvent;
importjava.awt.event.MouseAdapter;
importjava.awt.event.MouseEvent;
importjava.awt.event.WindowAdapter;
importjava.awt.event.WindowEvent;
importjavax.sound.sampled.AudioFormat;
importjavax.sound.sampled.AudioInputStream;
importjavax.sound.sampled.AudioSystem;
importjavax.sound.sampled.DataLine;
importjavax.sound.sampled.SourceDataLine;
{
/**
*
*/
=-2605658046194599045L;
booleanisStop=true;//控制播放线程
booleanhasStop=true;//播放线程状态
液悔Stringfilepath;//播放文件目录
Stringfilename;//播放文件名称
;//文件流
AudioFormataudioFormat;//文件格式
SourceDataLinesourceDataLine;//输出设备
Listlist;//文件列表
Labellabelfilepath;//播放目录显示标签
Labellabelfilename;//播放文件显示标签
publicMusicPlayer(){
闹磨正//设置窗体属性
setLayout(newBorderLayout());
setTitle("MP3MusicPlayer");
setSize(350,370);
//建立菜单栏
MenuBarmenubar=newMenuBar();
Menumenufile=newMenu("File");
MenuItemmenuopen=newMenuItem("Open",newMenuShortcut(KeyEvent.VK_O));
menufile.add(menuopen);
游宴menufile.addActionListener(newActionListener(){
publicvoidactionPerformed(ActionEvente){
open();
}
});
menubar.add(menufile);
setMenuBar(menubar);
//文件列表
list=newList(10);
list.addMouseListener(newMouseAdapter(){
publicvoidmouseClicked(MouseEvente){
//双击时处理
if(e.getClickCount()==2){
//播放选中的文件
filename=list.getSelectedItem();
play();
}
}
});
add(list,"Center");
//信息显示
Panelpanel=newPanel(newGridLayout(2,1));
labelfilepath=newLabel("Dir:");
labelfilename=newLabel("File:");
panel.add(labelfilepath);
panel.add(labelfilename);
add(panel,"North");
//注册窗体关闭事件
addWindowListener(newWindowAdapter(){
publicvoidwindowClosing(WindowEvente){
System.exit(0);
}
});
setVisible(true);
}
//打开
privatevoidopen(){
FileDialogdialog=newFileDialog(this,"Open",0);
dialog.setVisible(true);
filepath=dialog.getDirectory();
if(filepath!=null){
labelfilepath.setText("Dir:"+filepath);
//显示文件列表
list.removeAll();
Filefiledir=newFile(filepath);
File[]filelist=filedir.listFiles();
for(Filefile:filelist){
Stringfilename=file.getName().toLowerCase();
if(filename.endsWith(".mp3")||filename.endsWith(".wav")){
list.add(filename);
}
}
}
}
//播放
privatevoidplay(){
try{
isStop=true;//停止播放线程
//等待播放线程停止
System.out.print("Start:"+filename);
while(!hasStop){
System.out.print(".");
try{
Thread.sleep(10);
}catch(Exceptione){
}
}
System.out.println("");
Filefile=newFile(filepath+filename);
labelfilename.setText("Playing:"+filename);
//取得文件输入流
audioInputStream=AudioSystem.getAudioInputStream(file);
audioFormat=audioInputStream.getFormat();
//转换mp3文件编码
if(audioFormat.getEncoding()!=AudioFormat.Encoding.PCM_SIGNED){
audioFormat=newAudioFormat(AudioFormat.Encoding.PCM_SIGNED,
audioFormat.getSampleRate(),16,audioFormat
.getChannels(),audioFormat.getChannels()*2,
audioFormat.getSampleRate(),false);
audioInputStream=AudioSystem.getAudioInputStream(audioFormat,
audioInputStream);
}
//打开输出设备
DataLine.InfodataLineInfo=newDataLine.Info(
SourceDataLine.class,audioFormat,
AudioSystem.NOT_SPECIFIED);
sourceDataLine=(SourceDataLine)AudioSystem.getLine(dataLineInfo);
sourceDataLine.open(audioFormat);
sourceDataLine.start();
//创建独立线程进行播放
isStop=false;
ThreadplayThread=newThread(newPlayThread());
playThread.start();
}catch(Exceptione){
e.printStackTrace();
}
}
classPlayThreadextendsThread{
bytetempBuffer[]=newbyte[320];
publicvoidrun(){
try{
intcnt;
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(Exceptione){
e.printStackTrace();
System.exit(0);
}
}
}
publicstaticvoidmain(Stringargs[]){
newMusicPlayer();
}
}
2. 所有音乐格式中,哪种格式音质最好求解答
PCM,是音频文件里,级别最高的,是所有数字音频(模拟的不包括在内)的始祖,保真度最高,体积十分庞大,常见的格式有pcm和cda,多用来录制唱片如cd文件。CD不是一种格式,它是一种标准,详细请见SONY(索尼)公布的官方红皮书,CD是利用特殊的方式,直接刻录音轨保存在CD-ROM盘片(专用的CD盘,当然也可以是普通的CD-ROM盘,这是后来修改的)上的,无法作为一种格式来保存。
所以,应当说,PCM的格式是音质最好最高,但是它的体积极其巨大,所以一般使用WAV作为原始文件来保存音频文件,质量也是相当高,损失几乎相当的少,但体积也比较大,这是微软开发并图鉴的一种格式,适合Windows操作系统,在现在最新的MAC系统上也可以使用。扩展名:.wav
在MAC系统上专用的原始音频格式,是AIFF,扩展名为Aiff,这是由苹果公司独立开发的,在Mac上十分常见。也就是说在Mac上这是最好的格式(PCM除外)。
在Unix和Java平台下(多指SUN的平台),相应的格式是AU,扩展名就是au。它是目前在Unix和java下的标准音频格式。
以上格式均为原始文件格式,一般都是体积巨大,为了便于在计算机上流传,人们开发了压缩格式,压缩分为有损压缩和无损压缩,显然有损压缩的压缩率更大,但它需要解决的问题就是如何解决音质的问题。一般通常的做法,就是牺牲人耳辨别率比较若以及人耳无法收听的部分,但是人的耳朵区别很大,所以很难照顾到所有的人。在唱见的格式中,比较不错的格式有flac(无损,扩展名flac)、Monkey's Audio(无损,扩展名ape)、DTS(多声道,主要用与DVD,扩展名dtc/wav)、AC3(杜比推出,环绕多声道,现场感逼真,扩展名ac3)、AAC(收费,音质好,扩展名Aac或mp4)、WMV(这也是种视频格式,wma和asf的升级版,质量相当高,扩展名wmv),另外还有MusePack(扩展名mpc,完全免费)以及MP3Pro(扩展名mp3)也相当不错,这些格式音质都相当高,甚至对于对声音颇有要求的用户来说表现也不差。
3. java音频处理问题
为什么audioFormat.getChannels(), 一次后还要再一个audioFormat.getChannels()*2
每声道每帧字节数2字节,再加上双声道所以用声道数(2)*字节数(2) = 每帧的总字节数
看来你的audioFormat不是从AudioInputStream中产生的啊?刚才回答你的问题我还没注意。原来audioFormat也可以new出来的啊,嘿嘿。
4. 如何将pcm文件转换为mp3
PCM(Pulse Code Molation----脉码调制录音)。所谓PCM录音就是将声音等模拟信号变成符号化的脉冲列,再予以记录。PCM信号是由[1]、[0]等符号构成的数字信号。与模拟信号比,它不易受传送系统的杂波及失真的影响。动态范围宽,可得到音质相当好的影响效果。
可以使用Goldwave,只需要用GoldWave打开要转换的PCM文件,然后在“文件File”选择另存为save as...,保存类型,选(*mp3),“参数Attributes”里选择要保存的码率即可。如下图所示:
5. java实现 mp3格式转换wav
/*
*实现录音机的功能
*/
packagecom.liuyun.MyRecord1;
importjava.awt.*;
importjavax.swing.*;
importjava.awt.event.*;
importjava.io.*;
importjavax.sound.sampled.*;
importjava.lang.*;
{
//定义录音格式
AudioFormataf=null;
//定义目标数据行,可以从中读取音频数据,该TargetDataLine接口提供从目标数据行的缓冲区读取所捕获数据的方法。
TargetDataLinetd=null;
//定义源数据行,源数据行是可以写入数据的数据行。它充当其混频器的源。应用程序将音频字节写入源数据行,这样可处理字节缓冲并将它们传递给混频器。
SourceDataLinesd=null;
//定义字节数组输入输出流
ByteArrayInputStreams=null;
ByteArrayOutputStreambaos=null;
//定义音频输入流
AudioInputStreamais=null;
//定义停止录音的标志,来控制录音线程的运行
Booleanstopflag=false;
//记录开始录音的时间
longstartPlay;
//定义所需要的组件
JPaneljp1,jp2,jp3;
JLabeljl1=null;
JButtoncaptureBtn,stopBtn,playBtn,saveBtn;
publicstaticvoidmain(String[]args){
//创造一个实例
MyRecordmr=newMyRecord();
}
//构造函数
publicMyRecord()
{
//组件初始化
jp1=newJPanel();
jp2=newJPanel();
jp3=newJPanel();
//定义字体
FontmyFont=newFont("华文新魏",Font.BOLD,30);
jl1=newJLabel("录音机功能的实现");
jl1.setFont(myFont);
jp1.add(jl1);
captureBtn=newJButton("开始录音");
//对开始录音按钮进行注册监听
captureBtn.addActionListener(this);
captureBtn.setActionCommand("captureBtn");
//对停止录音进行注册监听
stopBtn=newJButton("停止录音");
stopBtn.addActionListener(this);
stopBtn.setActionCommand("stopBtn");
//对播放录音进行注册监听
playBtn=newJButton("播放录音");
playBtn.addActionListener(this);
playBtn.setActionCommand("playBtn");
//对保存录音进行注册监听
saveBtn=newJButton("保存录音");
saveBtn.addActionListener(this);
saveBtn.setActionCommand("saveBtn");
this.add(jp1,BorderLayout.NORTH);
this.add(jp2,BorderLayout.CENTER);
this.add(jp3,BorderLayout.SOUTH);
jp3.setLayout(null);
jp3.setLayout(newGridLayout(1,4,10,10));
jp3.add(captureBtn);
jp3.add(stopBtn);
jp3.add(playBtn);
jp3.add(saveBtn);
//设置按钮的属性
captureBtn.setEnabled(true);
stopBtn.setEnabled(false);
playBtn.setEnabled(false);
saveBtn.setEnabled(false);
//设置窗口的属性
this.setSize(400,300);
this.setTitle("录音机");
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setLocationRelativeTo(null);
this.setVisible(true);
}
publicvoidactionPerformed(ActionEvente){
if(e.getActionCommand().equals("captureBtn"))
{
//点击开始录音按钮后的动作
//停止按钮可以启动
captureBtn.setEnabled(false);
stopBtn.setEnabled(true);
playBtn.setEnabled(false);
saveBtn.setEnabled(false);
//调用录音的方法
capture();
//记录开始录音的时间
startPlay=System.currentTimeMillis();
}elseif(e.getActionCommand().equals("stopBtn")){
//点击停止录音按钮的动作
captureBtn.setEnabled(true);
stopBtn.setEnabled(false);
playBtn.setEnabled(true);
saveBtn.setEnabled(true);
//调用停止录音的方法
stop();
//记录停止录音的时间
longstopPlay=System.currentTimeMillis();
//输出录音的时间
System.out.println("Playcontinues"+(stopPlay-startPlay));
}elseif(e.getActionCommand().equals("playBtn"))
{
//调用播放录音的方法
play();
}elseif(e.getActionCommand().equals("saveBtn"))
{
//调用保存录音的方法
save();
}
}
//开始录音
publicvoidcapture()
{
try{
//af为AudioFormat也就是音频格式
af=getAudioFormat();
DataLine.Infoinfo=newDataLine.Info(TargetDataLine.class,af);
td=(TargetDataLine)(AudioSystem.getLine(info));
//打开具有指定格式的行,这样可使行获得所有所需的系统资源并变得可操作。
td.open(af);
//允许某一数据行执行数据I/O
td.start();
//创建播放录音的线程
Recordrecord=newRecord();
Threadt1=newThread(record);
t1.start();
}catch(LineUnavailableExceptionex){
ex.printStackTrace();
return;
}
}
//停止录音
publicvoidstop()
{
stopflag=true;
}
//播放录音
publicvoidplay()
{
//将baos中的数据转换为字节数据
byteaudioData[]=baos.toByteArray();
//转换为输入流
s=newByteArrayInputStream(audioData);
af=getAudioFormat();
ais=newAudioInputStream(s,af,audioData.length/af.getFrameSize());
try{
DataLine.InfodataLineInfo=newDataLine.Info(SourceDataLine.class,af);
sd=(SourceDataLine)AudioSystem.getLine(dataLineInfo);
sd.open(af);
sd.start();
//创建播放进程
Playpy=newPlay();
Threadt2=newThread(py);
t2.start();
}catch(Exceptione){
e.printStackTrace();
}finally{
try{
//关闭流
if(ais!=null)
{
ais.close();
}
if(s!=null)
{
s.close();
}
if(baos!=null)
{
baos.close();
}
}catch(Exceptione){
e.printStackTrace();
}
}
}
//保存录音
publicvoidsave()
{
//取得录音输入流
af=getAudioFormat();
byteaudioData[]=baos.toByteArray();
s=newByteArrayInputStream(audioData);
ais=newAudioInputStream(s,af,audioData.length/af.getFrameSize());
//定义最终保存的文件名
Filefile=null;
//写入文件
try{
//以当前的时间命名录音的名字
//将录音的文件存放到F盘下语音文件夹下
FilefilePath=newFile("F:/语音文件");
if(!filePath.exists())
{//如果文件不存在,则创建该目录
filePath.mkdir();
}
longtime=System.currentTimeMillis();
file=newFile(filePath+"/"+time+".wav");
AudioSystem.write(ais,AudioFileFormat.Type.WAVE,file);
//将录音产生的wav文件转换为容量较小的mp3格式
//定义产生后文件名
StringtarFileName=time+".mp3";
Runtimerun=null;
try{
run=Runtime.getRuntime();
longstart=System.currentTimeMillis();
//调用解码器来将wav文件转换为mp3文件
<strong><spanstyle="color:#ff0000;">Processp=run.exec(filePath+"/"+"lame-b16"+filePath+"/"+file.getName()+""+filePath+"/"+tarFileName);//16为码率,可自行修改
</span></strong>//释放进程
p.getOutputStream().close();
p.getInputStream().close();
p.getErrorStream().close();
p.waitFor();
longend=System.currentTimeMillis();
System.out.println("convertneedcosts:"+(end-start)+"ms");
//删除无用的wav文件
if(file.exists())
{
file.delete();
}
}catch(Exceptione){
e.printStackTrace();
}finally{
//最后都要执行的语句
//run调用lame解码器最后释放内存
run.freeMemory();
}
}catch(Exceptione){
e.printStackTrace();
}finally{
//关闭流
try{
if(s!=null)
{
s.close();
}
if(ais!=null)
{
ais.close();
}
}catch(Exceptione){
e.printStackTrace();
}
}
}
//设置AudioFormat的参数
()
{
//下面注释部分是另外一种音频格式,两者都可以
AudioFormat.Encodingencoding=AudioFormat.Encoding.
PCM_SIGNED;
floatrate=8000f;
intsampleSize=16;
StringsignedString="signed";
booleanbigEndian=true;
intchannels=1;
returnnewAudioFormat(encoding,rate,sampleSize,channels,
(sampleSize/8)*channels,rate,bigEndian);
////采样率是每秒播放和录制的样本数
//floatsampleRate=16000.0F;
////采样率8000,11025,16000,22050,44100
////sampleSizeInBits表示每个具有此格式的声音样本中的位数
//intsampleSizeInBits=16;
////8,16
//intchannels=1;
////单声道为1,立体声为2
//booleansigned=true;
////true,false
//booleanbigEndian=true;
////true,false
//returnnewAudioFormat(sampleRate,sampleSizeInBits,channels,signed,bigEndian);
}
//录音类,因为要用到MyRecord类中的变量,所以将其做成内部类
classRecordimplementsRunnable
{
//定义存放录音的字节数组,作为缓冲区
bytebts[]=newbyte[10000];
//将字节数组包装到流里,最终存入到baos中
//重写run函数
publicvoidrun(){
baos=newByteArrayOutputStream();
try{
stopflag=false;
while(stopflag!=true)
{
//当停止录音没按下时,该线程一直执行
//从数据行的输入缓冲区读取音频数据。
//要读取bts.length长度的字节,cnt是实际读取的字节数
intcnt=td.read(bts,0,bts.length);
if(cnt>0)
{
baos.write(bts,0,cnt);
}
}
}catch(Exceptione){
e.printStackTrace();
}finally{
try{
//关闭打开的字节数组流
if(baos!=null)
{
baos.close();
}
}catch(IOExceptione){
e.printStackTrace();
}finally{
td.drain();
td.close();
}
}
}
}
//播放类,同样也做成内部类
classPlayimplementsRunnable
{
//播放baos中的数据即可
publicvoidrun(){
bytebts[]=newbyte[10000];
try{
intcnt;
//读取数据到缓存数据
while((cnt=ais.read(bts,0,bts.length))!=-1)
{
if(cnt>0)
{
//写入缓存数据
//将音频数据写入到混频器
sd.write(bts,0,cnt);
}
}
}catch(Exceptione){
e.printStackTrace();
}finally{
sd.drain();
sd.close();
}
}
}
}