Acceso al flujo de medios de Android para la visualización de audio

Básicamente, quiero hacer un visualizador de audio. Sé que es posible, porque mi teléfono viene con unos fondos de pantalla en vivo que lo hacen. El problema es que no puedo averiguar cómo hacerlo con la API de Android.

Mi aplicación recogería el stream de medios actualmente en reproducción y, dependiendo del volumen que se esté reproduciendo en ese momento, mostraría más o menos barras en la pantalla.

¿Cómo puedo hacer esto? Parece que podría hacer algo como esto con el micrófono, pero quiero poder hacerlo por música, podcasts, etc.

La fuente de papel tapiz de MusicVisualization está disponible en el AOSP . Básicamente parece implicar llamar a MediaPlayer.snoop() , un método indocumentado añadido en Eclair.

Parece que en 2.3 las cosas han cambiado aquí, hay permisos ahora

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

Y hay una clase de ayudante de AudioCapture en losp para ayudar a los fondos de pantalla en vivo a hacerlo correctamente. https://android.googlesource.com/platform/packages/wallpapers/MusicVisualization/+/gingerbread-release/src/com/android/musicvis/AudioCapture.java

Editar:

Una de las importaciones en la AOSP no coincide con la API pública.
import android.media.audiofx.Visualizer;

es
import android.media.Visualizer;

Si da un dolor de cabeza asegúrese de cambiar. Esto es todo 2.3 api, al parecer, devuelve un flujo de audio de baja resolución para viz, pero no es lo suficientemente bueno para la grabación.

Básicamente lo que dijo roskit excepto con una modificación de valor de retorno menor de

 return 0; 

a

 return Integer.parseInt( (m.invoke(c, outData, kind)).toString() ); 

En otras palabras:

 public static int snoop(short [] outData, int kind){ try { Class c = MediaPlayer.class; Method m = c.getMethod("snoop", outData.getClass(), Integer.TYPE); m.setAccessible(true); return Integer.parseInt( (m.invoke(c, outData, kind)).toString() ); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); return 1; } } 

Un snoop() ligeramente más rápido snoop() sería llamar a Class.getMethod() una vez, y luego usar un parseInt() lugar de Integer.parseInt()

 private static Method mSnoop; //..(http://nadeausoftware.com/node/97).. private static int customParseInt( final String s ) { // Check for a sign. int num = 0; int sign = -1; final int len = s.length( ); final char ch = s.charAt( 0 ); if ( ch == '-' ) sign = 1; else num = '0' - ch; // Build the number. int i = 1; while ( i < len ) num = num*10 + '0' - s.charAt( i++ ); return sign * num; } private static int snoop(short [] outData, int kind) { if ( mSnoop != null ) { try { return customParseInt( (mSnoop.invoke( MediaPlayer.class , outData, kind)).toString() ); } catch ( Exception e ) { Log.e( TAG, "Failed to MediaPlayer.snoop()!", e ); return 1; } } else { try { Class c = MediaPlayer.class; Method m = c.getMethod("snoop", outData.getClass(), Integer.TYPE); m.setAccessible(true); mSnoop = m; return customParseInt( (m.invoke(c, outData, kind)).toString() ); } catch (Exception e) { Log.e( TAG, "Failed to MediaPlayer.snoop()!", e ); return 1; } } } 

Así es como lo hice desde mi aplicación:

 protected short [] mAudioData = new short[1024]; 

Luego en el bucle:

 int res = snoop(mAudioData, 0); 

Y aquí está la función en sí:

 public static int snoop(short [] outData, int kind){ try { Class c = MediaPlayer.class; Method m = c.getMethod("snoop", outData.getClass(), Integer.TYPE); m.setAccessible(true); m.invoke(c, outData, kind); return 0; } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); return 1; } } 

Consulte http://code.google.com/p/moonblink/wiki/Tricorder para obtener un ejemplo.

  • La aplicación de Android se bloquea con NullPointerException en ChoreoGrapher
  • ¿Cómo aplicar la validación del archivo DTD local al archivo xml en java?
  • Error de importación de Eclipse con Facebook .jar?
  • Obtener mapa de bits de ImageView en Android L
  • RxJava / Android: Combina el resultado de dos dependientes dependientes
  • ¿Qué significa exactamente este signo? | =
  • Ejecución de aplicaciones Java en Android Studio
  • PreferenceFragment.findPreference devuelve siempre NULL
  • Reproducción de música BG en actividades en Android
  • Gradle Android Maven Plugin no crea el archivo pom automáticamente
  • Almacén de datos local ParseQuery orderByDescending con createdAt no funciona
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.