24

私が取り組んでいるアプリケーションは、音楽ファイルを再生します。タイマーが切れたら、音楽をフェードアウトさせたい。それ、どうやったら出来るの。MediaPlayer を使用して音楽を再生していますが、音楽ファイルはアプリケーションの raw フォルダーにあります。

4

5 に答える 5

28

これは、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);
    }
}
于 2013-03-13T19:59:50.473 に答える
23

それを行う1つの方法MediaPlayer.setVolume(right, left)は、反復ごとにこれらの値を使用して減少させることです..ここに大まかなアイデアがあります

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

}

このタイマーの期限が切れたら、FadeIn()orを呼び出す必要があります。FadeOut()このメソッドは deltaTime を取得する必要はありませんが、すべてのデバイスで同じ割合で音量を下げるため、より優れています。

于 2011-07-30T18:31:03.477 に答える
8

とても良いクラスのスングレコです。

より完全にするために、フェードでプレーヤーを停止するstop()関数と、プレーヤーを停止してリソースを安全に解放するstopAndRelease()を追加します。onStop() や onDestroy() などのアクティビティ メソッドを呼び出すときに使用すると非常に便利です。 .

2 つの方法:

    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();
    }
}
于 2014-01-03T07:46:20.987 に答える
5

私はこれに取り組んできました。それが役立つことを願っています: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;
}
于 2015-03-25T01:38:55.097 に答える