Android MediaPlayer con AudioEffect: Obtención de error (-22,0)

Bueno, simplemente este es mi requisito.

Tengo un archivo WAV, quiero abrirlo, añadir algunos efectos, y jugar.

Estoy usando MediaPlayer para reproducir archivos, y PresetReverb para agregar algunos efectos.

Este es mi codigo

public void playSound(){ String fullPath = MainActivity.this.filePath + "tmpaudio.wav"; final MediaPlayer player = new MediaPlayer(); player.setDataSource(this, Uri.parse(fullPath)); PresetReverb pReverb = new PresetReverb(0,player.getAudioSessionId()); pReverb.setPreset(PresetReverb.PRESET_LARGEROOM); pReverb.setEnabled(true); player.attachAuxEffect(eReverb.getId()); player.setAuxEffectSendLevel(1.0f); //prepare for playback player.prepare(); // Media prepared listener player.setOnPreparedListener(new MediaPlayer.OnPreparedListener() { public void onPrepared(MediaPlayer mp) { //play player.start(); } }); } 

Cuando ejecuto este código, estoy recibiendo un log en logcat (No registrado por mí.)

05-02 12: 02: 42.356: E / MediaPlayer (17250): Error (-22,0)

Pero cuando comento estas líneas

 PresetReverb pReverb = new PresetReverb(0,player.getAudioSessionId()); pReverb.setPreset(PresetReverb.PRESET_LARGEROOM); pReverb.setEnabled(true); player.attachAuxEffect(eReverb.getId()); player.setAuxEffectSendLevel(1.0f); 

MediaPlayer reproduce el archivo correctamente. Así que nada malo con mi archivo WAV.

Al ser un poco decepcionado, he intentado EnvironmentalReverb , en lugar de PresetReverb,

 EnvironmentalReverb eReverb = new EnvironmentalReverb(1, player.getAudioSessionId()); eReverb.setDecayHFRatio((short) 1000); eReverb.setDecayTime(10000); eReverb.setDensity((short) 1000); eReverb.setDiffusion((short) 1000); eReverb.setReverbLevel((short) -1000); eReverb.setEnabled(true); player.attachAuxEffect(eReverb.getId()); player.setAuxEffectSendLevel(1.0f); 

Allí también conseguí el mismo error (error (-22,0)).

Así que o estoy perdiendo algo tan obvio, o hay algún problema con las clases de la familia AudioEffect (en la documentación o api en sí). ¿Puede alguien arrojar algo de luz?

EDIT: Olvidé agregar, cuando depuse el código el error se registra cuando

  player.start(); 

es ejecutado. He eliminado las partes de manejo de excepciones antes de publicar el segmento de código anterior. Pero soy positivo, ninguna excepción se coge cuando ejecuté.

EDITAR OTRA VEZ:

De este enlace llegué a entender el error -22 es PVMFErrLicenseRequiredPreviewAvailable

 /* Error due to the lack of a valid license for the content. However a preview is available. */ const PVMFStatus PVMFErrLicenseRequiredPreviewAvailable = (-22); 

I googled con PVMFErrLicenseRequiredPreviewAvailable, y conseguí este documento. Y en la página 87

14.10.5 Vista previa del contenido de DRM sin una licencia válida disponible

Una variación en el escenario cubierto en la Sección 14.10.3 es el caso en el que no hay una licencia válida para la reproducción completa de una pieza de contenido, pero allí se puede previsualizar. Este escenario podría ser una forma común de distribuir inicialmente contenido para que los consumidores puedan obtener una vista previa antes de decidirse a comprar una licencia completa. En este caso, el método Init () volverá con el código PVMFErrLicenseRequiredPreviewAvailable, lo que indica que se requiere una licencia para la reproducción completa, pero una vista previa está disponible. Para poder reproducir la vista preliminar, la aplicación debe eliminar la fuente actual y volver a añadirla con un indicador establecido en la fuente de datos local para indicar el modo de vista previa.

Ahora los archivos WAV que he reproducido es generado por mí utilizando la herramienta SpeechToText en android SDK en sí. No sé qué licencia me impide reproducir este archivo.

Bueno, lo conseguí trabajando por fin. Releí la documentación, jugé con el código y de repente todo funcionó. Estos son mis descubrimientos en caso de que ayude a alguien en el futuro.

En el caso de PresetReverb

En la documentación PresetReverb

El PresetReverb es un efecto auxiliar de mezcla de salida y debe crearse en la sesión de audio 0 . Para que un MediaPlayer o AudioTrack sea alimentado en este efecto, deben estar explícitamente unidos a él y debe especificarse un nivel de envío . Utilice el ID de efecto devuelto por el método getId () para designar este efecto particular al adjuntarlo al MediaPlayer o AudioTrack.

Que dice

 PresetReverb pReverb = new PresetReverb(0,player.getAudioSessionId()); <== error 

No se permite. Sólo puede utilizar la sesión de audio global 0 para construir PresetReverb.

 PresetReverb pReverb = new PresetReverb(1,0); <== correct 

Ahora podemos adjuntarlo con MediaPlayer o AudioTrack usando

 player.attachAuxEffect(pReverb.getId()); player.setAuxEffectSendLevel(1.0f); 

Mi código PresetReverb completo es

 PresetReverb pReverb = new PresetReverb(1,0); player.attachAuxEffect(pReverb.getId()); pReverb.setPreset(PresetReverb.PRESET_LARGEROOM); pReverb.setEnabled(true); player.setAuxEffectSendLevel(1.0f); 

Nota: Si está buscando un buen efecto de reverberación o eco, utilice mejor EnvironmentalReverb. Estoy un poco decepcionado con el rendimiento de PresetReverb.

En el caso de EnvironmentalReverb

De la documentación de EnvironmentalReverb

El EnvironmentalReverb es un efecto auxiliar de mezcla de salida y debe crearse en la sesión de Audio 0. Para que un MediaPlayer o AudioTrack pueda alimentarse con este efecto, deben estar explícitamente conectados a él y debe especificarse un nivel de envío . Utilice el ID de efecto devuelto por el método getId () para designar este efecto particular al adjuntarlo al MediaPlayer o AudioTrack.

Exactamente como PresetReverb, pero cuando escribí

 Log.e("DEBUG","sessionId : " + player.getAudioSessionId()); <== printed "454" EnvironmentalReverb eReverb = new EnvironmentalReverb(0,player.getAudioSessionId()); //should be error as per documentation //player.attachAuxEffect(eReverb.getId()); <== Yes this one was commented 

No hubo error y tengo buen efecto de reverberación y eco. Así que parece un error en la documentación. También cuando pasamos el identificador de sesión del jugador al constructor (player.getAudioSessionId ()), parece que no hay necesidad de conectar al jugador con la instancia de EnvironmentReverb. Extraño..

En aras de la integridad de este también trabajó justo como la documentación dice.

 EnvironmentalReverb eReverb = new EnvironmentalReverb(0,0); player.attachAuxEffect(eReverb.getId()); <== No,not comment this one 

Para otros niños de AudioEffect (Equalizer, BassBoost, Virtualizer)

Estos no eran la parte de mi pregunta. Pero para todos los que vean esto en el futuro ..

NOTA: adjuntar efectos de inserción (ecualizador, aumento de graves, virtualizador) a la mezcla de salida de audio global mediante el uso de la sesión 0 está obsoleto.

Ver documentación

Respecto al error (-22,0)

Bueno, es justo decir que no fue un mensaje de error informativo. No sé por qué se produce un error de licencia no válido cuando se interfiere con la sesión de audio. De todos modos cuando corregí el parámetro de sesión de audio este error desapareció. Eso es todo lo que sé.

Tengo el mismo problema, para usar la sesión de audio 0 tienes que usar el permiso MODIFY_AUDIO_SETTINGS

Esta línea en esencia, resolvió uno de los problemas, pero todavía requiere permisos.

 PresetReverb pReverb = new PresetReverb(1,0); 

Así que agregar la línea de abajo a su AndroidManifest.xml realmente resolvió el problema raíz:

 <uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" /> 

OH, también, es necesario configurar PresetReverb y adjuntarlo a su AudioTrack para que ocurra ANTES de hacer la AudioTrack.write () y AudioTrack.play ().

  • Gestionar devoluciones de llamada en el cliente android de Socket.io v1.4
  • ¿Cómo puedo implementar el equivalente RxJava de INotifyPropertyChanged para hacer un modelo de datos Observable?
  • Programe PPTP / L2TP VPN de forma programática en Android
  • ¿Cómo implementar la comunicación entre la aplicación cliente Java (Android) y la aplicación de servidor PHP?
  • Cómo aplicar máscara a valor de cadena
  • Animar el ángulo de barrido de Android Ring Shape
  • Android-support-v4.jar no se importa correctamente en Eclipse
  • Restringir el reconocimiento de voz a palabras alfanuméricas
  • TELEPHONY_SERVICE constante no reconocida en una clase, pero está en otra
  • Cómo averiguar qué clase anónima interior se indica por un nombre de clase?
  • TextToSpeech setLanguage no funciona?
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.