基本上,我想製作一個音頻可視化器。我知道這是可能的,因爲我的手機附帶了幾個動態壁紙。問題是,我似乎無法弄清楚如何使用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