2010-07-20 58 views
99

我有以下代碼:從資產目錄播放音頻文件

AssetFileDescriptor afd = getAssets().openFd("AudioFile.mp3"); 
player = new MediaPlayer(); 
player.setDataSource(afd.getFileDescriptor()); 
player.prepare(); 
player.start(); 

的問題是,當我運行這段代碼,它開始播放的所有音頻文件資源目錄中,按字母順序排列,而不是隻播放我要求的音頻文件。我究竟做錯了什麼?有沒有更好的方法來播放資產目錄中的音頻文件?

後續問題: 在資產目錄中保留音頻文件並將其保存在res/raw目錄中是否有區別?除了他們在資產目錄中沒有獲得ID的事實。如果我將音頻文件移動到res/raw文件夾,那麼我在重用MediaPlayer時遇到問題,因爲setDataSource()沒有id參數。我無法找到處理這類問題的良好指導方針。如果你有在資產 目錄只有一個文件

回答

205
player.setDataSource(afd.getFileDescriptor(),afd.getStartOffset(),afd.getLength()); 

你的版本會工作。資產目錄內容實際上不是磁盤上的「真實文件」 。他們都是一個接一個地放在一起。所以,如果你做 未指定從哪裏開始,如何讀取的字節數,玩家將 閱讀到最後(也就是,將繼續播放的所有文件的資產 目錄)

+1

它的工作。謝謝。但我認爲我的版本也應該有效。 – 2010-08-05 16:17:02

+54

如果資產目錄中只有一個文件,則您的版本可以正常工作。 資產目錄內容實際上不是磁盤上的「真實文件」。他們都是一個接一個地放在一起。所以,如果你沒有指定從哪裏開始讀取多少字節,播放器將讀取到最後(即將繼續播放資產目錄中的所有文件) – 2010-08-09 04:46:47

+0

非常好的答案! – Redax 2011-03-29 15:37:09

57

此功能將正常工作:)

// MediaPlayer m; /*assume, somewhere in the global scope...*/ 

public void playBeep() { 
    try { 
     if (m.isPlaying()) { 
      m.stop(); 
      m.release(); 
      m = new MediaPlayer(); 
     } 

     AssetFileDescriptor descriptor = getAssets().openFd("beepbeep.mp3"); 
     m.setDataSource(descriptor.getFileDescriptor(), descriptor.getStartOffset(), descriptor.getLength()); 
     descriptor.close(); 

     m.prepare(); 
     m.setVolume(1f, 1f); 
     m.setLooping(true); 
     m.start(); 
    } catch (Exception e) { 
     e.printStackTrace(); 
    } 
} 
+2

什麼是m?你正在初始化m = new MediaPlayer();之前和之前使用過它? – Umar 2015-01-29 07:33:52

+0

嗨@Umar,我有全局變量MediaPlayer m = null;那麼我已經在playBeep()函數中分配了 – 2015-01-29 09:22:42

+0

請記住'MediaPlayer m'必須是'static'或具有另一個**引用**。如果你在一個沒有任何引用的函數中有'm','GC'將會「收集」它 – 2015-03-20 20:40:56