2010-08-26 77 views
20

基本上,我想制作一个音频可视化器。我知道这是可能的,因为我的手机附带了几个动态壁纸。问题是,我似乎无法弄清楚如何使用Android API来做到这一点。访问Android媒体流以进行音频可视化

我的应用程序会选取当前正在播放的媒体流,然后根据当时正在播放的音量,它会在屏幕上显示更多或更少的条。

我该怎么做?它看起来像我可以用麦克风做这样的事情,但我希望能够做到这一点,音乐,播客等。

+0

从一个应用程序获取来自其他应用程序的音频(例如,可能存在严重的隐私问题)。,VOIP)。 – CommonsWare 2010-09-09 18:45:05

+1

请参阅我的回答,2.3通过低分辨率的音频嗅探器API以安全的方式解决此问题。 snoop()将无法在2.3设备上工作,找不到功能。 – HaMMeReD 2011-01-10 20:15:23

回答

5

MusicVisualization wallpaper source可在AOSP处获得。它基本上似乎涉及呼吁MediaPlayer.snoop(),Eclair中添加一个未公开的方法。

+0

谢谢!在赏金到期之前,我没有时间去测试,但这似乎正是我所期待的。 – HenryAdamsJr 2010-10-20 14:30:57

+0

谢谢,请在此发布一个链接到您的结果! – adietrich 2010-10-21 07:17:29

+0

该链接不再工作 – 2013-10-31 09:47:31

2

这是我从我的应用程序做到了:

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

然后在循环:

int res = snoop(mAudioData, 0); 

,这里是本身的功能:

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

基本上什么roskit说除了从

01次要返回值修改
return 0; 

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

换句话说:

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

稍快snoop()将调用Class.getMethod()一次,然后使用一个自定义parseInt()而不是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

它看起来像在2.3事情已经改变了这里,有权限现在

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

而且还有在AOSP一个AudioCapture辅助类来帮助动态壁纸做正确。 https://android.googlesource.com/platform/packages/wallpapers/MusicVisualization/+/gingerbread-release/src/com/android/musicvis/AudioCapture.java

编辑:

一位在AOSP的进口量不匹配的公共API。
import android.media.audiofx.Visualizer;


import android.media.Visualizer;

如果它给出了一个头痛确保切换。这都是2.3 api,它显然会返回一个低分辨率的音频流,但对于录制而言还不够好。

+2

对于2.3+,这是要走的路。看到这里的示例实现:https://github.com/felixpalmer/android-visualizer – pheelicks 2011-12-07 21:26:38