Monday, December 1, 2014

Android 5.0 호환성 문제 - SoundPool 유사한 AudioPool 만듬

Android 5.0 호환성 문제로 SoundPool이 제대로 동작하지 않아서 AudioPool을 직접 만들었다. 반복되는 사운드와 반복되지 않는 사운드를 따로 저장하였다. 파일이름으로 ID기반으로 관리하며, 반복되지 않는 사운드의 경우 같은 사운드를 동시에 여러게 Play 가능하다.

package com.beyond;

import java.util.HashMap;

import android.media.AudioManager;
import android.media.MediaPlayer;
import android.util.Log;

public class AudioPool implements MediaPlayer.OnCompletionListener {
    private final static String TAG = "AudioPool";

    private int mPosition = 0;

    private HashMap<Integer, String> mMediaResNameMap = new HashMap<Integer, String>();
    private HashMap<Integer, MediaPlayer> mMediaPlayerMap = new HashMap<Integer, MediaPlayer>();// Loop만 저장하자.
    private HashMap<MediaPlayer, Integer> mSoundIDMap = new HashMap<MediaPlayer, Integer>();// Loop만 저장하자.

    private void load(String resName, MediaPlayer mp) {
        mp.reset();
        mp.setAudioStreamType(AudioManager.STREAM_MUSIC);
        mp.setOnCompletionListener(this);
        try {
            android.content.res.AssetFileDescriptor afd = BeyondActivity.context.getAssets().openFd(resName);
            mp.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength());
            mp.prepare();
            afd.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private final MediaPlayer load(String resName) {
        final MediaPlayer mp = new MediaPlayer();
        load(resName, mp);
        return mp;
    }

    private void load(int soundID, final MediaPlayer mp) {
        String resName = mMediaResNameMap.get(soundID);
        load(resName, mp);
    }

    public int load(String resName, int priority) {
        mPosition++;

        // 1. 파일이름은 저장해 놓고
        mMediaResNameMap.put(mPosition, resName);
        Log.d(TAG, "load " + mPosition + " " + resName);

        return mPosition;
    }

    final int play(int soundID, float leftVolume, float rightVolume, int priority, int loop, float rate) {
        Log.d(TAG, "play " + soundID + " loop " + loop);

        boolean looping = loop == -1 ? true : false;
        if (looping) {
            Log.e(TAG, "play looping " + soundID);
            MediaPlayer mp = mMediaPlayerMap.get(soundID);
            if (mp != null) {// 이미 플레이되고 있으니깐 그냥 리턴
                return 0;
            }
        }
        final String resName = mMediaResNameMap.get(soundID);

        MediaPlayer mp = null;

        mp = load(resName);
        Log.d(TAG, "play " + soundID + " load");

        mp.start();
        Log.d(TAG, "play " + soundID + " start");

        if (looping) {
            Log.e(TAG, "play " + soundID + " looping start");
            mMediaPlayerMap.put(soundID, mp);
            mSoundIDMap.put(mp, soundID);
        }

        return 0;
    }

    final public void stop(int soundID) {
        Log.e(TAG, "stop " + soundID);
        MediaPlayer mp = mMediaPlayerMap.get(soundID);
        if (mp != null) {
            Log.e(TAG, "stop " + soundID + " remove");
            mp.stop();
            mp.reset();
            mp.release();
            mp = null;
            mMediaPlayerMap.remove(soundID);
        }
    }

    @Override
    public void onCompletion(MediaPlayer mp) {
        // TODO Auto-generated method stub
        // 플레이가 다 끝난건 제거 하자.
        Log.d(TAG, "onCompletion");
        if (mp != null) {
            if (mSoundIDMap.containsKey(mp)) {// looping
                int soundID = mSoundIDMap.get(mp);
                Log.d(TAG, "onCompletion " + soundID + " looping");
                load(soundID, mp);
                Log.d(TAG, "onCompletion " + soundID + " looping prepare");
                mp.start();
                Log.d(TAG, "onCompletion " + soundID + " looping start");
            } else
            {
                Log.d(TAG, "onCompletion else");
                mp.stop();
                mp.reset();
                mp.release();
                mp = null;
            }
        }
    }
}

No comments:

Post a Comment