2012-03-27 299 views
39

我有一個遊戲,當一個關卡完成時,聲音播放。一切工作正常開始,但重複一個級別10或20次logcat突然報告: 「MediaPlayer錯誤(-19,0)」和/或「MediaPlayer開始在狀態0調用」並且不再發出聲音。重複播放後Mediaplayer錯誤(-19,0)

我原本是以mp3格式發出的所有聲音,但在閱讀完ogg後可能會更可靠,我將它們全部轉換爲ogg,但錯誤也是一樣的。

任何想法如何解決這個問題?

回答

55

我覺得你不釋放您使用播放聲音的mediaplayers .. 你需要釋放()的媒體播放器,否則資源不釋放,你很快就會出來的內存(因爲你下次再分配它們)。所以,我認爲你可以播放兩次甚至三次...但沒有多少次沒有釋放資源

13

MediaPlayer是不是一個好的選擇當你播放小音效,因爲用戶可以點擊多個按鈕非常很快,你將不得不爲所有它們同步創建一個MP對象。這就是爲什麼你每次點擊都聽不到聲音的原因。去SoundPool類,它可以讓你將更小的聲音加載到內存中,你可以隨時播放它們,而不會在媒體播放器中感受到任何延遲。 http://developer.android.com/reference/android/media/SoundPool.html這裏是一個不錯的教程:http://www.anddev.org/using_soundpool_instead_of_mediaplayer-t3115.html

1

我嘗試刪除模擬器和新的創建模擬器來刪除(-19,0)媒體播放器的錯誤。

58

我得到了同樣的問題,我解決它通過添加以下代碼來釋放玩家:

mp1 = MediaPlayer.create(sound.this, R.raw.pan1); 
mp1.start(); 
mp1.setOnCompletionListener(new OnCompletionListener() { 
    public void onCompletion(MediaPlayer mp) { 
     mp.release(); 

    }; 
}); 
+3

完美適用於自動釋放玩家完成後,感謝很多 – Pelanes 2013-05-24 07:37:01

+0

它的作品像魅力。 – 2017-09-11 04:59:09

1

我解決了這兩個錯誤(-19,0)和(-38,0)每次在播放和釋放之前創建MediaPlayer的新對象。

前:

void play(int resourceID) { 
    if (getActivity() != null) { 

     //Using the same object - Problem persists 
     player = MediaPlayer.create(getActivity(), resourceID); 
     player.setAudioStreamType(AudioManager.STREAM_MUSIC); 

     player.setOnCompletionListener(new MediaPlayer.OnCompletionListener() { 
      @Override 
      public void onCompletion(MediaPlayer mp) { 
       player.release(); 
      } 
     }); 

     player.setOnPreparedListener(new MediaPlayer.OnPreparedListener() { 
      @Override 
      public void onPrepared(MediaPlayer mp) { 
       mp.start(); 
      } 
     }); 

    } 
} 

後:

void play(int resourceID) { 

    if (getActivity() != null) { 

     //Problem Solved 
     //Creating new MediaPlayer object every time and releasing it after completion 
     final MediaPlayer player = MediaPlayer.create(getActivity(), resourceID); 
     player.setAudioStreamType(AudioManager.STREAM_MUSIC); 

     player.setOnCompletionListener(new MediaPlayer.OnCompletionListener() { 
      @Override 
      public void onCompletion(MediaPlayer mp) { 
       player.release(); 
      } 
     }); 

     player.setOnPreparedListener(new MediaPlayer.OnPreparedListener() { 
      @Override 
      public void onPrepared(MediaPlayer mp) { 
       mp.start(); 
      } 
     }); 

    } 
} 
1

這是一個很古老的問題,但這個第一次在我的搜索結果,以便其他人同樣的問題可能會歸到這最終頁面。

與其他人所說的不同,事實上,您可以在不使用大量內存的情況下使用MediaPlayer進行小聲播放。我會從我的音板應用程序中加入一點修改過的snippit,以向您展示我所獲得的信息。

private MediaPlayer mp; 

protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.your_layout); 

    mp = new MediaPlayer(); 

} 

private void playSound(int soundID){ 
    mp.reset(); 
    AssetFileDescriptor sound = getResources().openRawResourceFd(soundID); 
    try { 
     mp.setDataSource(sound.getFileDescriptor(),sound.getStartOffset(),sound.getLength()); 
     mp.prepare(); 
    } catch (IOException e) { 
     e.printStackTrace(); 
    } 
    mp.start(); 


} 

與我設置它的樣子,你創建你重用你每次播放聲音,使您不會佔用太多空間MediaPlayer對象上。

您調用.reset()而不是.release(),因爲.release()僅用於處理對象時使用,但要保留MediaPlayer對象。

您可以使用assetfiledescriptor來爲您的mediaplayer設置一個新的聲音文件,而不是設置一個新的對象到您的mediaplayer地址,因爲這樣您在方法內創建的新對象不能正確處理,並且您最終會遇到與您所描述的相同的錯誤。

這只是使用MediaPlayer的衆多方法之一,但我個人認爲如果您僅將其用於小型聲音應用程序,效率最高。唯一的問題是,它對於你能完成的事情有比較嚴格的限制,但如果你確實將它用於小型聲音應用程序,這應該不是什麼大問題。