java android audio android-mediaplayer audioeffect

java - Android MediaPlayer con AudioEffect: Obteniendo Error(-22,0)



android-mediaplayer (3)

Bueno, simplemente este es mi requisito ...

Tengo un archivo WAV, quiero abrirlo, agregar algunos efectos y jugar.

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

Este es mi código

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, obtengo un registro 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 está reproduciendo el archivo con éxito. Así que no hay nada malo con mi archivo WAV.

Siendo algo decepcionado, probé 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);

también recibí el mismo error (Error (-22,0)).

Entonces me falta algo tan obvio, o hay algún problema con las clases de la familia AudioEffect (en la documentación o API). ¿Alguien puede arrojar algo de luz?

EDITAR: Olvidé agregar, cuando depuré el código, el error se registra cuando

player.start();

es ejecutado. He eliminado partes de manejo de excepciones antes de publicar el segmento de código anterior. Pero estoy seguro de que no se detecta ninguna excepción cuando ejecuto.

EDITAR DE NUEVO

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);

Busqué en Google con PVMFErrLicenseRequiredPreviewAvailable, y obtuve 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 del escenario cubierto en la Sección 14.10.3 es el caso donde no hay una licencia válida para la reproducción completa de una parte del contenido, pero allí se puede obtener una vista previa. Este escenario podría ser una forma común de distribución inicial de contenido para que los consumidores puedan obtener una vista previa antes de decidir comprar una licencia completa. En este caso, el método Init () volverá con el código PVMFErrLicenseRequiredPreviewAvailable, que indica que se necesita una licencia para la reproducción completa, pero hay una vista previa disponible. Para reproducir la vista previa, la aplicación debe eliminar la fuente actual y luego volver a agregarla con un marcador establecido en la fuente de datos local para indicar el modo de vista previa.

Ahora los archivos WAV que jugué los generé usando la herramienta SpeechToText en el SDK de Android. No sé qué licencia me impide reproducir este archivo.


Bueno, lo tengo trabajando al fin. Volví a leer la documentación, jugué con el código y de repente todo funcionó. Estos son mis hallazgos 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 un AudioTrack se alimenten con este efecto, deben estar explícitamente unidos y se debe especificar un nivel de envío . Use el ID de efecto devuelto por el método getId () para designar este efecto particular cuando lo conecte al MediaPlayer o al AudioTrack.

Que dice

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

No se permite. Solo puede usar 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 completo de PresetReverb 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 busca un buen efecto de reverberación o eco, mejor use EnvironmentalReverb. Estoy algo 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 un AudioTrack se alimenten con este efecto, deben estar explícitamente unidos y se debe especificar un nivel de envío . Use el ID de efecto devuelto por el método getId () para designar este efecto particular cuando lo conecte al MediaPlayer o al 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 obtengo un buen efecto de reverberación y eco. Entonces parece un error en la documentación. Además, cuando pasamos la identificación de sesión del jugador al constructor (player.getAudioSessionId ()), parece que no hay necesidad de adjuntar jugador con la instancia de EnvironmentalReverb. Extraño..

En aras de la exhaustividad, este también funcionó tal como lo dice la documentación.

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

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

Estos no fueron parte de mi pregunta. Pero para todos los que lo vean en el futuro ...

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

ver documentación

En cuanto a error (-22,0)

Bueno, es justo decir que no fue un mensaje de error informativo. No sé por qué aparece un error de licencia no válida cuando fallamos la sesión de audio. De todos modos, cuando corregí el parámetro de la 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 debes usar el permiso MODIFY_AUDIO_SETTINGS


Esta línea en esencia, resolvió uno de los problemas, pero aún requería permisos.

PresetReverb pReverb = new PresetReverb(1,0);

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

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

OH, también, necesita configurar PresetReverb y adjuntarlo a su AudioTrack para que ocurra ANTES de que haga AudioTrack.write () y AudioTrack.play ().