29

我正在开发一个应用程序,它既可以录制音频文件,又可以选择在录制完成后播放该文件。UI 有一个 EQ 组件,该组件相对于当前录音幅度进行动画处理。我已经通过该MediaRecorder.getMaxAmplitude()方法使动画工作,但找不到任何使用 MediaPlayer 执行此操作的方法。我知道这一定是可能的,因为默认情况下有音乐可视化动态壁纸可以执行此功能,但我看不出它在通过 AOSP 梳理时以任何方式提取该信息。有谁知道如何使这项工作?

4

7 回答 7

30

您可以借助 Audiomanager 类获取媒体播放器的当前音量。代码如下:-

AudioManager am = (AudioManager) getSystemService(AUDIO_SERVICE);
int volume_level= am.getStreamVolume(AudioManager.STREAM_MUSIC);

同样,如果你想设置媒体播放器的默认音量。你可以这样做: -

am.setStreamVolume(
            AudioManager.STREAM_MUSIC,
            volume_level,
            0);

就是这样......快乐的编码:)

于 2013-08-16T12:51:02.667 回答
13

你很幸运。有一个名为 Visualizer 的类,它会做你想做的事。

import android.app.Activity;
import android.media.audiofx.Visualizer;
import android.os.Bundle;
import android.util.Log;


public class MainActivity extends Activity {
private Visualizer audioOutput = null;
public float intensity = 0; //intensity is a value between 0 and 1. The intensity in this case is the system output volume
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    createVisualizer();

}


private void createVisualizer(){
    int rate = Visualizer.getMaxCaptureRate();
    audioOutput = new Visualizer(0); // get output audio stream
    audioOutput.setDataCaptureListener(new Visualizer.OnDataCaptureListener() {
        @Override
        public void onWaveFormDataCapture(Visualizer visualizer, byte[] waveform, int samplingRate) {
            intensity = ((float) waveform[0] + 128f) / 256;
            Log.d("vis", String.valueOf(intensity));
        }

        @Override
        public void onFftDataCapture(Visualizer visualizer, byte[] fft, int samplingRate) {

        }
    },rate , true, false); // waveform not freq data
    Log.d("rate", String.valueOf(Visualizer.getMaxCaptureRate()));
    audioOutput.setEnabled(true);
}


}

您将需要以下权限:

<uses-permission android:name="android.permission.RECORD_AUDIO"></uses-permission>
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS"></uses-permission>
于 2015-05-21T21:30:40.277 回答
10

我认为您必须使用AudioManager。正如 API 所述,它可用于音量控制:

AudioManager 提供对音量和振铃模式控制的访问。

使用 Context.getSystemService(Context.AUDIO_SERVICE) 获取此类的实例。

那么我认为这种方法会很有用。

于 2010-05-27T21:04:58.327 回答
6

如下:

audioManager = (AudioManager) activity.getSystemService(Context.AUDIO_SERVICE);
int volumeLevel = audioManager.getStreamVolume(AudioManager.STREAM_MUSIC);
int maxVolumeLevel = audioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC);
int volumePercent = (int) (((float) volumeLevel / maxVolumeLevel) * 100);
于 2019-10-29T14:16:05.670 回答
2

您必须在 DataLine 中实现 getLevel()。这与 Java 中的总线一样接近。

这涉及计算来自声音流缓冲区的幅度(波形)数据的运行平均值。

这会导致大量总线流量访问缓冲区,因此保留为抽象方法。

均方根 (RMS) 是一种方法:

https://community.oracle.com/message/5391003

带有 FFT 的 DSP(例如 Visualizer 类)提供了完整的频谱,但会消耗更多的 CPU 资源。

如果您只需要 RMS(例如简单的节拍检测),请不要使用完整的 DSP。限制样品的质量以提高性能。

于 2014-12-24T01:19:01.767 回答
1

我一直在寻找一种方法来做类似的事情。我真的希望能够看到通过媒体流播放的任何东西的音量/幅度,但我会满足于能够为我目前正在播放的东西做这件事。

到目前为止,我发现的最佳解决方案是在RingDroid中实现的。我没有深入研究代码,但看起来 RingDroid 创建它的声音映射的方式是通过实际分析声音文件一点一点。

我考虑过使用类似的方法,然后显示一个与音频文件分开运行但以同步速度运行的可视化工具。但是,对于应该更简单的事情来说,这似乎工作量太大了。

于 2010-09-15T18:27:19.630 回答
0

我得到了这个解决方案:

final int volume_level = audioManager.getStreamVolume(AudioManager.STREAM_MUSIC);
int maxVolume = audioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC);
float volume = (float) volume_level / maxVolume;
于 2019-06-07T06:53:05.900 回答