2011-07-30 21 views
16

私が取り組んでいるアプリケーションが音楽ファイルを再生します。タイマーが切れると音楽が消えてしまいます。それ、どうやったら出来るの。 MediaPlayerを使用して音楽を再生しています。音楽ファイルは、自分のアプリケーションの生のフォルダにあります。それを行うにはAndroid:私のアプリが演奏する音楽ファイルのフェードイン/フェードアウトサウンドエフェクトを作成するにはどうすればいいですか?

答えて

20

一つの方法は、(左、右)MediaPlayer.setVolumeを使用することで、これらの値がデクリメント持っているすべての後iteration..hereは、フェードインやフェードアウトが一度呼び出されるべき

float volume = 1; 
float speed = 0.05f; 

public void FadeOut(float deltaTime) 
{ 
    MediaPlayer.setVolume(volume, volume); 
    volume -= speed* deltaTime 

} 
public void FadeIn(float deltaTime) 
{ 
    MediaPlayer.setVolume(volume, volume); 
    volume += speed* deltaTime 

} 

目安ですこのタイマーの有効期限が切れていますが、方法ではdeltaTimeを実行する必要はありませんが、すべてのデバイスで同じレートでボリュームを下げるようにしてください。

+0

は、これは私がやりたいdidntは何かであるが、まだのためにやってしまいましたよりよい解決策の欠如。私はより良いとエレガントなソリューションを探していたが、誰も存在しないようだ。だから私はこの答えを受け入れるだろう。 – binW

+0

ほかに何ができるかわからない – Chris

+2

もう少しサンプルコードを追加できますか?この例ではあなたが運転していることを理解していると思いますが、それでも私をクリックしていません。同様に、「deltaTime」はどこから来たのですか? 1回のループですべてをやりますか? – bitops

24

これはAndroid MediaPlayerのハンドラクラス全体です。 play()とpause()関数を見てください。両方とも、フェードするかしないかのいずれかを含む。 updateVolume()関数は、サウンドを直線的に増減させるためのキーでした。

package com.stackoverflow.utilities; 

import java.io.File; 
import java.util.Timer; 
import java.util.TimerTask; 

import android.content.Context; 
import android.media.MediaPlayer; 
import android.net.Uri; 

public class MusicHandler { 
    private MediaPlayer mediaPlayer; 
    private Context context; 
    private int iVolume; 

    private final static int INT_VOLUME_MAX = 100; 
    private final static int INT_VOLUME_MIN = 0; 
    private final static float FLOAT_VOLUME_MAX = 1; 
    private final static float FLOAT_VOLUME_MIN = 0; 

    public MusicHandler(Context context) { 
     this.context = context; 
    } 

    public void load(String path, boolean looping) { 
     mediaPlayer = MediaPlayer.create(context, Uri.fromFile(new File(path))); 
     mediaPlayer.setLooping(looping); 
    } 

    public void load(int address, boolean looping) { 
     mediaPlayer = MediaPlayer.create(context, address); 
     mediaPlayer.setLooping(looping); 
    } 

    public void play(int fadeDuration) { 
     // Set current volume, depending on fade or not 
     if (fadeDuration > 0) 
      iVolume = INT_VOLUME_MIN; 
     else 
      iVolume = INT_VOLUME_MAX; 

     updateVolume(0); 

     // Play music 
     if (!mediaPlayer.isPlaying()) 
      mediaPlayer.start(); 

     // Start increasing volume in increments 
     if (fadeDuration > 0) { 
      final Timer timer = new Timer(true); 
      TimerTask timerTask = new TimerTask() { 
       @Override 
       public void run() { 
        updateVolume(1); 
        if (iVolume == INT_VOLUME_MAX) { 
         timer.cancel(); 
         timer.purge(); 
        } 
       } 
      }; 

      // calculate delay, cannot be zero, set to 1 if zero 
      int delay = fadeDuration/INT_VOLUME_MAX; 
      if (delay == 0) 
       delay = 1; 

      timer.schedule(timerTask, delay, delay); 
     } 
    } 

    public void pause(int fadeDuration) { 
     // Set current volume, depending on fade or not 
     if (fadeDuration > 0) 
      iVolume = INT_VOLUME_MAX; 
     else 
      iVolume = INT_VOLUME_MIN; 

     updateVolume(0); 

     // Start increasing volume in increments 
     if (fadeDuration > 0) { 
      final Timer timer = new Timer(true); 
      TimerTask timerTask = new TimerTask() { 
       @Override 
       public void run() { 
        updateVolume(-1); 
        if (iVolume == INT_VOLUME_MIN) { 
         // Pause music 
         if (mediaPlayer.isPlaying()) 
          mediaPlayer.pause(); 
         timer.cancel(); 
         timer.purge(); 
        } 
       } 
      }; 

      // calculate delay, cannot be zero, set to 1 if zero 
      int delay = fadeDuration/INT_VOLUME_MAX; 
      if (delay == 0) 
       delay = 1; 

      timer.schedule(timerTask, delay, delay); 
     } 
    } 

    private void updateVolume(int change) { 
     // increment or decrement depending on type of fade 
     iVolume = iVolume + change; 

     // ensure iVolume within boundaries 
     if (iVolume < INT_VOLUME_MIN) 
      iVolume = INT_VOLUME_MIN; 
     else if (iVolume > INT_VOLUME_MAX) 
      iVolume = INT_VOLUME_MAX; 

     // convert to float value 
     float fVolume = 1 - ((float) Math.log(INT_VOLUME_MAX - iVolume)/(float) Math.log(INT_VOLUME_MAX)); 

     // ensure fVolume within boundaries 
     if (fVolume < FLOAT_VOLUME_MIN) 
      fVolume = FLOAT_VOLUME_MIN; 
     else if (fVolume > FLOAT_VOLUME_MAX) 
      fVolume = FLOAT_VOLUME_MAX; 

     mediaPlayer.setVolume(fVolume, fVolume); 
    } 
} 
8

非常に良いクラスのsngrecoです。私はあなたが活動のメソッドを呼び出すときに使用することは非常に便利な、プレーヤーを停止し、安全にリソースを解放するために停止フェードを持つプレイヤーを停止する()機能、およびstopAndRelease()が追加されますそれをより完全なものにするに

onStop()やonDestroy()のように。

二つの方法:

public void stop(int fadeDuration) 
{ 
    try { 
     // Set current volume, depending on fade or not 
     if (fadeDuration > 0) 
      iVolume = INT_VOLUME_MAX; 
     else 
      iVolume = INT_VOLUME_MIN; 

     updateVolume(0); 

     // Start increasing volume in increments 
     if (fadeDuration > 0) 
     { 
      final Timer timer = new Timer(true); 
      TimerTask timerTask = new TimerTask() 
      { 
       @Override 
       public void run() 
       { 
        updateVolume(-1); 
        if (iVolume == INT_VOLUME_MIN) 
        { 
         // Pause music 
         mediaPlayer.stop(); 
         timer.cancel(); 
         timer.purge(); 
        } 
       } 
      }; 

      // calculate delay, cannot be zero, set to 1 if zero 
      int delay = fadeDuration/INT_VOLUME_MAX; 
      if (delay == 0) 
       delay = 1; 

      timer.schedule(timerTask, delay, delay); 
     } 
    } catch (Exception e) { 
     e.printStackTrace(); 
    } 

} 

public void stopAndRelease(int fadeDuration) { 
    try { 
     final Timer timer = new Timer(true); 
     TimerTask timerTask = new TimerTask() 
     { 
      @Override 
      public void run() 
      { 
       updateVolume(-1); 
       if (iVolume == INT_VOLUME_MIN) 
       { 
        // Stop and Release player after Pause music 
        mediaPlayer.stop(); 
        mediaPlayer.release(); 
        timer.cancel(); 
        timer.purge(); 
       } 
      } 
     }; 

     timer.schedule(timerTask, fadeDuration); 
    } catch (Exception e) { 
     e.printStackTrace(); 
    } 
} 
3

私はそれが役に立てば幸いこれに取り組んできました:D:

private static void crossFade() { 
    MediaPlayerManager.fadeOut(currentPlayer, 2000); 
    MediaPlayerManager.fadeIn(auxPlayer, 2000); 
    currentPlayer = auxPlayer; 
    auxPlayer = null; 
} 

public static void fadeOut(final MediaPlayer _player, final int duration) { 
    final float deviceVolume = getDeviceVolume(); 
    final Handler h = new Handler(); 
    h.postDelayed(new Runnable() { 
     private float time = duration; 
     private float volume = 0.0f; 

     @Override 
     public void run() { 
      if (!_player.isPlaying()) 
       _player.start(); 
      // can call h again after work! 
      time -= 100; 
      volume = (deviceVolume * time)/duration; 
      _player.setVolume(volume, volume); 
      if (time > 0) 
       h.postDelayed(this, 100); 
      else { 
       _player.stop(); 
       _player.release(); 
      } 
     } 
    }, 100); // 1 second delay (takes millis) 


} 

public static void fadeIn(final MediaPlayer _player, final int duration) { 
    final float deviceVolume = getDeviceVolume(); 
    final Handler h = new Handler(); 
    h.postDelayed(new Runnable() { 
     private float time = 0.0f; 
     private float volume = 0.0f; 

     @Override 
     public void run() { 
      if (!_player.isPlaying()) 
       _player.start(); 
      // can call h again after work! 
      time += 100; 
      volume = (deviceVolume * time)/duration; 
      _player.setVolume(volume, volume); 
      if (time < duration) 
       h.postDelayed(this, 100); 
     } 
    }, 100); // 1 second delay (takes millis) 

} 
public static float getDeviceVolume() { 
    int volumeLevel = audioManager.getStreamVolume(AudioManager.STREAM_MUSIC); 
    int maxVolume = audioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC); 

    return (float) volumeLevel/maxVolume; 
} 
+0

どうすればFadeOutとFadeInを同じに使いたいのですか?私は1つの曲を弾いてからフェードボタンを押してから、次の曲が音量を上げながら同時にゆっくりと下がります。最初の曲の音量が0になると停止し、2番目の曲の演奏が続行されます。 –

関連する問題