Доступ к медиа-потоку Android для аудио-визуализации - PullRequest
21 голосов
/ 26 августа 2010

В принципе, я хочу сделать аудио-визуализатор. Я знаю, что это возможно, потому что мой телефон поставляется с несколькими живыми обоями, которые делают это. Проблема в том, что я не могу понять, как это сделать с помощью Android API.

Мое приложение будет обрабатывать текущий воспроизводимый мультимедийный поток, а затем, в зависимости от громкости, воспроизводимой в это время, будет отображать более или менее полосы на экране.

Как я могу это сделать? Похоже, что я мог бы сделать что-то подобное с помощью микрофона, но я хочу быть в состоянии сделать это для музыки, подкастов и т. Д.

Ответы [ 6 ]

7 голосов
/ 10 января 2011

Похоже, что в 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, он, очевидно, возвращает аудиопоток с низким разрешением для Viz, но не достаточно хорошо для записи.

5 голосов
/ 19 октября 2010

Источник обоев MusicVisualization доступен на AOSP . Похоже, в основном это связано с вызовом MediaPlayer.snoop(), недокументированного метода, добавленного в Eclair.

3 голосов
/ 06 декабря 2010

В основном то, что сказал Роскит, за исключением незначительного изменения возвращаемого значения с

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 голосов
/ 08 декабря 2010

Немного быстрее 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 голосов
/ 06 декабря 2010

Вот как я это сделал из своего приложения:

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;
    }
}
0 голосов
/ 28 августа 2010

Посмотрите на http://code.google.com/p/moonblink/wiki/Tricorder для примера.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...