Mediaplayer cortando el sonido demasiado pronto

Tengo dos dispositivos en los que puedo probar mi juego: Un celular Celluar (SCH-R880) y un Kindle Fire, el Kindle Fire es mucho más potente que el teléfono.

Tengo varios efectos de sonido cortos (Menos o aproximadamente 1 segundo). Para guardar en la memoria, carga, reproduce y suelto algunos de estos efectos de sonido. En el teléfono juegan (sobre todo) como se esperaba. En el Kindle Fire, sin embargo, son cortos. Los sonidos realmente cortos se cortan tan rápidamente que no escucho nada. Los que se cargan en la configuración y permanecen, sin embargo, jugar bien.

Alguien tiene alguna idea de lo que está pasando aquí? ¿De algún modo estoy liberando mis medios de comunicación demasiado pronto? A continuación se muestra un ejemplo de esto. En el teléfono oigo "Nivel dos!" Pero en el Kindle escucho algo como "Lev tw."

mpNum = null; try { switch (level) { case 2: mpNum = MediaPlayer.create(contxt, R.raw.l2); break; case 3: mpNum = MediaPlayer.create(contxt, R.raw.l3); break; case 4: mpNum = MediaPlayer.create(contxt, R.raw.l4); break; case 5: mpNum = MediaPlayer.create(contxt, R.raw.l5); break; case 6: mpNum = MediaPlayer.create(contxt, R.raw.l6); break; case 7: mpNum = MediaPlayer.create(contxt, R.raw.l7); break; case 8: mpNum = MediaPlayer.create(contxt, R.raw.l8); break; default: return; } MediaPlayer vLevel = MediaPlayer.create(contxt, R.raw.level); vLevel.setOnPreparedListener(new MediaPlayer.OnPreparedListener() { public void onPrepared(MediaPlayer mp) { mp.start(); } }); vLevel.setOnCompletionListener(new MediaPlayer.OnCompletionListener() { public void onCompletion(MediaPlayer mpl) { mpNum.start(); mpl.release(); } }); mpNum.setOnCompletionListener(new MediaPlayer.OnCompletionListener() { public void onCompletion(MediaPlayer mp) { mp.release(); } }); } catch (Exception e) {} 

En un intento de tratar de solucionar esto, he intentado SoundPool, pero no funciona; No oigo nada. A continuación se muestra lo que hice para intentar reproducir la música con SoundPool:

 SoundPool soundPool = new SoundPool(1, AudioManager.STREAM_MUSIC, 100); soundPool.load(contxt, R.raw.song2, 1); AudioManager mgr = (AudioManager)contxt.getSystemService(Context.AUDIO_SERVICE); float streamVolumeCurrent = mgr.getStreamVolume(AudioManager.STREAM_MUSIC); float streamVolumeMax = mgr.getStreamMaxVolume(AudioManager.STREAM_MUSIC); float volume = streamVolumeMax; soundPool.play(1, volume, volume, 1, 5, 2); 

ACTUALIZAR

He notado cuando un sonido que debe estar jugando (pero no) tiene este error que aparece:

 AudioPolicyManager: stopOutput() oldDevice 2 AudioPolicyManager: [getDeviceForStrategy] strategy : 0,forceUse(0) 

Tuve el mismo problema y de hecho fue un problema de recolector de basura! Si asigna la instancia del reproductor de medios a alguna variable local dentro de un método, la instancia ya no existe después de dejar ese método, por lo que GC puede eliminarlo aleatoriamente en cualquier momento.

Para evitar esto, debe mantener al menos un puntero en la instancia en otro lugar. He creado un conjunto estático para mantener todos los punteros, se ve así:

 private static Set<MediaPlayer> activePlayers = new HashSet<MediaPlayer>(); 

A continuación, la creación del reproductor de medios es la siguiente:

 MediaPlayer player = MediaPlayer.create(context, context.getResources().getIdentifier(id, "raw", pkg)); activePlayers.add(player); player.setOnCompletionListener(releaseOnFinishListener); player.start(); 

Donde releaseOnFinishListener es un oyente que libera al reproductor de medios al final igual que el tuyo pero también elimina el puntero del conjunto activePlayers:

 MediaPlayer.OnCompletionListener releaseOnFinishListener = new MediaPlayer.OnCompletionListener() { public void onCompletion(MediaPlayer mp) { mp.release(); activePlayers.remove(mp); } }; 

Espero que esto te ayude.

He leído que la clase SoundPool es más adecuada para sonidos cortos como este que MediaPlayer, pero probablemente no sea el problema. ( Aquí hay un enlace a un ejemplo de SoundPool).

¿También puede publicar el código para su controlador de clics?

Además, recomiendo en lugar de liberar y recuperar instancias de MediaPlayer, use una instancia de MediaPlayer y siga las secuencias típicas reset (), setDataSource (), prepare (), start () siempre que sea necesario volver a usarla. Será más eficiente que construir una nueva instancia cada vez. Es decir:

 MediaPlayer mp = new MediaPlayer(); AssetFileDescriptor afd = getResources().openRawResourceFd(R.raw.sound1); mp.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength(); mp.prepare(); mp.start(); //to reuse mp.reset(); afd = getResources().openRawResourceFd(R.raw.sound2); mp.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength(); mp.prepare(); mp.start(); 

Así que tuve los mismos problemas en un proyecto y es porque en KindleFire los sonidos cortados antes de terminar para arreglar eso (con el lanzamiento) agregué un retraso en el lanzamiento:

  mpNum.setOnCompletionListener(new MediaPlayer.OnCompletionListener() { public void onCompletion(MediaPlayer mp) { // Add a handler delay new Timer().schedule(new TimerTask() { @Override public void run() { mp.release(); } }, DELAY_TIME); } }); 

No es la mejor solución, pero creo que tal vez le ayudará.

Esto es extraño, y no es una buena solución, pero la única solución que he encontrado hasta ahora. Si mp.setOnPreparedListener y mp.setOnCompletionListener y sólo tiene mp.start() , funciona.

Tuve este problema y lo solucioné haciendo mi objeto MediaPlayer privado, por lo que el recolector de basura no limpia la instancia. Espero que ayude a alguien!

  • Cómo detener reproductor multimedia correctamente, android
  • Control de medios de pantalla de bloqueo para reproductor multimedia personalizado
  • Android MediaPlayer parpadea al reproducir vídeos en Android 4.2.2
  • ¿Cómo evitar que el exoplayer se recargue en caso de retroceso?
  • Java.io.IOException: setDataSource falló al reproducir grabado mp4
  • Pausa y búsqueda en Android MediaPlayer
  • No se puede crear mediaplayer al reproducir sonido usando uri desde RingtoneManager.getDefaultUri (RingtoneManager.TYPE_ALARM) en android
  • Cómo hacer que la actividad continúe la transmisión de vídeo cuando se cambia la orientación
  • Lista completa de los códigos de error de MediaPlayer
  • Cómo reproducir el archivo de sonido cuando se dispara GCMIntentService onMessage?
  • MediaPlayer.getCurrentPosition ()> mediaPlayer.getDuration () al final de la reproducción del archivo mp3
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.