java mp3播放器

java mp3播放器

最近没有系统学习的计划,看了开源的YOYOPlayer(一个相当强大的播放器软件,基于java编写),心里痒痒,比较肤浅的学习下javasound。
javasound是比较小巧的底层api,引用网上的一幅 javasound体系结构图:


javasound实现: 目前使用最多的是 jdk中javax.sound组件 (包括javax.sound.sampled 和 javax.sound.midi包) 和 开源的 Tritonus(http://www.tritonus.org/)组件
SPI:是Service Provider Interface(服务提供接口),它的作用是以插件的形式提供音频扩展模块。比如,javax.sound组件中,只支持au,mid,wav等少许音频格式,其中不包括mp3。要想支持mp3格式,那么就需要相应的解码器和SPI。所幸的是,已经有相应的开源包。
javazoom(http://www.javazoom.net)下的jlayer,是mp3格式的解码包。
javazoom下的mp3spi就是spi。
只要添加了相应的开源组建包,可以在不修改任何一行代码的情况下,支持其他音频格式。这就是spi的魅力。

简单介绍了javasound的体系结构,下面就介绍一个简易的mp3播放器的实现(所谓简易,就是没有界面,除了能播放mp3等文件外,就啥都不能干了 :) )

几个步骤:
1)得到音频流:
AudioSystem.getAudioInputStream(input)
2)得到音频格式:
audioInputStream.getFormat()
3)初始化数据行信息
数据行信息包括(受数据行支持的音频格式;其内部缓冲区的最小和最大大小 )
DataLine.Info info = new DataLine.Info(SourceDataLine.class, decodedFormat);
4)从混频器获得源数据行
SourceDataLine 接口提供将音频数据写入数据行的缓冲区中的方法。播放或混合音频的应用程序应该以足够快的速度将数据写入源数据行,以防缓冲区下溢(排空),下溢可能导致单击时音频数据中出现可感知的间断
SourceDataLine line = (SourceDataLine) AudioSystem.getLine(info);
5)将音频数据写入源数据行中
line.start();
int  readLenth  =   0 ;
while  (readLenth  !=   - 1 ) {
    readLenth 
=  decodedAudioStream.read(AUDIO_BUFER,  0 , AUDIO_BUFER.length);
   
if  (readLenth  !=   - 1 ) {
        line.write(AUDIO_BUFER, 
0 , readLenth);
    }
}
line.drain();
line.stop();
line.close();


下面提供完整的简易mp3播放器代码:
其中 AudioPlayer仅仅是一个接口。
/**
 * <pre>
 * MP3播放器实现
 * 线程不安全,没有必要多个线程去启动播放器
 * </pre>
 * 
 * 
@author  Lee Jones
 
*/
public   class  Mp3Player  implements  AudioPlayer {

    
private   static   final  Log    log          =  LogFactory.getLog(Mp3Player. class );

    
private   static   final   byte [] AUDIO_BUFER  =   new   byte [ 4096 ];

    
private  AudioInputStream    audioStream;

    
private  AudioFormat         decodedFormat;
    
private  AudioInputStream    decodedAudioStream;

    @Override
    
public   void  play(InputStream input) {
        
if  (input  ==   null ) {
            log.warn(
" input stream is null " );
            
return ;
        }
        
try  {
            init(input);
            play();
        } 
catch  (Exception e) {
            log.error(
" play error: " , e);
        }
    }

    @Override
    
public   void  play(File file) {
        
if  (file  ==   null ) {
            log.warn(
" audio file is null " );
            
return ;
        }
        
try  {
            play(
new  FileInputStream(file));
        } 
catch  (FileNotFoundException e) {
            log.error(
" file to inputStream error: " , e);
        }
    }

    @Override
    
public   void  play(URL url) {
        
if  (url  ==   null ) {
            log.warn(
" url is null " );
            
return ;
        }
        
try  {
            play(url.openStream());
        } 
catch  (IOException e) {
            log.error(
" url open inputStream error: " , e);
        }
    }

    
/**
     * init
     * 
     * 
@param  input
     * 
@throws  UnsupportedAudioFileException
     * 
@throws  IOException
     
*/
    
protected   void  init(InputStream input)  throws  UnsupportedAudioFileException, IOException {
        initAudioStream(input);
        initDecodedFormat();
        initDecodedAudioStream();
    }

    
/**
     * init audio input stream
     * 
     * 
@param  input:audio input stream
     * 
@throws  IOException
     * 
@throws  UnsupportedAudioFileException
     
*/
    
protected   void  initAudioStream(InputStream input)  throws  UnsupportedAudioFileException, IOException {
        audioStream 
=  AudioSystem.getAudioInputStream(input);
    }

    
/**
     * init decoded format
     * 
     * 
@throws  UnsupportedAudioFileException
     * 
@throws  IOException
     
*/
    
protected   void  initDecodedFormat()  throws  UnsupportedAudioFileException, IOException {
        AudioFormat baseFormat 
=  audioStream.getFormat();
        decodedFormat 
=   new  AudioFormat(AudioFormat.Encoding.PCM_SIGNED, baseFormat.getSampleRate(),  16 ,
                                        baseFormat.getChannels(), baseFormat.getChannels() 
*   2 ,
                                        baseFormat.getSampleRate(), 
false );
    }

    
/**
     * init decoded audio stream
     
*/
    
protected   void  initDecodedAudioStream() {
        decodedAudioStream 
=  AudioSystem.getAudioInputStream(decodedFormat, audioStream);
    }

    
/**
     * get source data line
     * 
     * 
@param  input audio input stream
     * 
@return
     * 
@throws  UnsupportedAudioFileException
     * 
@throws  IOException
     * 
@throws  LineUnavailableException
     
*/
    
protected  SourceDataLine getSourceDataLine()  throws  UnsupportedAudioFileException, IOException,
                                                LineUnavailableException {
        DataLine.Info info 
=   new  DataLine.Info(SourceDataLine. class , decodedFormat);
        SourceDataLine line 
=  (SourceDataLine) AudioSystem.getLine(info);
        line.open(decodedFormat);
        
return  line;
    }

    
/**
     * play audio
     * 
     * 
@throws  UnsupportedAudioFileException
     * 
@throws  IOException
     * 
@throws  LineUnavailableException
     
*/
    
protected   void  play()  throws  UnsupportedAudioFileException, IOException, LineUnavailableException {
        SourceDataLine line 
=  getSourceDataLine();
        line.start();
        
int  readLenth  =   0 ;
        
while  (readLenth  !=   - 1 ) {
            readLenth 
=  decodedAudioStream.read(AUDIO_BUFER,  0 , AUDIO_BUFER.length);
            
if  (readLenth  !=   - 1 ) {
                line.write(AUDIO_BUFER, 
0 , readLenth);
            }
        }
        line.drain();
        line.stop();
        line.close();
        decodedAudioStream.close();
        audioStream.close();
    }
}


最后附上简易播放器:
easy mp3 player

启动方式:linux用户使用./mp3player.sh,windows用户使用mp3player.bat启动(需要说明的是,必须设置好JAVA_HOME和PATH,并且使用jdk5以上版本。因为启动脚本中的指定classpath的方法需要jdk5版本以上才支持。如果是jdk1.4下的用户,请修改启动脚本)
lib目录:是简易播放器的lib包支持
log目录:记录log,如果有错误等情况,可查看log。
conf目录:因为没有图形界面,所以需要把播放的mp3文件路径手工写入。支持两种形式,一个是本地mp3文件,另一个是网络mp3资源,分别写入到local.txt和net.txt文件中。
比如
local.txt
/home/jones/data/music/misc/xin_nian_hao.mp3
/home/jones/data/music/misc/guo_ge.mp3
net.txt
http://lubai.com.cn/CGI-BIN/shuanxing.mp3
http://lubai.com.cn/CGI-BIN/shuanxing.mp3

因多媒体方向非自己的工作方向,所以了解的相当肤浅。有兴趣的朋友请多多指教。

你可能感兴趣的:(java mp3播放器)