基本上,我想制作一个音频可视化器。我知道这是可能的,因为我的手机附带了几个动态壁纸。问题是,我似乎无法弄清楚如何使用Android API来做到这一点。访问Android媒体流以进行音频可视化
我的应用程序会选取当前正在播放的媒体流,然后根据当时正在播放的音量,它会在屏幕上显示更多或更少的条。
我该怎么做?它看起来像我可以用麦克风做这样的事情,但我希望能够做到这一点,音乐,播客等。
基本上,我想制作一个音频可视化器。我知道这是可能的,因为我的手机附带了几个动态壁纸。问题是,我似乎无法弄清楚如何使用Android API来做到这一点。访问Android媒体流以进行音频可视化
我的应用程序会选取当前正在播放的媒体流,然后根据当时正在播放的音量,它会在屏幕上显示更多或更少的条。
我该怎么做?它看起来像我可以用麦克风做这样的事情,但我希望能够做到这一点,音乐,播客等。
MusicVisualization wallpaper source可在AOSP处获得。它基本上似乎涉及呼吁MediaPlayer.snoop()
,Eclair中添加一个未公开的方法。
谢谢!在赏金到期之前,我没有时间去测试,但这似乎正是我所期待的。 – HenryAdamsJr 2010-10-20 14:30:57
谢谢,请在此发布一个链接到您的结果! – adietrich 2010-10-21 07:17:29
该链接不再工作 – 2013-10-31 09:47:31
tricorder应用程序使用麦克风进行音频可视化。我希望能够从原始数据流中提取信息,即使戴着耳机也能正常工作,并且不会受到外部噪音的影响。 – HenryAdamsJr 2010-08-28 17:38:25
这是我从我的应用程序做到了:
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;
}
}
基本上什么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;
}
}
稍快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;
}
}
}
它看起来像在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.3+,这是要走的路。看到这里的示例实现:https://github.com/felixpalmer/android-visualizer – pheelicks 2011-12-07 21:26:38
从一个应用程序获取来自其他应用程序的音频(例如,可能存在严重的隐私问题)。,VOIP)。 – CommonsWare 2010-09-09 18:45:05
请参阅我的回答,2.3通过低分辨率的音频嗅探器API以安全的方式解决此问题。 snoop()将无法在2.3设备上工作,找不到功能。 – HaMMeReD 2011-01-10 20:15:23