java mp3播放器 ×××面

1、服务器端:html

最近没有系统学习的计划,看了开源的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)获得音频流:html5

AudioSystem.getAudioInputStream(input)java

2)获得音频格式:
linux

audioInputStream.getFormat()windows

3)初始化数据行信息
数据行信息包括(受数据行支持的音频格式;其内部缓冲区的最小和最大大小 )
api

DataLine.Info info = new DataLine.Info(SourceDataLine.class, decodedFormat);安全

4)从混频器得到源数据行
SourceDataLine 接口提供将音频数据写入数据行的缓冲区中的方法。播放或混合音频的应用程序应该以足够快的速度将数据写入源数据行,以防缓冲区下溢(排空),下溢可能致使单击时音频数据中出现可感知的间断
服务器

SourceDataLine line = (SourceDataLine) AudioSystem.getLine(info);网络

5)将音频数据写入源数据行中ide

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();
    }
}


本身写个main方法便可测试  啦啦啦......

public static void main(String[] args) {

Mp3Player mp3Player=new Mp3Player();

String sourcUrl="C:"+File.separator+"879_mp3.mp3";

        File file=new File(sourcUrl); 

        

        mp3Player.play(file);

}


最后附上简易播放器:见附件


启动方式: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


2、客户端:

http://translate.google.cn/translate_tts?ie=UTF-8&q=这是要发音的文本&tl=zh-CN&total=1&idx=0&textlen=2&client=t&prev=input

这个URL直接返回你要说的话的MP3文件。播放就能够了。

html5:支持 <audio autoplay='true'><source src='<%=path%>/MP3/1.mp3' /></audio>

相关文章
相关标签/搜索