How to control MediaPlayer.setVolume () + SeekBar to set it + device volume level

As recommended by the document , I would like to use the setvolume() method to control the volume of my MediaPlayer , but I'm a bit confused about how to manage it.

I install a volume using a SeekBar initialized by the current volume in the AudioManager.STREAM_MUSIC stream.

This makes sense when the user does not change the volume control of the device, but when he does, Iโ€™m not sure what to do, and I have a few doubts:

  • How is MediaPlayer volume related to device volume? The maximum value (1) set in setvolume() corresponds to mAudioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC)

  • if so, the SeekBar progress SeekBar should be reset every time the device volume control is set, but then what is the point of using MediaPlayer.setVolume() instead of AudioManager.setStreamVolume () ?

  • What is the standard way to use MediaPlayer.setVolume() with 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) { } }; 
+6
source share
3 answers

MediaPlayer.setVolume sets the volume of this player as a percentage of the total volume for this stream. This does not affect the flow rate. Therefore, if you want to install this particular volume of the player, set it to a value from 0 to 1 (fractional value representing percentage), and allow the user to separately control the volume of the system using hardware volume controls. To connect a SeekBar , you can scale it 100 times, as it was in your code example, since SeekBar does not support fractional values. Oh, and another advantage for others (since you already understood this): the docs say: โ€œUser interface controls should scale logarithmically,โ€ which means that if you just set the volume without any scaling, the volume control will feel yourself unnaturally. Basically, half the wave amplitude is NOT perceived by the human ear as โ€œhalf volumeโ€, so you need to scale logarithmically to make it more natural for the human ear, as you did in your code example.

If you want to set the system volume for this stream (and not just for the given player), you can use AudioManager.setStreamVolume with a value from 0 to the value returned by AudioManager.getStreamMaxVolume . But keep in mind that this is usually a low-resolution volume control - getMaxStreamVolume usually returns a relatively low value - for example, 10 or 15, so you only have a few possible positions for volume. This means that volume control will not be as smooth as if you were directly controlling the volume of MediaPlayer . In addition, it is obvious that installing the volume in this way installs it for the entire system and affects all applications that may not be what users want.

+11
source

Adding TodorK to the answer.

What I did was, I initially set StreamVolume to Max and let the user control the SeekBar. As soon as they finished, I returned StreamVolume to its original state. This allows the user to manage the MediaPlayer volume and does not affect other applications.

First set Stream to your desired and initialize AudioManager

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

Get InitialVolume (so you get it back after that) and set it to MaxVolume

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

Make an AudioStuff in the onProgress part of the SeekBarChangedListener

  @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(); } 

Once you are done, return it to its original volume so that the user does not get angry (in my case im uses AlertDialog, so its in onDismiss thing

  @Override public void onDismiss(DialogInterface dialog) { audioManager.setStreamVolume(AudioManager.STREAM_MUSIC,initVolume, 0); //Stop Playing the Song stopSong(); } 

Also note that I did the magazine stuff in the onProgress part

+1
source

First create a seekBar in the XML file. Then copy this code ( seekBar2 is the identifier for seekBar):

 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) { } }); 
0
source

Source: https://habr.com/ru/post/951335/


All Articles