8

根据文档的建议,我想使用该setvolume()方法来控制我的音量MediaPlayer,但我对如何管理它有点困惑。

我使用 , 设置音量SeekBar,初始化为流中的当前音量AudioManager.STREAM_MUSIC

当用户不修改设备音量控制时,这是有道理的,但是当他这样做时,我不确定我应该做什么,并且我有几个疑问:

  • MediaPlayer音量与设备音量有什么关系?设置的最大值(1)是否setVolume()对应于mAudioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC)

  • 如果是这种情况,SeekBar每次设置设备音量控制时都应该重置进度值,但是,使用MediaPlayer.setVolume()而不是AudioManager.setStreamVolume()有什么意义呢?

  • MediaPlayer.setVolume()使用a的标准方法是SeekBar什么?

private final static int MAX_VOLUME = 100;
private AudioManager mAudioManager; 
private SeekBar mVolumeControl;

mVolumeControl = (SeekBar) getActivity().findViewById(R.id.volume_control);
mAudioManager = (AudioManager) getActivity().getSystemService(Context.AUDIO_SERVICE);
mVolumeControl.setMax(MAX_VOLUME);
mVolumeControl.setProgress(MAX_VOLUME*mAudioManager.getStreamVolume(AudioManager.STREAM_MUSIC)/mAudioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC)); 
mVolumeControl.setOnSeekBarChangeListener(mVolumeControlChangeListener);

private SeekBar.OnSeekBarChangeListener mVolumeControlChangeListener = new SeekBar.OnSeekBarChangeListener() {

    @Override
    public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {

        float volume = (float) (1 - (Math.log(MAX_VOLUME - progress) / Math.log(MAX_VOLUME)));
        mediaPlayer.setVolume(volume, volume);
    }

    @Override
    public void onStartTrackingTouch(SeekBar seekBar) {}

    @Override
    public void onStopTrackingTouch(SeekBar seekBar) {
    }
};
4

3 回答 3

13

MediaPlayer.setVolume将该播放器的音量设置为该流的总音量的百分比。它不影响流音量。因此,如果您只想设置该播放器的音量,请将其设置为介于 0 和 1 之间的某个值(表示百分比的小数值),并让用户通过使用硬件音量控件单独控制系统音量。要连接 a SeekBar,您可以将其缩放 100 倍,就像您在示例代码中所做的那样,因为SeekBar不支持小数值。哦,还有一件事是为了别人的利益(因为你已经弄清楚了):文档说“UI控件应该以对数方式缩放”,这意味着如果你只是设置音量而不进行任何缩放,音量控制将感觉不自然。基本上,人耳不会将波的幅度减半视为“音量的一半”,因此您需要以对数方式缩放以使人耳感觉更自然,就像您在示例代码中所做的那样。

如果您确实想为给定的流(而不仅仅是给定的播放器)设置系统音量,您可以使用AudioManager.setStreamVolume介于 0 和返回的值之间的值AudioManager.getStreamMaxVolume。但请记住,这通常是一个低分辨率的音量控制——getMaxStreamVolume通常返回一个相对较低的值——比如 10 或 15,所以你只有几个可能的音量位置。这意味着控制音量不会像MediaPlayer直接控制音量一样流畅。此外,显然,以这种方式设置音量会为整个系统设置音量并影响所有应用程序,这可能不是用户想要的。

于 2014-01-18T16:28:31.657 回答
2

添加到 TodorK 的答案。

我所做的是我最初将 StreamVolume 设置为 Max,并让用户控制 SeekBar。完成后,我将 StreamVolume 设置回其原始状态。这允许用户控制 MediaPlayer 的音量,并且不影响其他应用程序。

首先将 Stream 设置为您想要的并初始化 AudioManager

setVolumeControlStream(AudioManager.STREAM_MUSIC);
audioManager = (AudioManager) getActivity().getSystemService(Context.AUDIO_SERVICE);

获取 InitialVolume(完成后将其设置回此值)并将其设置为 MaxVolume

final int initVolume = audioManager.getStreamVolume(AudioManager.STREAM_MUSIC);
final int maxVolume  = audioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC);
audioManager.setStreamVolume(AudioManager.STREAM_MUSIC,maxVolume, 0);

在 SeekBarChangedListener 的 onProgress 部分执行 AudioStuff

        @Override
        public void onProgressChanged(SeekBar seekBar, int progress,boolean fromUser) 
        {
            float volume = (float) (1 - (Math.log(100 - progress) / Math.log(100)));
            mp.setVolume(volume, volume);
            mp.start();
        }

完成后,将其设置回初始音量,这样用户就不会生气(在我的情况下,我使用 AlertDialog,所以它在 onDismiss 中

        @Override
        public void onDismiss(DialogInterface dialog) 
        {
            audioManager.setStreamVolume(AudioManager.STREAM_MUSIC,initVolume, 0);

            //Stop Playing the Song
            stopSong();             
        }

另请注意,我在 onProgress 部分做了日志内容

于 2014-05-29T17:43:24.937 回答
1

首先在 XML 文件中创建一个 seekBar。然后复制此代码(seekBar2是 seekBar 的 ID):

private final static int MAX_VOLUME = 100;
SeekBar seekBar = (SeekBar) findViewById(R.id.seekBar2);
seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
    @Override
    public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
        float volume = (float) (1 - (Math.log(MAX_VOLUME - progress) / Math.log(MAX_VOLUME)));
        mediaPlayer.setVolume(volume, volume);
    }

    @Override
    public void onStartTrackingTouch(SeekBar seekBar) {

    }

    @Override
    public void onStopTrackingTouch(SeekBar seekBar) {

    }
});
于 2017-08-08T02:57:27.587 回答