2014-01-21 7 views
8

In Android 4.x hat meine Audio-Loop-App 0,2 bis 0,5 Sekunden Lücken in den Sound-Loops.Android MediaPlayer-Schleife hat Lücken auch mit OGG-Format

Ich verwende den MediaPlayer, da meine Sounds ziemlich groß sein können (in manchen Fällen 2-3 MB) und mehrere Instanzen gleichzeitig ausführen können.

Ich habe das ziemlich viel recherchiert und ich sehe, dass es einen Fehler für Android 4.x gibt ... aber ich habe viele Arbeitsumgebungen ausprobiert, und ich kann nicht scheinen, dass irgendwelche von ihnen arbeiten.

  • alle wavs zu OGG mit Audacity konvertiert (Qualitätsstufe 2 bis 10, es spielte keine Rolle)
  • Versuchte setNextMediaPlayer()
  • Versuchte seekTo (0) auf Anschlag zu verwenden, und wiederholen Sie
  • Versuchte Soundpool, der seine eigenen Fehler hat

Hier ist ein Beispiel für den Code ich verwende:

public class SoundPlayer implements OnCompletionListener { 
    private MediaPlayer mp = null; 

    public void initPlayer() { 
     if(mp == null) { 
      mp = new MediaPlayer(); 
     } 
    } 

    public void prepare(Context context, int resource) { 
    initPlayer(); 
    try{ 
     mp.reset(); 
     Uri uri = Uri.parse("android.resource://com.myapp.app/"+resource); 
     mp.setDataSource(context,uri); 
     mp.prepare(); 
     isPrepared = true; 
     mp.setOnCompletionListener(this); 
    } catch(Exception e) { 
     e.printStackTrace(); 
    } 
    } 


.......... etc (Uses typical MediaPlayer methods such as stop(), start(), setLooping(true) 


} 

Ich benutze nichts besonderes, also frage ich mich, ob irgendjemand eine Arbeit für den Looping Bug auf Android kennt.

+0

Sind Sie der Lücke wird verursacht wird nicht durch eine einfache Verzögerung beim Laden und die erneute Erstellung Ihrer Mediaplayer-Objekt helfen? –

+0

Verwenden Sie einen Emulator, hatte ich ein ähnliches Problem auf einem Emulator, aber wenn ich es mit einem tatsächlichen Gerät probierte - die Verzögerung war weg. – Ogen

+0

Verwenden eines GS3-Geräts nicht Emulator. Es fühlt sich wie eine Verzögerung an, aber wie würde ich das verhindern? – user3217336

Antwort

1

Okay, alte Post, aber diese Lösung funktioniert. Das ist eine Art Hack. Es wird jemandem helfen, wenn jemand zu dieser Antwort kommt.

Ich verwende nur drei Media Player. mp1, mp2, mp3. mp1 wird gespielt, und ich setze mp2 auf seine setNextMediaPlayer. Wenn mp1 endet, setze ich mp3 auf mp2'ssetNextMediaPlayer. Wenn mp2 endet, setze ich mp1 auf mp3'ssetNextMediaPlayer. Im Folgenden ist der vollständige Code, der Pause, Stopp, Set vol. Erstellen Sie einfach ein Objekt BZMediaPlayer, starten Sie es, indem Sie uri oder Ressource-ID bereitstellen.

import android.content.Context; 
import android.media.MediaPlayer; 
import android.media.MediaPlayer.OnCompletionListener; 
import android.net.Uri; 
import android.util.Log; 

public class BZMediaPlayer { 


    private Context context; 
    private Uri uri; 
    private int resourceId; 

    // which file is getting played 
    public static final int URI_PLAYING = 1; 
    public static final int RESOURCE_PLAYING = 2; 
    private int filePlaying; 

    // states of the media player 
    public static final int STATE_PLAYING = 1; 
    public static final int STATE_PAUSED = 2; 
    public static final int STATE_STOP = 3; 

    // current state 
    private int state = STATE_STOP; 

    // current mediaPlayer which is playing 
    private int mediaPlayerIndex = -1; 

    // 3 media players 
    private MediaPlayer mp[] = new MediaPlayer[3]; 

    // current volume 
    private float vol; 


    public BZMediaPlayer(Context context) { 
     this.context = context; 
    } 

    /** 
    * plays the provided uri 
    * @param uri 
    */ 
    public void play(Uri uri) { 
     this.uri = uri; 
     // current playing file 
     filePlaying = URI_PLAYING; 
     // stop any playing session 
     stop(); 

     // initialize and set listener to three mediaplayers 
     for (int i = 0; i < mp.length; i++) { 
      mp[i] = MediaPlayer.create(context, uri); 
      mp[i].setOnCompletionListener(completionListener); 
     } 

     // set nextMediaPlayers 
     mp[0].setNextMediaPlayer(mp[1]); 
     mp[1].setNextMediaPlayer(mp[2]); 

     // start the first MediaPlayer 
     mp[0].start(); 
     // set mediaplayer inex 
     mediaPlayerIndex = 0; 
     // set state 
     state = STATE_PLAYING; 
    } 

    /** 
    * play file from resource 
    * @param resourceId 
    */ 
    public void play(int resourceId) { 
     this.resourceId = resourceId; 
     filePlaying = RESOURCE_PLAYING; 
     stop(); 
     for (int i = 0; i < mp.length; i++) { 
      mp[i] = MediaPlayer.create(context, resourceId); 
      mp[i].setOnCompletionListener(completionListener); 
     } 

     mp[0].setNextMediaPlayer(mp[1]); 
     mp[1].setNextMediaPlayer(mp[2]); 

     mp[0].start(); 
     mediaPlayerIndex = 0; 
     state = STATE_PLAYING; 
    } 

    /** 
    * play if the mediaplayer is pause 
    */ 
    public void play() { 
     if (state == STATE_PAUSED) { 
      mp[mediaPlayerIndex].start(); 
      Log.d("BZMediaPlayer", "playing"); 
      state = STATE_PLAYING; 
     } 
    } 

    /** 
    * pause current playing session 
    */ 
    public void pause() { 
     if (state == STATE_PLAYING) { 
      mp[mediaPlayerIndex].pause(); 
      Log.d("BZMediaPlayer", "pausing"); 
      state = STATE_PAUSED; 
     } 
    } 

    /** 
    * get current state 
    * @return 
    */ 
    public int getState() { 
     return state; 
    } 

    /** 
    * stop every mediaplayer 
    */ 
    public void stop() { 
     for(int i = 0 ; i < mp.length ; i++) { 
      if (mp[i] != null) { 
       mp[i].stop(); 

       if(mp[i].isPlaying()) { 
        mp[i].release(); 
       } 
      } 
     } 
     state = STATE_STOP; 
    } 

    /** 
    * set vol for every mediaplayer 
    * @param vol 
    */ 
    public void setVol(float vol) { 
     this.vol = vol; 
     for(int i = 0 ; i < mp.length ; i++) { 
      if (mp[i] != null && mp[i].isPlaying()) { 
       mp[i].setVolume(vol, vol); 
      } 
     } 
    } 

    /** 
    * internal listener which handles looping thing 
    */ 
    private MediaPlayer.OnCompletionListener completionListener = new OnCompletionListener() { 

     @Override 
     public void onCompletion(MediaPlayer curmp) { 
      int mpEnds = 0; 
      int mpPlaying = 0; 
      int mpNext = 0; 
      if(curmp == mp[0]) { 
       mpEnds = 0; 
       mpPlaying = 1; 
       mpNext = 2; 
      } 
      else if(curmp == mp[1]) { 
       mpEnds = 1; 
       mpPlaying = 2; 
       mpNext = 0; // corrected, else index out of range 
      } 
      else if(curmp == mp[2]) { 
       mpEnds = 2; 
       mpPlaying = 0; // corrected, else index out of range 
       mpNext = 1; // corrected, else index out of range 
      } 

      // as we have set mp2 mp1's next, so index will be 1 
      mediaPlayerIndex = mpPlaying; 
      Log.d("BZMediaPlayer", "Media Player " + mpEnds); 
      try { 
       // mp3 is already playing release it 
       if (mp[mpNext] != null) { 
        mp[mpNext].release(); 
       } 
       // if we are playing uri 
       if (filePlaying == URI_PLAYING) { 
        mp[mpNext] = MediaPlayer.create(context, uri); 
       } else { 
        mp[mpNext] = MediaPlayer.create(context, resourceId); 
       } 
       // at listener to mp3 
       mp[mpNext].setOnCompletionListener(this); 
       // set vol 
       mp[mpNext].setVolume(vol, vol); 
       // set nextMediaPlayer 
       mp[mpPlaying].setNextMediaPlayer(mp[mpNext]); 
       // set nextMediaPlayer vol 
       mp[mpPlaying].setVolume(vol, vol); 
      } catch (Exception e) { 
       e.printStackTrace(); 
      } 
     } 
    }; 

} 

Hoffe, dass es jemand

Edit: clean code

+0

Vielen Dank für diese Lösung! Allerdings gab es 2 Bugs, ich habe den Quellcode entsprechend bearbeitet. Funktioniert jetzt großartig! Danke nochmal! – Taifun

+0

Ich habe das in meinem Spiel implementiert (mit libGDX) und es funktioniert ein Vergnügen. Ich musste eine Menge Klassen aus dem Quellcode kopieren und einige Sachen schlachten, aber der Prinzipal funktioniert hier. Großartiges Zeug @moonzai –

+0

@RussWheeler mein Vergnügen Kumpel :-) – moonzai

Verwandte Themen