2013-08-08 5 views
6

Als recommended by the doc, würde Ich mag die setvolume() Methode verwenden, um die Lautstärke meiner MediaPlayer zu kontrollieren, aber ich bin ein wenig verwirrt darüber, wie man verwalte es.Wie MediaPlayer.setVolume() + SeekBar verwalten it + Gerät Lautstärkeregler einstellen

Ich setze die Lautstärke mit einem SeekBar, initialisiert auf das aktuelle Volumen im AudioManager.STREAM_MUSIC Stream.

Dies macht Sinn, wenn der Benutzer das Gerät nicht Lautstärkeregler nicht ändern, aber wenn er es tut, ich bin nicht sicher, was ich tun soll, und ich habe mehrere Zweifel:

  • wie ist die MediaPlayer Lautstärke bezogen auf das Gerät Volumen? Ist der Maximalwert (1), die in setVolume() entsprechen mAudioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC)

  • wenn es der Fall ist, sollte der Fortschritt Wert des SeekBar zurückgesetzt werden jedes Mal das Gerät Lautstärkeregler eingestellt ist, aber dann, was ist der Sinn der Verwendung von MediaPlayer.setVolume() anstelle von AudioManager.setStreamVolume()?

  • Wie lautet die Standardmethode MediaPlayer.setVolume() mit SeekBar zu verwenden?

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

Wie Sie gelöst? – Erum

Antwort

11

MediaPlayer.setVolume stellt die Lautstärke des Spielers als prozentualer Anteil des Gesamtvolumens für diesen Strom. Es hat keinen Einfluss auf das Stream-Volume. Wenn Sie also nur die Lautstärke dieses Players einstellen möchten, stellen Sie ihn auf einen Wert zwischen 0 und 1 ein (ein Bruchwert, der den Prozentwert darstellt) und lassen Sie den Benutzer die Systemlautstärke mithilfe der Hardware-Lautstärkeregler separat steuern. Um einen SeekBar zu verbinden, können Sie ihn um einen Faktor von 100 skalieren, wie Sie es in Ihrem Beispielcode getan haben, da SeekBar keine Bruchwerte unterstützt. Oh, und noch eine Sache für den Nutzen anderer (da Sie es bereits herausgefunden haben): Die Dokumentation sagt "UI-Controls sollten logarithmisch skaliert werden", was bedeutet, dass wenn Sie nur die Lautstärke ohne Skalierung einstellen, der Lautstärkeregler sich unnatürlich fühlen. Im Grunde wird die Halbierung der Amplitude der Welle vom menschlichen Ohr NICHT als "die Hälfte des Volumens" wahrgenommen. Daher müssen Sie logarithmisch skalieren, damit es sich für das menschliche Ohr natürlicher anfühlt, wie Sie es in Ihrem Beispielcode getan haben.

Wenn Sie das Systemvolumen für den angegebenen Stream (und nicht nur für den angegebenen Player) festlegen möchten, können Sie AudioManager.setStreamVolume mit einem Wert zwischen 0 und dem von AudioManager.getStreamMaxVolume zurückgegebenen Wert verwenden. Aber denken Sie daran, dass das normalerweise ein niedrigauflösender Lautstärkeregler ist - gibt normalerweise einen relativ niedrigen Wert zurück - wie 10 oder 15, so dass Sie nur ein paar mögliche Positionen für die Lautstärke haben. Dies bedeutet, dass das Steuern der Lautstärke nicht so flüssig ist, als wenn Sie die Lautstärke des MediaPlayer direkt steuern würden. Das Festlegen des Volumes auf diese Weise setzt natürlich das gesamte System und wirkt sich auf alle Anwendungen aus, die möglicherweise nicht den Wünschen des Benutzers entsprechen.

+0

hey, das war wirklich informativ. Hat mir geholfen, eine Lösung für ein Problem zu finden, bei dem ich feststeckte. Danke :) – Zen

1

Hinzufügen zu TodorKs Antwort.

Was ich getan habe, ist, dass ich zuerst die StreamVolume auf Max eingestellt habe und Benutzer die SeekBar steuern lassen. Sobald sie fertig sind, setze ich das StreamVolume zurück in seinen ursprünglichen Zustand. Damit kann der Benutzer das MediaPlayer-Volume steuern und andere Anwendungen nicht beeinflussen.

zuerst den Strom auf die gewünschte ein & initialisieren Audiomanager

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

Holen Sie sich das InitialVolume (so, dass Sie es wieder auf diese gesetzt, sobald Sie fertig sind) und stellen Sie es

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

Haben die AudioStuff im onProgress Teil des 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(); 
     } 

Sobald Sie fertig sind, setzen Sie es zurück an den initialVolume, so dass der Benutzer tut (in meinem Fall erhalten sauer, im einen Alertdialog verwenden, so ist es in der onDismiss Sache

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

      //Stop Playing the Song 
      stopSong();    
     } 

Beachten Sie auch, ich hat das Log-Zeug im onProgress-Teil

+0

Hey, Entschuldigung über die Störung, aber ich sah dies Ihre Antwort und ich dachte, dass Sie mir vielleicht helfen könnten (Wenn Sie nichts dagegen haben). Ich habe meine Frage [hier] gepostet (http://stackoverflow.com/questions/40322485/change-the-volume-of-a-specif-player-and-get-its-current-volume), ich muss das beenden Projekt und nur diese 2 Methoden fehlen. Ich habe versucht, das mp.setVolume und funktioniert aber nur für eine Weile, nachdem das Volume wieder normal funktioniert. Aber stellen Sie den Fortschritt wie Lautstärke vor zeigen Sie die Suchleiste Ich habe keine Ahnung, denn wenn ich AudioManager benutze ich werde alle Spieler Volumen. Bitte, wenn Sie mir helfen könnten, werde ich danken. – EmilyR

0

Zuerst machen Sie eine Suchleiste in XML-Datei. Dann kopieren Sie diesen Code (seekBar2 ist die ID für die Suchleiste):

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

    } 
});