<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    stone2083

    java mp3播放器

    最近沒有系統(tǒng)學(xué)習(xí)的計劃,看了開源的YOYOPlayer(一個相當(dāng)強大的播放器軟件,基于java編寫),心里癢癢,比較膚淺的學(xué)習(xí)下javasound。
    javasound是比較小巧的底層api,引用網(wǎng)上的一幅 javasound體系結(jié)構(gòu)圖:


    javasound實現(xiàn): 目前使用最多的是 jdk中javax.sound組件 (包括javax.sound.sampled 和 javax.sound.midi包) 和 開源的 Tritonus(http://www.tritonus.org/)組件
    SPI:是Service Provider Interface(服務(wù)提供接口),它的作用是以插件的形式提供音頻擴展模塊。比如,javax.sound組件中,只支持au,mid,wav等少許音頻格式,其中不包括mp3。要想支持mp3格式,那么就需要相應(yīng)的解碼器和SPI。所幸的是,已經(jīng)有相應(yīng)的開源包。
    javazoom(http://www.javazoom.net)下的jlayer,是mp3格式的解碼包。
    javazoom下的mp3spi就是spi。
    只要添加了相應(yīng)的開源組建包,可以在不修改任何一行代碼的情況下,支持其他音頻格式。這就是spi的魅力。

    簡單介紹了javasound的體系結(jié)構(gòu),下面就介紹一個簡易的mp3播放器的實現(xiàn)(所謂簡易,就是沒有界面,除了能播放mp3等文件外,就啥都不能干了 :) )

    幾個步驟:
    1)得到音頻流:
    AudioSystem.getAudioInputStream(input)
    2)得到音頻格式:
    audioInputStream.getFormat()
    3)初始化數(shù)據(jù)行信息
    數(shù)據(jù)行信息包括(受數(shù)據(jù)行支持的音頻格式;其內(nèi)部緩沖區(qū)的最小和最大大小 )
    DataLine.Info info = new DataLine.Info(SourceDataLine.class, decodedFormat);
    4)從混頻器獲得源數(shù)據(jù)行
    SourceDataLine 接口提供將音頻數(shù)據(jù)寫入數(shù)據(jù)行的緩沖區(qū)中的方法。播放或混合音頻的應(yīng)用程序應(yīng)該以足夠快的速度將數(shù)據(jù)寫入源數(shù)據(jù)行,以防緩沖區(qū)下溢(排空),下溢可能導(dǎo)致單擊時音頻數(shù)據(jù)中出現(xiàn)可感知的間斷
    SourceDataLine line = (SourceDataLine) AudioSystem.getLine(info);
    5)將音頻數(shù)據(jù)寫入源數(shù)據(jù)行中
    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播放器實現(xiàn)
     * 線程不安全,沒有必要多個線程去啟動播放器
     * </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啟動(需要說明的是,必須設(shè)置好JAVA_HOME和PATH,并且使用jdk5以上版本。因為啟動腳本中的指定classpath的方法需要jdk5版本以上才支持。如果是jdk1.4下的用戶,請修改啟動腳本)
    lib目錄:是簡易播放器的lib包支持
    log目錄:記錄log,如果有錯誤等情況,可查看log。
    conf目錄:因為沒有圖形界面,所以需要把播放的mp3文件路徑手工寫入。支持兩種形式,一個是本地mp3文件,另一個是網(wǎng)絡(luò)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

    因多媒體方向非自己的工作方向,所以了解的相當(dāng)膚淺。有興趣的朋友請多多指教。

    posted on 2008-02-17 21:19 stone2083 閱讀(5862) 評論(6)  編輯  收藏 所屬分類: java

    Feedback

    # re: java mp3播放器 2009-04-28 17:32 wscool

    謝謝啊,雖然簡單但對初學(xué)者是非常有幫助的……  回復(fù)  更多評論   

    # re: java mp3播放器 2011-05-15 20:45 zechou

    必須加支持MP3的SPI?  回復(fù)  更多評論   

    # re: java mp3播放器 2011-05-16 12:55 stone2083

    @zechou
    是的。需要第三方服務(wù)提供。  回復(fù)  更多評論   

    # re: java mp3播放器 2011-11-12 21:49 fangtest

    你的這個給力 謝謝樓主  回復(fù)  更多評論   

    # re: java mp3播放器 2014-12-15 19:08 lousongtao

    樓主能不能研究下, 如何調(diào)整播放MP3的速度, 我搞了一天也沒搞懂  回復(fù)  更多評論   

    # re: java mp3播放器 2014-12-16 13:17 stone2083

    @lousongtao
    音頻文件是將模擬信號采樣轉(zhuǎn)成的數(shù)字信號. 把每一秒鐘所采樣的數(shù)目稱為采樣頻率或采率. 也就是說, 聲音的速度是一定的,取決于模擬信號.
    比特率 = 每秒采樣數(shù)量 (hz) × 位深(bit) × 聲道數(shù)量
    位速是指在一個數(shù)據(jù)流中每秒鐘能通過的信息量

    從理論上說, 增加位速, 就可以實現(xiàn)快速播放的效果.
    至于api上怎么使用, 我也不知道, 你可以順著這個思路,再看看.
      回復(fù)  更多評論   

    主站蜘蛛池模板: 国产又大又黑又粗免费视频| 曰韩亚洲av人人夜夜澡人人爽| 在免费jizzjizz在线播| 亚洲精品视频免费在线观看| 成人免费视频试看120秒| 特级aa**毛片免费观看| 亚洲av无码国产精品夜色午夜| 91在线视频免费91| 一级午夜免费视频| 91亚洲自偷在线观看国产馆| 亚洲国产综合无码一区二区二三区| 国产成人免费ā片在线观看老同学 | 国产亚洲人成网站在线观看不卡| 在线视频精品免费| 日韩毛片免费一二三| 亚洲欧洲精品国产区| 亚洲日韩人妻第一页| 免费AA片少妇人AA片直播| 国产成人精品免费视频大全| 激情综合亚洲色婷婷五月| 亚洲精品无码成人AAA片| 日本特黄特黄刺激大片免费| 久操视频免费观看| 春意影院午夜爽爽爽免费| 亚洲第一成人在线| 亚洲不卡av不卡一区二区| 免费国产人做人视频在线观看| 最近2019中文字幕免费直播| selaoban在线视频免费精品| 亚洲无码一区二区三区| 久久精品国产亚洲AV香蕉| 狠狠综合久久综合88亚洲| 国产片免费福利片永久| av大片在线无码免费| 久久精品电影免费动漫| 一级特黄aaa大片免费看| 亚洲a∨无码一区二区| 中文字幕亚洲综合久久综合| 亚洲综合在线成人一区| 亚洲av色福利天堂| 亚洲精品无码乱码成人|