【问题标题】:How do I get the current volume/amplitude in a MediaPlayer?如何获取 MediaPlayer 中的当前音量/幅度?
【发布时间】:2011-02-24 20:44:15
【问题描述】:

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

【问题讨论】:

  • 我对你接受的答案感到困惑,它似乎没有从 cmets 解决你的问题,对吗?
  • 不仅如此,对这个问题的另一个类似错误的答案在下面获得了 31 票。

标签: android android-mediaplayer


【解决方案1】:

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

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

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

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

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

【讨论】:

  • 这不是他要问的。他要的是当前的输出电平,而不是音量设置。
  • 请仔细阅读我的回答。我已经解释了这两件事。
  • 他要求的是正在运行的实时波形幅度数据(当前输出电平),而不是播放器的音量设置,这就是你所建议的。
  • 那么您的答案中的振幅数据在哪里? @DeepakSharma
【解决方案2】:

你很幸运。有一个名为 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>

【讨论】:

  • Visualizer 可能是 Java 中跨平台最少的类。保证要求在至少一个目标平台(linux、mac、win、arm 等与某些声音芯片组合)上进行子类化。甚至比 Camera 类更糟糕。也是一个CPU hog。更好地在数据线上实现 getLevel() 以满足 OPs 的要求。它只是一个缓冲区,因此可以在任何地方使用。
  • 这个答案在问题的上下文中最有帮助
【解决方案3】:

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

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

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

那我觉得this method会很有用。

【讨论】:

  • 这就是我一直在探索的地方,但该方法返回的是设备当前设置的音量级别,而不是播放级别。
  • 区别在哪里?也许您要求的是错误流的音量?
  • 不是当前播放流的音量问题,而是实际播放的媒体的音量问题。仅仅因为您的音乐流音量设置为 60% 并不意味着当时的音量处于同一水平。这可能是歌曲中安静的部分。
  • 他要求访问音频流样本数据,而不是播放器的音量设置,这只是一个缩放倍数。为什么这是公认的答案?您至少可以接受 Visualizer 解决方案,即使该课程的麻烦多于其价值。
【解决方案4】:

如下:

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

【讨论】:

    【解决方案5】:

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

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

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

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

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

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

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

    【讨论】:

      【解决方案6】:

      我一直在寻找一种方法来做something similar 一段时间。我真的希望能够看到通过媒体流播放的任何内容的音量/幅度,但我会满足于能够为我当前正在播放的内容做到这一点。

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

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

      【讨论】:

        【解决方案7】:

        我得到了这个解决方案:

        final int volume_level = audioManager.getStreamVolume(AudioManager.STREAM_MUSIC);
        int maxVolume = audioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC);
        float volume = (float) volume_level / maxVolume;
        

        【讨论】:

        • 这只是告诉你可以设置多高的音量。 OP 正在寻找实时幅度测量值。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多