【问题标题】:Accessing the Android media stream for audio visualization访问 Android 媒体流以进行音频可视化
【发布时间】:2010-08-26 03:16:55
【问题描述】:

基本上,我想做一个音频可视化工具。我知道这是可能的,因为我的手机附带了一些可以做到这一点的动态壁纸。问题是,我似乎无法弄清楚如何使用 Android API 做到这一点。

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

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

【问题讨论】:

  • 一个应用程序从另一个应用程序(例如,VOIP)获取音频可能存在严重的隐私问题。
  • 进一步查看我的答案,2.3 通过低分辨率音频嗅探可视化 API 以安全的方式解决了这个问题。 snoop() 在 2.3 设备上不起作用,找不到函数。

标签: java android audio


【解决方案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,它显然为 viz 返回了一个低分辨率的音频流,但不足以录制。

【讨论】:

【解决方案2】:

MusicVisualization wallpaper source 可在AOSP 获得。它基本上似乎涉及调用 MediaPlayer.snoop(),这是 Eclair 中添加的一个未记录的方法。

【讨论】:

  • 谢谢!在赏金到期之前我没有时间对此进行测试,但这似乎正是我想要的。
  • 谢谢,请在此处发布结果链接!
【解决方案3】:

基本上是 roskit 所说的,除了来自

的较小的返回值修改
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;
           }
    }

【讨论】:

    【解决方案4】:

    稍快的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;
            }
        }
    }
    

    【讨论】:

      【解决方案5】:

      这就是我在应用程序中的做法:

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

      【讨论】:

        【解决方案6】:

        【讨论】:

        • 三录仪应用程序使用麦克风进行音频可视化。我希望能够从原始流中提取信息,这样即使您戴着耳机也能正常工作,并且不会受到外部噪音的影响。
        • 链接已损坏。
        猜你喜欢
        • 2016-06-12
        • 1970-01-01
        • 1970-01-01
        • 2013-02-24
        • 2013-05-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多