2010-08-26 5 views
20

Básicamente, quiero hacer un visualizador de audio. Sé que es posible, porque mi teléfono viene con algunos fondos de pantalla en vivo que lo hacen. El problema es que parece que no puedo entender cómo hacerlo con la API de Android.Accediendo a la transmisión multimedia de Android para visualización de audio

Mi aplicación recogía la transmisión multimedia que se estaba reproduciendo actualmente y luego, dependiendo del volumen que se estaba reproduciendo en ese momento, mostraba más o menos barras en la pantalla.

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

+0

Puede haber serios problemas de privacidad para una aplicación que adquiere el audio de otra aplicación (p., VOIP). – CommonsWare

+1

Ver mi respuesta más abajo, 2.3 resuelve esto de una manera segura, a través de una api de visualizador de audio sniffing de baja resolución. snoop() no funcionará en dispositivos 2.3, función no encontrada. – HaMMeReD

Respuesta

2

Esta es la forma en que lo hice desde mi aplicación:

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

Luego, en el bucle:

int res = snoop(mAudioData, 0); 

Y aquí es la función propia:

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; 
    } 
} 
3

Básicamente lo roskit dicho 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; 
      } 
    } 
2

Un poco más rápido snoop() habría que llamar Class.getMethod() una vez, y luego utilizar una costumbre parseInt() en 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; 
     } 
    } 
} 
6

Parece que en 2.3 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 ayuda AudioCapture en los PSE para ayudar a los fondos de pantalla en vivo lo hacen correctamente. https://android.googlesource.com/platform/packages/wallpapers/MusicVisualization/+/gingerbread-release/src/com/android/musicvis/AudioCapture.java

Editar:

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

es
import android.media.Visualizer;

si se da un dolor de cabeza Asegúrese de cambiar. Esto es todo 2.3 api, aparentemente devuelve un flujo de audio de baja resolución para viz, pero no lo suficientemente bueno para grabar.

+2

Para 2.3+, este es el camino a seguir. Vea aquí para una implementación de ejemplo: https://github.com/felixpalmer/android-visualizer – pheelicks

Cuestiones relacionadas