8

ドキュメントで推奨されているように、このsetvolume()方法を使用して の音量を制御したいのMediaPlayerですが、その管理方法について少し混乱しています。

ストリームSeekBar内の現在のボリュームに初期化されたを使用してボリュームを設定しています。AudioManager.STREAM_MUSIC

これは、ユーザーがデバイスのボリューム コントロールを変更しない場合には理にかなっていますが、変更した場合はどうすればよいかわかりません。いくつか疑問があります。

  • MediaPlayerボリュームはデバイスのボリュームとどのように関連していますか? に設定された最大値 (1) はsetVolume()対応していますか?mAudioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC)

  • その場合、SeekBarデバイスの音量コントロールが設定されるたびに の進行状況の値をリセットする必要がありますが、MediaPlayer.setVolume()代わりにAudioManager.setStreamVolume()を使用する意味は何ですか?

  • MediaPlayer.setVolume()を使用する標準的な方法は何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 (パーセンテージを表す分数値) の間の値に設定し、ユーザーがハードウェアの音量コントロールを使用してシステムの音量を個別に制御できるようにします。を接続するにはSeekBar、サンプル コードで行ったように 100 倍にスケーリングできます。SeekBar小数値はサポートしていません。ああ、そして他の人の利益のためにもう1つ(あなたはすでにそれを理解しているので):ドキュメントには「UIコントロールは対数的にスケーリングする必要がある」と書かれています。つまり、スケーリングせずにボリュームを設定した場合、ボリュームコントロールは不自然に感じる。基本的に、波の振幅を半分にしても人間の耳には「半分の音量」として認識されないため、サンプル コードで行ったように、人間の耳にとってより自然に感じるように対数的にスケーリングする必要があります。

特定のストリーム (特定のプレーヤーだけでなく) のシステム ボリュームを設定したい場合は、AudioManager.setStreamVolume0 から によって返される値までの値を使用できますAudioManager.getStreamMaxVolume。ただし、通常は低解像度のボリューム コントロールであることに注意してgetMaxStreamVolumeください。通常、10 や 15 などの比較的低い値が返されるため、ボリュームの可能な位置はわずかしかありません。MediaPlayerこれは、音量の制御が、の音量を直接制御する場合ほどスムーズではないことを意味します。また、明らかに、この方法で音量を設定すると、システム全体に設定され、すべてのアプリケーションに影響します。これは、ユーザーが望んでいるものではない可能性があります.

于 2014-01-18T16:28:31.657 に答える
2

TodorK の回答に追加します。

私がしたことは、最初に StreamVolume を Max に設定し、ユーザーが SeekBar を制御できるようにすることでした。終了したら、StreamVolume を元の状態に戻します。これにより、ユーザーは MediaPlayer の音量を制御でき、他のアプリケーションには影響しません。

最初にストリームを目的のものに設定し、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();
        }

完了したら、initialVolume に戻して、ユーザーが腹を立てないようにします (私の場合、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 に答える