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.
- ¿Cómo instalar manualmente App Engine en Android Studio?
- No hay tipo de proyecto Android en Eclipse-> Archivo-> Nuevo proyecto
- Cómo convertir InputStream en origen?
- ¿Cómo puedo leer / escribir octetos hexadecimales crudos de la corriente de entrada / salida en BluetoothChat?
- Comunicación USB entre Android (modo accesorio) y Windows PC (host)
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.
- Android Studio 2.3 Firma de confirmación de paso v1 (Firma del frasco), v2 (Firma Apk completa) Desactivado
- ¿Qué versiones de GLSL puedo usar en OpenGL ES 2.0?
- Persistencia de una clase Collection con ORMLite en android
- ¿Es posible ejecutar pruebas de unidad de Android Espresso en métodos anotados @BeforeClass?
- Java.lang.NumberFormatException: Invalid int: ""
- Esperando que se complete un Runnable antes de ejecutar otro Runnable
- Rx Java mergeDelayError no funciona como se esperaba
- ¿Cómo usar PJSIP en Android?
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 ().